c-toxcore-0.2.18/0000777000175000017500000000000014227324767012533 5ustar robinrobinc-toxcore-0.2.18/.circleci/0000777000175000017500000000000014227324767014366 5ustar robinrobinc-toxcore-0.2.18/.circleci/cmake-asan0000777000175000017500000000212514227324767016314 0ustar robinrobin#!/bin/bash set -eu CACHEDIR="$HOME/cache" . ".github/scripts/flags-$CC.sh" add_flag -Werror add_flag -fdiagnostics-color=always add_flag -fno-omit-frame-pointer add_flag -fsanitize=address cmake -B_build -H. -GNinja \ -DCMAKE_C_FLAGS="$C_FLAGS" \ -DCMAKE_CXX_FLAGS="$CXX_FLAGS" \ -DCMAKE_EXE_LINKER_FLAGS="$LD_FLAGS" \ -DCMAKE_SHARED_LINKER_FLAGS="$LD_FLAGS" \ -DCMAKE_INSTALL_PREFIX:PATH="$PWD/_install" \ -DCMAKE_UNITY_BUILD=ON \ -DMIN_LOGGER_LEVEL=TRACE \ -DMUST_BUILD_TOXAV=ON \ -DNON_HERMETIC_TESTS=ON \ -DSTRICT_ABI=ON \ -DTEST_TIMEOUT_SECONDS=120 \ -DUSE_IPV6=OFF \ -DAUTOTEST=ON \ -DBUILD_MISC_TESTS=ON \ -DBUILD_FUN_UTILS=ON cd _build ninja install -j"$(nproc)" export ASAN_OPTIONS="color=always" export ASAN_OPTIONS="$ASAN_OPTIONS,detect_invalid_pointer_pairs=1" export ASAN_OPTIONS="$ASAN_OPTIONS,detect_stack_use_after_return=1" export ASAN_OPTIONS="$ASAN_OPTIONS,strict_init_order=1" export ASAN_OPTIONS="$ASAN_OPTIONS,strict_string_checks=1" export ASAN_OPTIONS="$ASAN_OPTIONS,symbolize=1" ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 c-toxcore-0.2.18/.circleci/cmake-tsan0000777000175000017500000000162714227324767016345 0ustar robinrobin#!/bin/bash set -eu CACHEDIR="$HOME/cache" . ".github/scripts/flags-$CC.sh" add_flag -Werror add_flag -fdiagnostics-color=always add_flag -fno-omit-frame-pointer add_flag -fsanitize=thread cmake -B_build -H. -GNinja \ -DCMAKE_C_FLAGS="$C_FLAGS" \ -DCMAKE_CXX_FLAGS="$CXX_FLAGS" \ -DCMAKE_EXE_LINKER_FLAGS="$LD_FLAGS" \ -DCMAKE_SHARED_LINKER_FLAGS="$LD_FLAGS" \ -DCMAKE_INSTALL_PREFIX:PATH="$PWD/_install" \ -DCMAKE_UNITY_BUILD=ON \ -DMIN_LOGGER_LEVEL=TRACE \ -DMUST_BUILD_TOXAV=ON \ -DNON_HERMETIC_TESTS=ON \ -DSTRICT_ABI=ON \ -DTEST_TIMEOUT_SECONDS=120 \ -DUSE_IPV6=OFF \ -DAUTOTEST=ON cd _build ninja install -j"$(nproc)" export TSAN_OPTIONS="color=always" export TSAN_OPTIONS="$TSAN_OPTIONS,halt_on_error=1" export TSAN_OPTIONS="$TSAN_OPTIONS,second_deadlock_stack=1" export TSAN_OPTIONS="$TSAN_OPTIONS,symbolize=1" ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 c-toxcore-0.2.18/.circleci/cmake-ubsan0000777000175000017500000000237214227324767016506 0ustar robinrobin#!/bin/bash set -eu CACHEDIR="$HOME/cache" . ".github/scripts/flags-$CC.sh" add_flag -Werror add_flag -fdiagnostics-color=always add_flag -fno-omit-frame-pointer add_flag -fno-sanitize-recover=all add_flag -fsanitize=undefined,nullability,local-bounds,float-divide-by-zero,integer add_flag -fno-sanitize=implicit-conversion,unsigned-integer-overflow # Enable extra checks. We only do this on ubsan because it shows useful error # messages for the kind of bugs this catches (mostly incorrect nullability # annotations). Other builds will segfault, ubsan will show a stack trace. add_flag -D_DEBUG cmake -B_build -H. -GNinja \ -DCMAKE_C_FLAGS="$C_FLAGS" \ -DCMAKE_CXX_FLAGS="$CXX_FLAGS" \ -DCMAKE_EXE_LINKER_FLAGS="$LD_FLAGS" \ -DCMAKE_SHARED_LINKER_FLAGS="$LD_FLAGS" \ -DCMAKE_INSTALL_PREFIX:PATH="$PWD/_install" \ -DCMAKE_UNITY_BUILD=ON \ -DMIN_LOGGER_LEVEL=TRACE \ -DMUST_BUILD_TOXAV=ON \ -DNON_HERMETIC_TESTS=ON \ -DSTRICT_ABI=ON \ -DTEST_TIMEOUT_SECONDS=120 \ -DUSE_IPV6=OFF \ -DAUTOTEST=ON cd _build ninja install -j"$(nproc)" export UBSAN_OPTIONS="color=always" export UBSAN_OPTIONS="$UBSAN_OPTIONS,print_stacktrace=1" export UBSAN_OPTIONS="$UBSAN_OPTIONS,symbolize=1" ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 c-toxcore-0.2.18/.circleci/config.yml0000777000175000017500000000774014227324767016371 0ustar robinrobin--- version: 2 workflows: version: 2 program-analysis: jobs: # Dynamic analysis - asan - tsan - msan - ubsan # Static analysis - clang-analyze - clang-tidy - cpplint - infer - static-analysis jobs: asan: working_directory: ~/work docker: - image: ubuntu steps: - run: &apt_install apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ca-certificates clang cmake git libconfig-dev libgtest-dev libopus-dev libsodium-dev libvpx-dev llvm-dev ninja-build pkg-config - checkout - run: git submodule update --init --recursive - run: CC=clang .circleci/cmake-asan tsan: working_directory: ~/work docker: - image: ubuntu steps: - run: *apt_install - checkout - run: git submodule update --init --recursive - run: CC=clang .circleci/cmake-tsan ubsan: working_directory: ~/work docker: - image: ubuntu steps: - run: *apt_install - checkout - run: git submodule update --init --recursive - run: CC=clang .circleci/cmake-ubsan msan: working_directory: ~/work docker: - image: toxchat/toktok-stack:latest-msan steps: - checkout - run: git submodule update --init --recursive - run: rm -rf /src/workspace/c-toxcore/* && mv * /src/workspace/c-toxcore/ - run: cd /src/workspace && bazel test //c-toxcore/auto_tests:lossless_packet_test //c-toxcore/toxav/... //c-toxcore/toxcore/... infer: working_directory: ~/work docker: - image: toxchat/infer steps: - run: *apt_install - checkout - run: git submodule update --init --recursive - run: infer --no-progress-bar -- cc auto_tests/auto_test_support.c auto_tests/lossless_packet_test.c testing/misc_tools.c toxav/*.c toxcore/*.c toxcore/*/*.c toxencryptsave/*.c third_party/cmp/*.c -lpthread $(pkg-config --cflags --libs libsodium opus vpx) static-analysis: working_directory: ~/work docker: - image: ubuntu steps: - run: *apt_install - run: apt-get install -y --no-install-recommends ca-certificates cppcheck g++ llvm-dev - checkout - run: git submodule update --init --recursive - run: other/analysis/check_includes - run: other/analysis/check_logger_levels - run: other/analysis/run-check-recursion - run: other/analysis/run-clang - run: other/analysis/run-cppcheck - run: other/analysis/run-gcc clang-analyze: working_directory: ~/work docker: - image: ubuntu steps: - run: *apt_install - checkout - run: git submodule update --init --recursive - run: other/analysis/run-clang-analyze clang-tidy: working_directory: ~/work docker: - image: ubuntu steps: - run: *apt_install - run: apt-get install -y --no-install-recommends ca-certificates clang-tidy-12 - checkout - run: git submodule update --init --recursive - run: cmake . -B_build -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON - run: other/analysis/run-clang-tidy || other/analysis/run-clang-tidy || other/analysis/run-clang-tidy cpplint: working_directory: ~/work docker: - image: ubuntu steps: - run: *apt_install - run: apt-get install -y --no-install-recommends ca-certificates python3-pip - checkout - run: git submodule update --init --recursive - run: pip install cpplint - run: other/analysis/run-cpplint c-toxcore-0.2.18/.cirrus.yml0000777000175000017500000000713114227324767014650 0ustar robinrobin--- bazel-opt_task: container: image: toxchat/toktok-stack:latest-release cpu: 2 memory: 2G 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? bazel-dbg_task: container: image: toxchat/toktok-stack:latest-debug cpu: 2 memory: 2G 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? 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:onion_test -//c-toxcore/auto_tests:tcp_relay_test -//c-toxcore/auto_tests:tox_many_test cimple_task: container: image: toxchat/toktok-stack:latest-release 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 -- //c-toxcore/... c-toxcore-0.2.18/.clang-format0000777000175000017500000000106214227324767015110 0ustar robinrobinBasedOnStyle: WebKit ColumnLimit: 100 PointerAlignment: Right SpacesBeforeTrailingComments: 2 AlignConsecutiveMacros: true AlignEscapedNewlines: Left AlwaysBreakTemplateDeclarations: Yes SpaceBeforeCpp11BracedList: false Cpp11BracedListStyle: true IncludeIsMainRegex: '([-_](test|fuzz_test))?$' IncludeBlocks: Regroup IncludeCategories: - Regex: '^<.*\.h>' Priority: 1 SortPriority: 0 - Regex: '^<.*' Priority: 2 SortPriority: 0 - Regex: '.*' Priority: 3 SortPriority: 0 c-toxcore-0.2.18/.clusterfuzzlite/0000777000175000017500000000000014227324767016067 5ustar robinrobinc-toxcore-0.2.18/.clusterfuzzlite/build.sh0000777000175000017500000000120414227324767017522 0ustar robinrobin#!/bin/bash -eu FUZZ_TARGETS="bootstrap_fuzzer toxsave_fuzzer" # out of tree build cd "$WORK" ls /usr/local/lib/ # Debug build for asserts cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER="$CC" \ -DCMAKE_CXX_COMPILER="$CXX" \ -DCMAKE_C_FLAGS="$CFLAGS" \ -DCMAKE_CXX_FLAGS="$CXXFLAGS" \ -DCMAKE_EXE_LINKER_FLAGS="$LIB_FUZZING_ENGINE" \ -DBUILD_TOXAV=OFF -DENABLE_SHARED=NO -DBUILD_FUZZ_TESTS=ON \ -DDHT_BOOTSTRAP=OFF -DBOOTSTRAP_DAEMON=OFF "$SRC"/c-toxcore for TARGET in $FUZZ_TARGETS; do # build fuzzer target cmake --build ./ --target "$TARGET" # copy to output files cp "$WORK/testing/fuzzing/$TARGET" "$OUT"/ done c-toxcore-0.2.18/.clusterfuzzlite/Dockerfile0000777000175000017500000000144314227324767020066 0ustar robinrobin# c-toxcore Clusterfuzzlite build environment # We want to use the latest tools always FROM gcr.io/oss-fuzz-base/base-builder:latest RUN apt-get update && \ apt-get -y install --no-install-suggests --no-install-recommends \ cmake libtool autoconf automake pkg-config \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* # Static builds of dependencies # libsodium RUN git clone --depth 1 --branch 1.0.18 https://github.com/jedisct1/libsodium libsodium WORKDIR $SRC/libsodium RUN ./autogen.sh && ./configure --enable-shared=no && make install WORKDIR $SRC # Copy your project's source code. COPY . $SRC/c-toxcore # Working directory for build.sh. WORKDIR $SRC/c-toxcore RUN git submodule update --init --recursive # Copy build.sh into $SRC dir. COPY ./.clusterfuzzlite/build.sh $SRC/ c-toxcore-0.2.18/.editorconfig0000777000175000017500000000045514227324767015217 0ustar robinrobinroot = true [*] end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true [*.{c,h}] indent_style = space indent_size = 4 [*.{yml,sh,cmake}] indent_style = space indent_size = 2 [Makefile] indent_style = tab indent_size = 4 [CMakeLists.txt] indent_style = space indent_size = 2 c-toxcore-0.2.18/.github/0000777000175000017500000000000014227324767014073 5ustar robinrobinc-toxcore-0.2.18/.github/CODEOWNERS0000777000175000017500000000003114227324767015463 0ustar robinrobin/.github/ @TokTok/admins c-toxcore-0.2.18/.github/dependabot.yml0000777000175000017500000000023314227324767016724 0ustar robinrobin--- version: 2 updates: - package-ecosystem: gitsubmodule directory: "/" schedule: interval: daily time: "11:00" open-pull-requests-limit: 2 c-toxcore-0.2.18/.github/scripts/0000777000175000017500000000000014227324767015562 5ustar robinrobinc-toxcore-0.2.18/.github/scripts/autotools-linux0000777000175000017500000000130214227324767020672 0ustar robinrobin#!/bin/bash set -eu NPROC=$(nproc) . ".github/scripts/flags-$CC.sh" add_ld_flag -Wl,-z,defs # Make compilation error on a warning add_flag -Werror add_config_flag --with-nacl-libs="$CACHEDIR/lib/amd64" add_config_flag --with-nacl-headers="$CACHEDIR/include/amd64" add_config_flag --disable-ipv6 add_config_flag --enable-nacl add_config_flag --enable-daemon add_config_flag --with-log-level=TRACE autoreconf -fi mkdir -p _build cd _build # pushd ../configure "${CONFIG_FLAGS[@]}" || (cat config.log && false) make "-j$NPROC" -k CFLAGS="$C_FLAGS" LDFLAGS="$LD_FLAGS" make -j50 -k distcheck DISTCHECK_CONFIGURE_FLAGS="${CONFIG_FLAGS[*]}" || (cat tox-*/_build/build/test-suite.log && false) cd - # popd c-toxcore-0.2.18/.github/scripts/cmake-android0000777000175000017500000000236614227324767020215 0ustar robinrobin#!/bin/bash set -eu # Set up environment NDK=$ANDROID_NDK_HOME ABI=${1:-"armeabi-v7a"} case $ABI in armeabi-v7a) TARGET=armv7a-linux-androideabi NDK_API=16 ;; arm64-v8a) TARGET=aarch64-linux-android NDK_API=21 ;; x86) TARGET=i686-linux-android NDK_API=16 ;; x86_64) TARGET=x86_64-linux-android NDK_API=21 ;; *) exit 1 ;; esac rm -rf _android_prefix mkdir -p _android_prefix PREFIX=$PWD/_android_prefix TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64 SYSROOT=$TOOLCHAIN/sysroot export CC="$TOOLCHAIN/bin/$TARGET$NDK_API"-clang export LDFLAGS=-static-libstdc++ export PKG_CONFIG_PATH="$PREFIX"/lib/pkgconfig # Build libsodium if [ ! -d libsodium ]; then git clone --branch=1.0.18 https://github.com/jedisct1/libsodium.git fi cd libsodium git clean -ffdx autoreconf -fi ./configure --prefix="$PREFIX" --host="$TARGET" --with-sysroot="$SYSROOT" --disable-shared make -j"$(nproc)" install cd .. # Build c-toxcore rm -rf _build mkdir -p _build cd _build cmake .. \ -DBUILD_TOXAV=OFF \ -DBOOTSTRAP_DAEMON=OFF \ -DCMAKE_TOOLCHAIN_FILE="$NDK/build/cmake/android.toolchain.cmake" \ -DANDROID_ABI="$ABI" \ -DCMAKE_INSTALL_PREFIX="$PREFIX" \ -DCMAKE_PREFIX_PATH="$PREFIX" cmake --build . c-toxcore-0.2.18/.github/scripts/cmake-freebsd-stage20000777000175000017500000000221114227324767021357 0ustar robinrobin#!/bin/bash # Copyright (C) 2018-2021 nurupo # Toxcore building set -eux if [ "$PWD" != "/work" ]; then cd .. mv c-toxcore / mkdir c-toxcore cd /work fi . cmake-freebsd-run.sh # === Get VM ready to build the code === gunzip "$IMAGE_NAME.gz" start_vm # Copy over toxcore code from host to qemu scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -P "$SSH_PORT" -r /c-toxcore root@localhost:~ RUN ls -lh cd /c-toxcore . ".github/scripts/flags-clang.sh" add_ld_flag -Wl,-z,defs # Make compilation error on a warning add_flag -Werror RUN 'cmake -B_build -Hc-toxcore \ -DCMAKE_C_FLAGS="$C_FLAGS" \ -DCMAKE_CXX_FLAGS="$CXX_FLAGS" \ -DCMAKE_EXE_LINKER_FLAGS="$LD_FLAGS" \ -DCMAKE_SHARED_LINKER_FLAGS="$LD_FLAGS" \ -DCMAKE_INSTALL_PREFIX:PATH="_install" \ -DMIN_LOGGER_LEVEL=TRACE \ -DMUST_BUILD_TOXAV=ON \ -DNON_HERMETIC_TESTS=ON \ -DSTRICT_ABI=ON \ -DTEST_TIMEOUT_SECONDS=90 \ -DUSE_IPV6=OFF \ -DAUTOTEST=ON' # We created the VM with the same number of cores as the host, so the host-ran `nproc` here is fine RUN 'gmake "-j$NPROC" -k install -C_build' RUN 'gmake "-j$NPROC" test ARGS="-j50" -C_build || true' c-toxcore-0.2.18/.github/scripts/cmake-osx0000777000175000017500000000212714227324767017401 0ustar robinrobin#!/bin/bash set -eu NPROC=$(sysctl -n hw.physicalcpu) # Workaround for bug in Homebrew where it only finds an old Ruby version. brew update brew install \ libconfig \ libsodium \ libvpx \ opus . ".github/scripts/flags-clang.sh" add_ld_flag -undefined error # Make compilation error on a warning add_flag -Werror # Allow _Static_assert. Supported C11 extensions are fine, since we have several # C99-only compilers we test against anyway. Anything that passes all the # compilers we use is fine. add_c_flag -Wno-c11-extensions cmake -B_build -H. \ -DCMAKE_C_FLAGS="$C_FLAGS" \ -DCMAKE_CXX_FLAGS="$CXX_FLAGS" \ -DCMAKE_EXE_LINKER_FLAGS="$LD_FLAGS" \ -DCMAKE_SHARED_LINKER_FLAGS="$LD_FLAGS" \ -DCMAKE_INSTALL_PREFIX:PATH="$PWD/_install" \ -DMIN_LOGGER_LEVEL=TRACE \ -DMUST_BUILD_TOXAV=ON \ -DNON_HERMETIC_TESTS=ON \ -DTEST_TIMEOUT_SECONDS=120 \ -DUSE_IPV6=OFF \ -DAUTOTEST=ON cd _build # pushd make "-j$NPROC" -k install ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 || ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 cd - # popd c-toxcore-0.2.18/.github/scripts/cmake-win320000777000175000017500000000014314227324767017526 0ustar robinrobin#!/usr/bin/env bash i686=true x86_64=false WINDOWS_ARCH=win32 . .github/scripts/cmake-windows.sh c-toxcore-0.2.18/.github/scripts/cmake-win640000777000175000017500000000014314227324767017533 0ustar robinrobin#!/usr/bin/env bash i686=false x86_64=true WINDOWS_ARCH=win64 . .github/scripts/cmake-windows.sh c-toxcore-0.2.18/.github/scripts/cmake-windows.sh0000777000175000017500000000140714227324767020673 0ustar robinrobin#!/bin/bash set -eu NPROC=$(nproc) . ".github/scripts/flags-gcc.sh" # Allows wine to display source code file names and line numbers on crash in # its backtrace. add_flag -gdwarf-2 # Fix invalid register for .seh_savexmm error add_flag -fno-asynchronous-unwind-tables docker run \ -e ALLOW_TEST_FAILURE=true \ -e ENABLE_ARCH_i686="$i686" \ -e ENABLE_ARCH_x86_64="$x86_64" \ -e ENABLE_TEST=true \ -e EXTRA_CMAKE_FLAGS="-DBOOTSTRAP_DAEMON=OFF -DMIN_LOGGER_LEVEL=DEBUG -DTEST_TIMEOUT_SECONDS=90 -DAUTOTEST=ON" \ -e CMAKE_C_FLAGS="$C_FLAGS" \ -e CMAKE_CXX_FLAGS="$CXX_FLAGS" \ -e CMAKE_EXE_LINKER_FLAGS="$LD_FLAGS" \ -e CMAKE_SHARED_LINKER_FLAGS="$LD_FLAGS" \ -v "$PWD:/toxcore" \ -v "$PWD/result:/prefix" \ --rm \ "toxchat/windows:$WINDOWS_ARCH" c-toxcore-0.2.18/.github/scripts/coverage-linux0000777000175000017500000000263414227324767020445 0ustar robinrobin#!/bin/bash set -eu NPROC=$(nproc) sudo apt-get install -y --no-install-recommends \ libgtest-dev \ libopus-dev \ libsodium-dev \ libvpx-dev \ llvm-11 \ ninja-build git clone --depth=1 https://github.com/ralight/mallocfail /tmp/mallocfail cd /tmp/mallocfail # pushd make sudo make install cd - # popd export CC=clang export CXX=clang++ sudo install other/docker/coverage/run_mallocfail /usr/local/bin/run_mallocfail (cd other/proxy && go build) other/proxy/proxy & . ".github/scripts/flags-coverage.sh" cmake -B_build -H. -GNinja \ -DCMAKE_C_FLAGS="$C_FLAGS" \ -DCMAKE_CXX_FLAGS="$CXX_FLAGS" \ -DCMAKE_EXE_LINKER_FLAGS="$LD_FLAGS" \ -DCMAKE_SHARED_LINKER_FLAGS="$LD_FLAGS" \ -DCMAKE_INSTALL_PREFIX:PATH="$PWD/_install" \ -DENABLE_SHARED=OFF \ -DMIN_LOGGER_LEVEL=TRACE \ -DMUST_BUILD_TOXAV=ON \ -DNON_HERMETIC_TESTS=OFF \ -DSTRICT_ABI=ON \ -DTEST_TIMEOUT_SECONDS=120 \ -DUSE_IPV6=OFF \ -DAUTOTEST=ON \ -DPROXY_TEST=ON cmake --build _build --parallel "$NPROC" --target install -- -k 0 cd _build # pushd ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 || ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 export PYTHONUNBUFFERED=1 run_mallocfail --ctest=2 --jobs=8 cd - # popd #coveralls \ # --exclude auto_tests \ # --exclude other \ # --exclude testing \ # --gcov-options '\-lp' bash <(curl -s https://codecov.io/bash) -x "llvm-cov-11 gcov" c-toxcore-0.2.18/.github/scripts/flags-clang.sh0000777000175000017500000000520714227324767020303 0ustar robinrobin#!/bin/bash . .github/scripts/flags.sh # Add all warning flags we can. add_flag -Wall add_flag -Wextra add_flag -Weverything # Disable specific warning flags for both C and C++. # Very verbose, not very useful. This warns about things like int -> uint # conversions that change sign without a cast and narrowing conversions. add_flag -Wno-conversion # TODO(iphydf): Check enum values when received from the user, then assume # correctness and remove this suppression. add_flag -Wno-covered-switch-default # Due to clang's tolower() macro being recursive # https://github.com/TokTok/c-toxcore/pull/481 add_flag -Wno-disabled-macro-expansion # We don't put __attribute__ on the public API. add_flag -Wno-documentation-deprecated-sync # Bootstrap daemon does this. add_flag -Wno-format-nonliteral # struct Foo foo = {0}; is a common idiom. Missing braces means we'd need to # write {{{0}}} in some cases, which is ugly and a maintenance burden. add_flag -Wno-missing-braces add_flag -Wno-missing-field-initializers # We don't use this attribute. It appears in the non-NDEBUG stderr logger. add_flag -Wno-missing-noreturn # Useful sometimes, but we accept padding in structs for clarity. # Reordering fields to avoid padding will reduce readability. add_flag -Wno-padded # This warns on things like _XOPEN_SOURCE, which we currently need (we # probably won't need these in the future). add_flag -Wno-reserved-id-macro # TODO(iphydf): Clean these up. They are likely not bugs, but still # potential issues and probably confusing. add_flag -Wno-sign-compare # __attribute__((nonnull)) causes this warning on defensive null checks. add_flag -Wno-tautological-pointer-compare # Our use of mutexes results in a false positive, see 1bbe446. add_flag -Wno-thread-safety-analysis # File transfer code has this. add_flag -Wno-type-limits # Callbacks often don't use all their parameters. add_flag -Wno-unused-parameter # cimple does this better add_flag -Wno-unused-function # libvpx uses __attribute__((unused)) for "potentially unused" static # functions to avoid unused static function warnings. add_flag -Wno-used-but-marked-unused # We use variable length arrays a lot. add_flag -Wno-vla # Disable warnings about unknown Doxygen commands add_flag -Wno-documentation-unknown-command # Disable specific warning flags for C++. # Comma at end of enum is supported everywhere we run. add_cxx_flag -Wno-c++98-compat-pedantic # TODO(iphydf): Stop using flexible array members. add_cxx_flag -Wno-c99-extensions # We're C-compatible, so use C style casts. add_cxx_flag -Wno-old-style-cast # Downgrade to warning so we still see it. add_flag -Wno-error=unreachable-code add_flag -Wno-error=unused-variable c-toxcore-0.2.18/.github/scripts/flags-coverage.sh0000777000175000017500000000145014227324767021006 0ustar robinrobin#!/bin/bash . .github/scripts/flags-clang.sh add_ld_flag -Wl,-z,defs # Make compilation error on a warning add_flag -Werror # Coverage flags. add_flag --coverage # Optimisation, but keep stack traces useful. add_c_flag -fno-inline -fno-omit-frame-pointer # Show useful stack traces on crash. add_flag -fsanitize=undefined -fno-sanitize-recover=all # In test code (_test.cc and libgtest), throw away all debug information. # We only care about stack frames inside toxcore (which is C). Without this, # mallocfail will spend a lot of time finding all the ways in which gtest can # fail to allocate memory, which is not interesting to us. add_cxx_flag -g0 # Continue executing code in error paths so we can see it cleanly exit (and the # test code itself may abort). add_flag -DABORT_ON_LOG_ERROR=false c-toxcore-0.2.18/.github/scripts/flags-gcc.sh0000777000175000017500000000347314227324767017756 0ustar robinrobin#!/bin/bash . .github/scripts/flags.sh # Add all warning flags we can. add_flag -Wall add_flag -Wextra # Some additional warning flags not enabled by any of the above. add_flag -Wbool-compare add_flag -Wcast-align add_flag -Wcast-qual add_flag -Wchar-subscripts add_flag -Wdouble-promotion add_flag -Wduplicated-cond add_flag -Wempty-body add_flag -Wenum-compare add_flag -Wfloat-equal add_flag -Wformat=2 add_flag -Wframe-address add_flag -Wframe-larger-than=9000 add_flag -Wignored-attributes add_flag -Wignored-qualifiers add_flag -Winit-self add_flag -Winline add_flag -Wlarger-than=530000 add_flag -Wmaybe-uninitialized add_flag -Wmemset-transposed-args add_flag -Wmisleading-indentation add_flag -Wmissing-declarations add_flag -Wnonnull add_flag -Wnull-dereference add_flag -Wodr add_flag -Wredundant-decls add_flag -Wreturn-type add_flag -Wshadow add_flag -Wsuggest-attribute=format add_flag -Wundef add_flag -Wunsafe-loop-optimizations add_flag -Wunused-but-set-parameter add_flag -Wunused-but-set-variable add_flag -Wunused-label add_flag -Wunused-local-typedefs add_flag -Wunused-value # Disable specific warning flags for both C and C++. # struct Foo foo = {0}; is a common idiom. add_flag -Wno-missing-field-initializers # TODO(iphydf): Clean these up. They are likely not bugs, but still # potential issues and probably confusing. add_flag -Wno-sign-compare # File transfer code has this. add_flag -Wno-type-limits # Callbacks often don't use all their parameters. add_flag -Wno-unused-parameter # cimple does this better add_flag -Wno-unused-function # struct Foo foo = {0}; is a common idiom. Missing braces means we'd need to # write {{{0}}} in some cases, which is ugly and a maintenance burden. add_flag -Wno-missing-braces # __attribute__((nonnull)) causes this warning on defensive null checks. add_flag -Wno-nonnull-compare c-toxcore-0.2.18/.github/scripts/flags.sh0000777000175000017500000000142414227324767017216 0ustar robinrobin#!/bin/bash add_config_flag() { CONFIG_FLAGS+=("$@"); } add_c_flag() { C_FLAGS="$C_FLAGS $@"; } add_cxx_flag() { CXX_FLAGS="$CXX_FLAGS $@"; } add_ld_flag() { LD_FLAGS="$LD_FLAGS $@"; } add_flag() { add_c_flag "$@" add_cxx_flag "$@" } # Our own flags which we can insert in the correct place. We don't use CFLAGS # and friends here (we unset them below), because they influence config tests # such as ./configure and cmake tests. Our warning flags break those tests, so # we can't add them globally here. CONFIG_FLAGS=() C_FLAGS="" CXX_FLAGS="" LD_FLAGS="" unset CFLAGS unset CXXFLAGS unset CPPFLAGS unset LDFLAGS # Optimisation flags. add_flag -O3 -march=native # Warn on non-ISO C. add_c_flag -pedantic add_c_flag -std=c99 add_cxx_flag -std=c++11 add_flag -g3 add_flag -ftrapv c-toxcore-0.2.18/.github/scripts/sonar-build0000777000175000017500000000017414227324767017731 0ustar robinrobin#!/bin/bash set -eu . ".github/scripts/flags-gcc.sh" cmake --build _build --parallel "$(nproc)" --target install -- -k 0 c-toxcore-0.2.18/.github/scripts/sonar-prepare0000777000175000017500000000126314227324767020270 0ustar robinrobin#!/bin/bash set -eu sudo apt-get install -y --no-install-recommends \ libconfig-dev \ libopus-dev \ libsodium-dev \ libvpx-dev \ ninja-build . ".github/scripts/flags-gcc.sh" add_ld_flag -Wl,-z,defs # Make compilation error on a warning add_flag -Werror cmake -B_build -H. -GNinja \ -DCMAKE_C_FLAGS="$C_FLAGS" \ -DCMAKE_CXX_FLAGS="$CXX_FLAGS" \ -DCMAKE_EXE_LINKER_FLAGS="$LD_FLAGS" \ -DCMAKE_SHARED_LINKER_FLAGS="$LD_FLAGS" \ -DCMAKE_INSTALL_PREFIX:PATH="$PWD/_install" \ -DMIN_LOGGER_LEVEL=TRACE \ -DMUST_BUILD_TOXAV=ON \ -DNON_HERMETIC_TESTS=OFF \ -DSTRICT_ABI=ON \ -DTEST_TIMEOUT_SECONDS=120 \ -DUSE_IPV6=OFF \ -DAUTOTEST=ON \ -DENABLE_SHARED=OFF c-toxcore-0.2.18/.github/scripts/tox-bootstrapd-docker0000777000175000017500000000370314227324767021751 0ustar robinrobin#!/bin/bash set -exu LOCAL="${1:-}" readarray -t FILES <<<"$(git ls-files)" tar c "${FILES[@]}" | docker build -f other/bootstrap_daemon/docker/Dockerfile -t toxchat/bootstrap-node - docker tag toxchat/bootstrap-node:latest toxchat/bootstrap-node:"$(other/print-version)" sudo useradd \ --home-dir /var/lib/tox-bootstrapd \ --create-home \ --system \ --shell /sbin/nologin \ --comment "Account to run Tox's DHT bootstrap daemon" \ --user-group tox-bootstrapd sudo chmod 700 /var/lib/tox-bootstrapd docker run -d --name tox-bootstrapd \ --user "$(id -u tox-bootstrapd):$(id -g tox-bootstrapd)" \ -v /var/lib/tox-bootstrapd/:/var/lib/tox-bootstrapd/ \ --ulimit nofile=32768:32768 \ -p 443:443 \ -p 3389:3389 \ -p 33445:33445 \ -p 33445:33445/udp \ toxchat/bootstrap-node sudo ls -lbh /var/lib/tox-bootstrapd if sudo [ ! -f /var/lib/tox-bootstrapd/keys ]; then echo "Error: File /var/lib/tox-bootstrapd/keys doesn't exist" exit 1 fi if [ "$LOCAL" != "local" ]; then COUNTER=0 COUNTER_END=120 while [ "$COUNTER" -lt "$COUNTER_END" ]; do if docker logs tox-bootstrapd | grep -q "Connected to another bootstrap node successfully"; then break fi sleep 1 COUNTER=$(($COUNTER + 1)) done docker logs tox-bootstrapd if [ "$COUNTER" = "$COUNTER_END" ]; then echo "Error: Didn't connect to any nodes" exit 1 fi else docker logs tox-bootstrapd fi # Wait a bit before testing if the container is still running sleep 30 docker ps -a if [ "$(docker inspect -f {{.State.Running}} tox-bootstrapd)" != "true" ]; then echo "Error: Container is not running" exit 1 fi cat /proc/"$(pidof tox-bootstrapd)"/limits if ! grep -P '^Max open files(\s+)32768(\s+)32768(\s+)files' /proc/"$(pidof tox-bootstrapd)"/limits; then echo "Error: ulimit is not set to the expected value" exit 1 fi if ! other/fun/bootstrap_node_info.py ipv4 localhost 33445; then echo "Error: Unable to get bootstrap node info" exit 1 fi c-toxcore-0.2.18/.github/settings.yml0000777000175000017500000000324314227324767016463 0ustar robinrobin--- _extends: .github repository: name: c-toxcore description: The future of online communications. homepage: https://tox.chat/ topics: toxcore, network, p2p, security, encryption, cryptography branches: - name: "master" protection: required_status_checks: contexts: - "bazel-asan" - "bazel-dbg" - "bazel-opt" - "bazel-tsan" - "build-compcert" - "build-macos" - "build-nacl" - "build-tcc" - "build-win32" - "build-win64" - "CodeFactor" - "common / buildifier" - "coverage-linux" - "ci/circleci: asan" - "ci/circleci: clang-analyze" - "ci/circleci: clang-tidy" - "ci/circleci: cpplint" - "ci/circleci: infer" - "ci/circleci: msan" - "ci/circleci: static-analysis" - "ci/circleci: tsan" - "ci/circleci: ubsan" - "cimple" - "code-review/reviewable" - "continuous-integration/appveyor/pr" - "docker-bootstrap-node" - "docker-bootstrap-node-websocket" - "docker-toxcore-js" - "mypy" - "sonar-scan" # Labels specific to c-toxcore. labels: - name: "bootstrap" color: "#01707f" description: "Bootstrap" - name: "crypto" color: "#1d76db" description: "Crypto" - name: "file transfers" color: "#e02abf" description: "File Transfers" - name: "messenger" color: "#d93f0b" description: "Messenger" - name: "network" color: "#d4c5f9" description: "Network" - name: "toxav" color: "#0052cc" description: "Audio/video" c-toxcore-0.2.18/.github/workflows/0000777000175000017500000000000014227324767016130 5ustar robinrobinc-toxcore-0.2.18/.github/workflows/cflite_batch.yml0000777000175000017500000000247214227324767021272 0ustar robinrobin# Derived from: https://google.github.io/clusterfuzzlite/running-clusterfuzzlite/github-actions/ name: ClusterFuzzLite batch fuzzing on: schedule: - cron: '0 6,8 * * *' # Run twice a day at low activity times workflow_dispatch: # Manual trigger for testing permissions: read-all jobs: BatchFuzzing: runs-on: ubuntu-latest strategy: fail-fast: false matrix: sanitizer: - address - undefined - memory steps: - name: Build Fuzzers (${{ matrix.sanitizer }}) id: build uses: google/clusterfuzzlite/actions/build_fuzzers@v1 with: sanitizer: ${{ matrix.sanitizer }} - name: Run Fuzzers (${{ matrix.sanitizer }}) id: run uses: google/clusterfuzzlite/actions/run_fuzzers@v1 with: github-token: ${{ secrets.GITHUB_TOKEN }} fuzz-seconds: 3600 # 60min mode: 'batch' sanitizer: ${{ matrix.sanitizer }} # Optional but recommended: For storing certain artifacts from fuzzing. # See later section on "Git repo for storage". storage-repo: https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/TokTok/toktok-fuzzer.git storage-repo-branch: master # Optional. Defaults to "main" storage-repo-branch-coverage: gh-pages # Optional. Defaults to "gh-pages". c-toxcore-0.2.18/.github/workflows/cflite_cron.yml0000777000175000017500000000335414227324767021152 0ustar robinrobin# Derived from: https://google.github.io/clusterfuzzlite/running-clusterfuzzlite/github-actions/ name: ClusterFuzzLite cron tasks on: schedule: - cron: '0 10 * * *' # Once a day, after fuzzing run workflow_dispatch: # Manual trigger for testing permissions: read-all jobs: Pruning: runs-on: ubuntu-latest steps: - name: Build Fuzzers id: build uses: google/clusterfuzzlite/actions/build_fuzzers@v1 - name: Run Fuzzers id: run uses: google/clusterfuzzlite/actions/run_fuzzers@v1 with: github-token: ${{ secrets.GITHUB_TOKEN }} fuzz-seconds: 600 mode: 'prune' # Optional but recommended. # See later section on "Git repo for storage". storage-repo: https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/TokTok/toktok-fuzzer.git storage-repo-branch: master # Optional. Defaults to "main" storage-repo-branch-coverage: gh-pages # Optional. Defaults to "gh-pages". Coverage: runs-on: ubuntu-latest steps: - name: Build Fuzzers id: build uses: google/clusterfuzzlite/actions/build_fuzzers@v1 with: sanitizer: coverage - name: Run Fuzzers id: run uses: google/clusterfuzzlite/actions/run_fuzzers@v1 with: github-token: ${{ secrets.GITHUB_TOKEN }} fuzz-seconds: 600 mode: 'coverage' sanitizer: 'coverage' # Optional but recommended. # See later section on "Git repo for storage". storage-repo: https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/TokTok/toktok-fuzzer.git storage-repo-branch: master # Optional. Defaults to "main" storage-repo-branch-coverage: gh-pages # Optional. Defaults to "gh-pages". c-toxcore-0.2.18/.github/workflows/ci.yml0000777000175000017500000001323414227324767017254 0ustar robinrobinname: ci on: pull_request: branches: [master] # Cancel old PR builds when pushing new commits. concurrency: group: build-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: common: uses: TokTok/ci-tools/.github/workflows/common-ci.yml@master mypy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: submodules: recursive - name: Set up Python 3.9 uses: actions/setup-python@v1 with: python-version: 3.9 - name: Install mypy run: pip install mypy - name: Run mypy run: | (find . -name "*.py" -and -not -name "conanfile.py"; grep -lR '^#!.*python') \ | xargs -n1 -P8 mypy --strict doxygen: runs-on: ubuntu-latest steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: Docker Build uses: docker/build-push-action@v2 with: file: other/docker/doxygen/Dockerfile tokstyle: runs-on: ubuntu-latest steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: Docker Build uses: docker/build-push-action@v2 with: file: other/docker/tokstyle/Dockerfile misra: runs-on: ubuntu-latest steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: Docker Build uses: docker/build-push-action@v2 with: file: other/docker/misra/Dockerfile cimplefmt: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: submodules: recursive - name: Run cimplefmt run: other/docker/cimplefmt/run -u $(find tox* -name "*.[ch]") build-nacl: runs-on: ubuntu-latest steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: Docker Build uses: docker/build-push-action@v2 with: file: other/docker/autotools/Dockerfile build-win32: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: submodules: recursive - name: Cross compilation run: .github/scripts/cmake-win32 script build-win64: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: submodules: recursive - name: Cross compilation run: .github/scripts/cmake-win64 script build-freebsd: runs-on: ubuntu-latest container: toxchat/freebsd steps: - uses: actions/checkout@v2 with: submodules: recursive - name: Build on FreeBSD run: .github/scripts/cmake-freebsd-stage2 build-macos: runs-on: macos-latest steps: - uses: actions/checkout@v2 with: submodules: recursive - name: Build and test run: .github/scripts/cmake-osx coverage-linux: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: submodules: recursive - name: Build, test, and upload coverage run: .github/scripts/coverage-linux build-tcc: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: submodules: recursive - name: Install dependencies run: sudo apt-get install -y --no-install-recommends tcc libconfig-dev libopus-dev libsodium-dev libvpx-dev - name: Build with TCC run: tcc -Dinline=static -o send_message_test -Wall -Werror -bench -g auto_tests/auto_test_support.c auto_tests/send_message_test.c testing/misc_tools.c toxav/*.c toxcore/*.c toxcore/*/*.c toxencryptsave/*.c third_party/cmp/*.c $(pkg-config --cflags --libs libsodium opus vpx) - name: Run the test run: "./send_message_test | grep 'tox clients connected'" - name: Build amalgamation file with TCC run: other/make_single_file auto_tests/auto_test_support.c auto_tests/send_message_test.c testing/misc_tools.c | tcc - -o send_message_test -Wall -Werror -bench -g $(pkg-config --cflags --libs libsodium opus vpx) - name: Run the test again run: "./send_message_test | grep 'tox clients connected'" build-compcert: runs-on: ubuntu-latest container: toxchat/compcert steps: - uses: actions/checkout@v2 with: submodules: recursive - name: Build with CompCert run: ccomp -o send_message_test -Wall -Werror -Wno-c11-extensions -Wno-unknown-pragmas -Wno-unused-variable -fstruct-passing -fno-unprototyped -g auto_tests/auto_test_support.c auto_tests/send_message_test.c testing/misc_tools.c toxav/*.c toxcore/*.c toxcore/*/*.c toxencryptsave/*.c third_party/cmp/*.c -D__COMPCERT__ -DDISABLE_VLA -Dinline= -lpthread $(pkg-config --cflags --libs libsodium opus vpx) - name: Run the test run: "./send_message_test | grep 'tox clients connected'" build-android: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: submodules: recursive - run: .github/scripts/cmake-android armeabi-v7a - run: .github/scripts/cmake-android arm64-v8a - run: .github/scripts/cmake-android x86 - run: .github/scripts/cmake-android x86_64 c-toxcore-0.2.18/.github/workflows/coverity-scan.yml0000777000175000017500000000302214227324767021441 0ustar robinrobinname: coverity-scan on: schedule: - cron: '0 10 * * *' # Once a day jobs: latest: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: submodules: recursive - name: Install libraries run: sudo apt-get update && sudo apt-get install -y --no-install-recommends libopus-dev libsodium-dev libvpx-dev - name: Download Coverity Build Tool run: | wget -q https://scan.coverity.com/download/cxx/linux64 --post-data "token=$TOKEN&project=TokTok/c-toxcore" -O cov-analysis-linux64.tar.gz mkdir cov-analysis-linux64 tar xzf cov-analysis-linux64.tar.gz --strip 1 -C cov-analysis-linux64 env: TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }} - name: Run autoreconf run: autoreconf -fi - name: Configure run: ./configure - name: Build with cov-build run: cov-analysis-linux64/bin/cov-build --dir cov-int make - name: Submit the result to Coverity Scan run: tar czvf c-toxcore.tgz cov-int && curl --form project=TokTok/c-toxcore --form token=$TOKEN --form email=iphydf@gmail.com --form file=@c-toxcore.tgz --form version="$(git rev-list --count HEAD)" --form description="CI build of $(git rev-parse --abbrev-ref HEAD) branch" https://scan.coverity.com/builds env: TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }} c-toxcore-0.2.18/.github/workflows/docker.yml0000777000175000017500000001441514227324767020132 0ustar robinrobinname: docker on: push: branches: [master] pull_request: branches: [master] jobs: docker-bootstrap-node: runs-on: ubuntu-latest steps: - name: Login to DockerHub if: ${{ github.event_name == 'push' }} uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - uses: actions/checkout@v2 with: submodules: recursive - name: Docker Build run: .github/scripts/tox-bootstrapd-docker local - name: Push latest image to DockerHub if: ${{ github.event_name == 'push' }} run: docker push toxchat/bootstrap-node:latest - name: Push versioned image to DockerHub if: ${{ github.event_name == 'push' && contains(github.ref, 'refs/tags/') }} run: docker push toxchat/bootstrap-node:"$(other/print-version)" docker-bootstrap-node-websocket: runs-on: ubuntu-latest needs: [docker-bootstrap-node] steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: Login to DockerHub if: ${{ github.event_name == 'push' }} uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v2 with: context: "{{defaultContext}}:other/bootstrap_daemon/websocket" push: ${{ github.event_name == 'push' }} tags: toxchat/bootstrap-node:latest-websocket cache-from: type=registry,ref=toxchat/bootstrap-node:latest-websocket cache-to: type=inline docker-clusterfuzz: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: Login to DockerHub if: ${{ github.event_name == 'push' }} uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v2 with: context: "." file: .clusterfuzzlite/Dockerfile push: ${{ github.event_name == 'push' }} tags: toxchat/c-toxcore:clusterfuzz cache-from: type=registry,ref=toxchat/c-toxcore:clusterfuzz cache-to: type=inline docker-fuzzer: runs-on: ubuntu-latest steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: Login to DockerHub if: ${{ github.event_name == 'push' }} uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v2 with: file: testing/Dockerfile push: ${{ github.event_name == 'push' }} tags: toxchat/c-toxcore:fuzzer cache-from: type=registry,ref=toxchat/c-toxcore:fuzzer cache-to: type=inline docker-toxcore-js: runs-on: ubuntu-latest steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: Login to DockerHub if: ${{ github.event_name == 'push' }} uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v2 with: file: other/emscripten/Dockerfile push: ${{ github.event_name == 'push' }} tags: toxchat/c-toxcore:wasm cache-from: type=registry,ref=toxchat/c-toxcore:wasm cache-to: type=inline docker-esp32: runs-on: ubuntu-latest steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 with: driver: docker - name: Login to DockerHub if: ${{ github.event_name == 'push' }} uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build toxchat/c-toxcore:sources uses: docker/build-push-action@v2 with: file: other/docker/sources/Dockerfile tags: toxchat/c-toxcore:sources - name: Build and push uses: docker/build-push-action@v2 with: file: other/docker/esp32/Dockerfile push: ${{ github.event_name == 'push' }} tags: toxchat/c-toxcore:esp32 cache-from: type=registry,ref=toxchat/c-toxcore:esp32 cache-to: type=inline docker-win32: runs-on: ubuntu-latest steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: Login to DockerHub if: ${{ github.event_name == 'push' }} uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v2 with: context: "{{defaultContext}}:other/docker/windows" push: ${{ github.event_name == 'push' }} tags: toxchat/windows:win32 cache-from: type=registry,ref=toxchat/windows:win32 cache-to: type=inline build-args: | SUPPORT_ARCH_i686=true SUPPORT_ARCH_x86_64=false SUPPORT_TEST=true docker-win64: runs-on: ubuntu-latest steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: Login to DockerHub if: ${{ github.event_name == 'push' }} uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v2 with: context: "{{defaultContext}}:other/docker/windows" push: ${{ github.event_name == 'push' }} tags: toxchat/windows:win64 cache-from: type=registry,ref=toxchat/windows:win64 cache-to: type=inline build-args: | SUPPORT_ARCH_i686=false SUPPORT_ARCH_x86_64=true SUPPORT_TEST=true c-toxcore-0.2.18/.github/workflows/sonar-scan.yml0000777000175000017500000000424714227324767020731 0ustar robinrobinname: sonar-scan on: push: branches: [master] pull_request: branches: [master] jobs: sonar-scan: runs-on: ubuntu-latest env: SONAR_SCANNER_VERSION: 4.4.0.2170 SONAR_SERVER_URL: "https://sonarcloud.io" BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed steps: - uses: actions/checkout@v2 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis submodules: recursive - name: Set up JDK 11 uses: actions/setup-java@v1 with: java-version: 11 - name: Download and set up sonar-scanner env: SONAR_SCANNER_DOWNLOAD_URL: https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${{ env.SONAR_SCANNER_VERSION }}-linux.zip run: | mkdir -p $HOME/.sonar curl -sSLo $HOME/.sonar/sonar-scanner.zip ${{ env.SONAR_SCANNER_DOWNLOAD_URL }} unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/ echo "$HOME/.sonar/sonar-scanner-${{ env.SONAR_SCANNER_VERSION }}-linux/bin" >> $GITHUB_PATH - name: Download and set up build-wrapper env: BUILD_WRAPPER_DOWNLOAD_URL: ${{ env.SONAR_SERVER_URL }}/static/cpp/build-wrapper-linux-x86.zip run: | curl -sSLo $HOME/.sonar/build-wrapper-linux-x86.zip ${{ env.BUILD_WRAPPER_DOWNLOAD_URL }} unzip -o $HOME/.sonar/build-wrapper-linux-x86.zip -d $HOME/.sonar/ echo "$HOME/.sonar/build-wrapper-linux-x86" >> $GITHUB_PATH - name: Install dependencies and prepare build run: | .github/scripts/sonar-prepare - name: Run build-wrapper run: | build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} .github/scripts/sonar-build - name: Run sonar-scanner if: github.event_name == 'push' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: 'sonar-scanner --define sonar.host.url="${{ env.SONAR_SERVER_URL }}" --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"' c-toxcore-0.2.18/.gitignore0000777000175000017500000000146314227324767014532 0ustar robinrobin# OS files .DS_Store .DS_Store? ._* .mypy_cache .Spotlight-V100 .Trash* Icon? ethumbs.db Thumbs.db *.tmp # Make /_build /_install /tox-0.0.0* CMakeCache.txt CMakeFiles Makefile !/other/rpm/Makefile cmake_install.cmake install_manifest.txt tags Makefile.in CMakeLists.txt.user DartConfiguration.tcl CTestTestfile.cmake *.pc # Testing /amalgamation.* testing/data *~ # Vim *.swp # Object files *.o *.lo *.a # Executables *.exe *.out *.app *.la # Libraries *.so # Misc (?) m4/* configure configure_aux !m4/pkg.m4 aclocal.m4 config.h* config.log config.status stamp-h1 autom4te.cache libtool .deps .libs .dirstamp build/ #kdevelop .kdev/ *.kdev* # VScode .vscode/ # Netbeans nbproject # astyle *.orig # Android buildscript android-toolchain-* toxcore-android-* # cscope files list cscope.files # rpm tox.spec c-toxcore-0.2.18/.gitmodules0000777000175000017500000000013414227324767014711 0ustar robinrobin[submodule "third_party/cmp"] path = third_party/cmp url = https://github.com/camgunz/cmp c-toxcore-0.2.18/.hadolint.yaml0000777000175000017500000000047214227324767015305 0ustar robinrobin--- ignored: # "cd" is sometimes useful when you want to run one command in one directory # and then another command in another directory, but they should be executed # in the same RUN instruction. - DL3003 - DL3007 - DL3008 - DL3013 - DL3018 - DL3059 # $(pkg-config ...) needs this - SC2046 c-toxcore-0.2.18/.restyled.yaml0000777000175000017500000000065014227324767015334 0ustar robinrobin--- exclude: - "**/*.api.h" # shfmt doesn't support this file - "other/analysis/run-clang-tidy" restylers: - astyle: arguments: ["--options=other/astyle/astylerc"] include: - "!**/*.cc" - autopep8 - black - clang-format: image: restyled/restyler-clang-format:13.0.1 include: - "**/*.cc" - prettier-yaml - reorder-python-imports - shellharden - shfmt - yapf c-toxcore-0.2.18/appveyor.yml0000777000175000017500000000123014227324767015122 0ustar robinrobin--- image: Visual Studio 2019 cache: - '%USERPROFILE%\.conan -> conanfile.py' environment: matrix: - job_name: static - job_name: shared install: - set PATH=C:\Python310-x64\Scripts;%PATH% - py -3 -m pip install conan - git submodule update --init --recursive for: - matrix: only: - job_name: static before_build: - conan install -if _build -o with_tests=True . - matrix: only: - job_name: shared before_build: - conan install -if _build -o with_tests=True -o shared=True . build_script: - set CONAN_CPU_COUNT=50 - set CTEST_OUTPUT_ON_FAILURE=1 - conan build -bf _build -if _build . c-toxcore-0.2.18/autogen.sh0000777000175000017500000000010414227324767014527 0ustar robinrobin#!/bin/sh -e echo 'Running autoreconf -if...' ( autoreconf -if ) c-toxcore-0.2.18/auto_tests/0000777000175000017500000000000014227324767014725 5ustar robinrobinc-toxcore-0.2.18/auto_tests/announce_test.c0000777000175000017500000001017414227324767017744 0ustar robinrobin#include #include #include "../toxcore/announce.h" #include "../toxcore/tox.h" #include "../testing/misc_tools.h" #include "../toxcore/mono_time.h" #include "../toxcore/forwarding.h" #include "../toxcore/net_crypto.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" static void test_bucketnum(void) { const Random *rng = system_random(); ck_assert(rng != nullptr); uint8_t key1[CRYPTO_PUBLIC_KEY_SIZE], key2[CRYPTO_PUBLIC_KEY_SIZE]; random_bytes(rng, key1, sizeof(key1)); memcpy(key2, key1, CRYPTO_PUBLIC_KEY_SIZE); ck_assert_msg(announce_get_bucketnum(key1, key2) == 0, "Bad bucketnum"); key2[4] ^= 0x09; key2[5] ^= 0xc5; ck_assert_msg(announce_get_bucketnum(key1, key2) == 7, "Bad bucketnum"); key2[4] ^= 0x09; ck_assert_msg(announce_get_bucketnum(key1, key2) == 17, "Bad bucketnum"); key2[5] ^= 0xc5; key2[31] ^= 0x09; ck_assert_msg(announce_get_bucketnum(key1, key2) == 4, "Bad bucketnum"); } typedef struct Announce_Test_Data { uint8_t data[MAX_ANNOUNCEMENT_SIZE]; uint16_t length; bool passed; } Announce_Test_Data; static void test_announce_data(void *object, const uint8_t *data, uint16_t length) { Announce_Test_Data *test_data = (Announce_Test_Data *) object; test_data->passed = test_data->length == length && memcmp(test_data->data, data, length) == 0; } static void test_store_data(void) { const Random *rng = system_random(); ck_assert(rng != nullptr); const Network *ns = system_network(); ck_assert(ns != nullptr); Logger *log = logger_new(); ck_assert(log != nullptr); logger_callback_log(log, (logger_cb *)print_debug_log, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(nullptr, nullptr); Networking_Core *net = new_networking_no_udp(log, ns); DHT *dht = new_dht(log, rng, ns, mono_time, net, true, true); Forwarding *forwarding = new_forwarding(log, rng, mono_time, dht); Announcements *announce = new_announcements(log, rng, mono_time, forwarding); ck_assert(announce != nullptr); /* Just to prevent CI from complaining that set_synch_offset is unused: */ announce_set_synch_offset(announce, 0); Announce_Test_Data test_data; random_bytes(rng, test_data.data, sizeof(test_data.data)); test_data.length = sizeof(test_data.data); uint8_t key[CRYPTO_PUBLIC_KEY_SIZE]; random_bytes(rng, key, sizeof(key)); ck_assert_msg(!announce_on_stored(announce, key, nullptr, nullptr), "Unstored announcement exists"); ck_assert_msg(announce_store_data(announce, key, test_data.data, sizeof(test_data.data), MAX_MAX_ANNOUNCEMENT_TIMEOUT), "Failed to store announcement"); ck_assert_msg(announce_on_stored(announce, key, test_announce_data, &test_data), "Failed to get stored announcement"); ck_assert_msg(test_data.passed, "Bad stored announcement data"); const uint8_t *const base = dht_get_self_public_key(dht); ck_assert_msg(announce_store_data(announce, base, test_data.data, sizeof(test_data.data), 1), "failed to store base"); uint8_t test_keys[ANNOUNCE_BUCKET_SIZE + 1][CRYPTO_PUBLIC_KEY_SIZE]; for (uint8_t i = 0; i < ANNOUNCE_BUCKET_SIZE + 1; ++i) { memcpy(test_keys[i], base, CRYPTO_PUBLIC_KEY_SIZE); test_keys[i][i] ^= 1; ck_assert_msg(announce_store_data(announce, test_keys[i], test_data.data, sizeof(test_data.data), 1), "Failed to store announcement %d", i); } ck_assert_msg(announce_on_stored(announce, base, nullptr, nullptr), "base was evicted"); ck_assert_msg(!announce_on_stored(announce, test_keys[0], nullptr, nullptr), "furthest was not evicted"); ck_assert_msg(!announce_store_data(announce, test_keys[0], nullptr, 0, 1), "furthest evicted closer"); kill_announcements(announce); kill_forwarding(forwarding); kill_dht(dht); kill_networking(net); mono_time_free(mono_time); logger_kill(log); } static void basic_announce_tests(void) { test_bucketnum(); test_store_data(); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); basic_announce_tests(); return 0; } c-toxcore-0.2.18/auto_tests/auto_test_support.c0000777000175000017500000003255314227324767020707 0ustar robinrobin#include // assert #include // calloc, free #include "check_compat.h" #include "../testing/misc_tools.h" #include "../toxcore/Messenger.h" #include "../toxcore/mono_time.h" #include "../toxcore/tox_struct.h" #include "auto_test_support.h" #ifndef ABORT_ON_LOG_ERROR #define ABORT_ON_LOG_ERROR true #endif Run_Auto_Options default_run_auto_options() { return (Run_Auto_Options) { .graph = GRAPH_COMPLETE, .init_autotox = nullptr, .tcp_port = 33188, }; } // List of live bootstrap nodes. These nodes should have TCP server enabled. static const struct BootstrapNodes { const char *ip; uint16_t port; const uint8_t key[32]; } BootstrapNodes[] = { #ifndef USE_TEST_NETWORK { "tox.abilinski.com", 33445, 0x10, 0xC0, 0x0E, 0xB2, 0x50, 0xC3, 0x23, 0x3E, 0x34, 0x3E, 0x2A, 0xEB, 0xA0, 0x71, 0x15, 0xA5, 0xC2, 0x89, 0x20, 0xE9, 0xC8, 0xD2, 0x94, 0x92, 0xF6, 0xD0, 0x0B, 0x29, 0x04, 0x9E, 0xDC, 0x7E, }, { "tox.initramfs.io", 33445, 0x02, 0x80, 0x7C, 0xF4, 0xF8, 0xBB, 0x8F, 0xB3, 0x90, 0xCC, 0x37, 0x94, 0xBD, 0xF1, 0xE8, 0x44, 0x9E, 0x9A, 0x83, 0x92, 0xC5, 0xD3, 0xF2, 0x20, 0x00, 0x19, 0xDA, 0x9F, 0x1E, 0x81, 0x2E, 0x46, }, { "tox.plastiras.org", 33445, 0x8E, 0x8B, 0x63, 0x29, 0x9B, 0x3D, 0x52, 0x0F, 0xB3, 0x77, 0xFE, 0x51, 0x00, 0xE6, 0x5E, 0x33, 0x22, 0xF7, 0xAE, 0x5B, 0x20, 0xA0, 0xAC, 0xED, 0x29, 0x81, 0x76, 0x9F, 0xC5, 0xB4, 0x37, 0x25, }, { "tox.novg.net", 33445, 0xD5, 0x27, 0xE5, 0x84, 0x7F, 0x83, 0x30, 0xD6, 0x28, 0xDA, 0xB1, 0x81, 0x4F, 0x0A, 0x42, 0x2F, 0x6D, 0xC9, 0xD0, 0xA3, 0x00, 0xE6, 0xC3, 0x57, 0x63, 0x4E, 0xE2, 0xDA, 0x88, 0xC3, 0x54, 0x63, }, #else { "172.93.52.70", 33445, 0x79, 0xCA, 0xDA, 0x49, 0x74, 0xB0, 0x92, 0x6F, 0x28, 0x6F, 0x02, 0x5C, 0xD5, 0xFF, 0xDF, 0x3E, 0x65, 0x4A, 0x37, 0x58, 0xC5, 0x3E, 0x02, 0x73, 0xEC, 0xFC, 0x4D, 0x12, 0xC2, 0x1D, 0xCA, 0x48, }, #endif // USE_TEST_NETWORK { nullptr, 0, 0 }, }; void bootstrap_tox_live_network(Tox *tox, bool enable_tcp) { ck_assert(tox != nullptr); for (size_t j = 0; BootstrapNodes[j].ip != nullptr; ++j) { const char *ip = BootstrapNodes[j].ip; uint16_t port = BootstrapNodes[j].port; const uint8_t *key = BootstrapNodes[j].key; Tox_Err_Bootstrap err; tox_bootstrap(tox, ip, port, key, &err); if (err != TOX_ERR_BOOTSTRAP_OK) { fprintf(stderr, "Failed to bootstrap node %zu (%s): error %d\n", j, ip, err); } if (enable_tcp) { tox_add_tcp_relay(tox, ip, port, key, &err); if (err != TOX_ERR_BOOTSTRAP_OK) { fprintf(stderr, "Failed to add TCP relay %zu (%s): error %d\n", j, ip, err); } } } } bool all_connected(const AutoTox *autotoxes, uint32_t tox_count) { if (tox_count) { ck_assert(autotoxes != nullptr); } for (uint32_t i = 0; i < tox_count; ++i) { if (tox_self_get_connection_status(autotoxes[i].tox) == TOX_CONNECTION_NONE) { return false; } } return true; } bool all_friends_connected(const AutoTox *autotoxes, uint32_t tox_count) { if (tox_count) { ck_assert(autotoxes != nullptr); } for (uint32_t i = 0; i < tox_count; ++i) { const size_t friend_count = tox_self_get_friend_list_size(autotoxes[i].tox); for (size_t j = 0; j < friend_count; ++j) { if (tox_friend_get_connection_status(autotoxes[i].tox, j, nullptr) == TOX_CONNECTION_NONE) { return false; } } } return true; } void iterate_all_wait(AutoTox *autotoxes, uint32_t tox_count, uint32_t wait) { if (tox_count) { ck_assert(autotoxes != nullptr); } for (uint32_t i = 0; i < tox_count; ++i) { if (autotoxes[i].alive) { tox_iterate(autotoxes[i].tox, &autotoxes[i]); autotoxes[i].clock += wait; } } /* Also actually sleep a little, to allow for local network processing */ c_sleep(5); } static uint64_t get_state_clock_callback(void *user_data) { const uint64_t *clock = (const uint64_t *)user_data; return *clock; } void set_mono_time_callback(AutoTox *autotox) { ck_assert(autotox != nullptr); Mono_Time *mono_time = autotox->tox->mono_time; autotox->clock = current_time_monotonic(mono_time); mono_time_set_current_time_callback(mono_time, nullptr, nullptr); // set to default first mono_time_set_current_time_callback(mono_time, get_state_clock_callback, &autotox->clock); } void save_autotox(AutoTox *autotox) { ck_assert(autotox != nullptr); fprintf(stderr, "Saving #%u\n", autotox->index); free(autotox->save_state); autotox->save_state = nullptr; autotox->save_size = tox_get_savedata_size(autotox->tox); ck_assert_msg(autotox->save_size > 0, "save is invalid size %u", (unsigned)autotox->save_size); autotox->save_state = (uint8_t *)malloc(autotox->save_size); ck_assert_msg(autotox->save_state != nullptr, "malloc failed"); tox_get_savedata(autotox->tox, autotox->save_state); } void kill_autotox(AutoTox *autotox) { ck_assert(autotox != nullptr); ck_assert(autotox->alive); fprintf(stderr, "Killing #%u\n", autotox->index); autotox->alive = false; tox_kill(autotox->tox); } void reload(AutoTox *autotox) { ck_assert(autotox != nullptr); if (autotox->alive) { kill_autotox(autotox); } fprintf(stderr, "Reloading #%u\n", autotox->index); ck_assert(autotox->save_state != nullptr); struct Tox_Options *const options = tox_options_new(nullptr); ck_assert(options != nullptr); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); tox_options_set_savedata_data(options, autotox->save_state, autotox->save_size); autotox->tox = tox_new_log(options, nullptr, &autotox->index); ck_assert(autotox->tox != nullptr); tox_options_free(options); set_mono_time_callback(autotox); autotox->alive = true; } static void initialise_autotox(struct Tox_Options *options, AutoTox *autotox, uint32_t index, uint32_t state_size, Run_Auto_Options *autotest_opts) { autotox->index = index; Tox_Err_New err = TOX_ERR_NEW_OK; if (index == 0) { struct Tox_Options *default_opts = tox_options_new(nullptr); ck_assert(default_opts != nullptr); if (options == nullptr) { options = default_opts; } // Try a few ports for the TCP relay. for (uint16_t tcp_port = autotest_opts->tcp_port; tcp_port < autotest_opts->tcp_port + 200; ++tcp_port) { tox_options_set_tcp_port(options, tcp_port); autotox->tox = tox_new_log(options, &err, &autotox->index); if (autotox->tox != nullptr) { autotest_opts->tcp_port = tcp_port; break; } ck_assert_msg(err == TOX_ERR_NEW_PORT_ALLOC, "unexpected tox_new error (expected PORT_ALLOC): %d", err); } tox_options_free(default_opts); } else { // No TCP relay enabled for all the other toxes. if (options != nullptr) { tox_options_set_tcp_port(options, 0); } autotox->tox = tox_new_log(options, &err, &autotox->index); } ck_assert_msg(autotox->tox != nullptr, "failed to create tox instance #%u (error = %d)", index, err); set_mono_time_callback(autotox); autotox->alive = true; autotox->save_state = nullptr; if (state_size > 0) { autotox->state = calloc(1, state_size); ck_assert(autotox->state != nullptr); ck_assert_msg(autotox->state != nullptr, "failed to allocate state"); } else { autotox->state = nullptr; } if (autotest_opts->init_autotox != nullptr) { autotest_opts->init_autotox(autotox, index); } } static void autotox_add_friend(AutoTox *autotoxes, uint32_t adding, uint32_t added) { uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(autotoxes[added].tox, public_key); Tox_Err_Friend_Add err; tox_friend_add_norequest(autotoxes[adding].tox, public_key, &err); ck_assert(err == TOX_ERR_FRIEND_ADD_OK); } static void initialise_friend_graph(Graph_Type graph, uint32_t num_toxes, AutoTox *autotoxes) { if (graph == GRAPH_LINEAR) { printf("toxes #%d-#%u each add adjacent toxes as friends\n", 0, num_toxes - 1); for (uint32_t i = 0; i < num_toxes; ++i) { for (uint32_t j = i - 1; j != i + 3; j += 2) { if (j < num_toxes) { autotox_add_friend(autotoxes, i, j); } } } } else if (graph == GRAPH_COMPLETE) { printf("toxes #%d-#%u add each other as friends\n", 0, num_toxes - 1); for (uint32_t i = 0; i < num_toxes; ++i) { for (uint32_t j = 0; j < num_toxes; ++j) { if (i != j) { autotox_add_friend(autotoxes, i, j); } } } } else { ck_abort_msg("Unknown graph type"); } } static void bootstrap_autotoxes(struct Tox_Options *options, uint32_t tox_count, const Run_Auto_Options *autotest_opts, AutoTox *autotoxes) { const bool udp_enabled = options != nullptr ? tox_options_get_udp_enabled(options) : true; printf("bootstrapping all toxes off tox 0\n"); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(autotoxes[0].tox, dht_key); const uint16_t dht_port = tox_self_get_udp_port(autotoxes[0].tox, nullptr); for (uint32_t i = 1; i < tox_count; ++i) { Tox_Err_Bootstrap err; tox_bootstrap(autotoxes[i].tox, "localhost", dht_port, dht_key, &err); ck_assert(err == TOX_ERR_BOOTSTRAP_OK); } if (!udp_enabled) { printf("bootstrapping all toxes to local TCP relay running on port %d\n", autotest_opts->tcp_port); for (uint32_t i = 0; i < tox_count; ++i) { Tox_Err_Bootstrap err; tox_add_tcp_relay(autotoxes[i].tox, "localhost", autotest_opts->tcp_port, dht_key, &err); ck_assert(err == TOX_ERR_BOOTSTRAP_OK); } } } void run_auto_test(struct Tox_Options *options, uint32_t tox_count, void test(AutoTox *autotoxes), uint32_t state_size, Run_Auto_Options *autotest_opts) { printf("initialising %u toxes\n", tox_count); AutoTox *autotoxes = (AutoTox *)calloc(tox_count, sizeof(AutoTox)); ck_assert(autotoxes != nullptr); for (uint32_t i = 0; i < tox_count; ++i) { initialise_autotox(options, &autotoxes[i], i, state_size, autotest_opts); } initialise_friend_graph(autotest_opts->graph, tox_count, autotoxes); bootstrap_autotoxes(options, tox_count, autotest_opts, autotoxes); do { iterate_all_wait(autotoxes, tox_count, ITERATION_INTERVAL); } while (!all_connected(autotoxes, tox_count)); printf("toxes are online\n"); do { iterate_all_wait(autotoxes, tox_count, ITERATION_INTERVAL); } while (!all_friends_connected(autotoxes, tox_count)); printf("tox clients connected\n"); test(autotoxes); for (uint32_t i = 0; i < tox_count; ++i) { tox_kill(autotoxes[i].tox); free(autotoxes[i].state); free(autotoxes[i].save_state); } free(autotoxes); } static const char *tox_log_level_name(Tox_Log_Level level) { switch (level) { case TOX_LOG_LEVEL_TRACE: return "TRACE"; case TOX_LOG_LEVEL_DEBUG: return "DEBUG"; case TOX_LOG_LEVEL_INFO: return "INFO"; case TOX_LOG_LEVEL_WARNING: return "WARNING"; case TOX_LOG_LEVEL_ERROR: return "ERROR"; } return ""; } void print_debug_log(Tox *m, Tox_Log_Level level, const char *file, uint32_t line, const char *func, const char *message, void *user_data) { if (level == TOX_LOG_LEVEL_TRACE) { return; } const uint32_t index = user_data ? *(uint32_t *)user_data : 0; fprintf(stderr, "[#%u] %s %s:%u\t%s:\t%s\n", index, tox_log_level_name(level), file, line, func, message); if (level == TOX_LOG_LEVEL_ERROR && ABORT_ON_LOG_ERROR) { fputs("Aborting test program\n", stderr); abort(); } } Tox *tox_new_log_lan(struct Tox_Options *options, Tox_Err_New *err, void *log_user_data, bool lan_discovery) { struct Tox_Options *log_options = options; if (log_options == nullptr) { log_options = tox_options_new(nullptr); } assert(log_options != nullptr); tox_options_set_local_discovery_enabled(log_options, lan_discovery); // Use a higher start port for non-LAN-discovery tests so it's more likely for the LAN discovery // test to get the default port 33445. const uint16_t start_port = lan_discovery ? 33445 : 33545; tox_options_set_start_port(log_options, start_port); tox_options_set_end_port(log_options, start_port + 2000); tox_options_set_log_callback(log_options, &print_debug_log); tox_options_set_log_user_data(log_options, log_user_data); Tox *tox = tox_new(log_options, err); if (options == nullptr) { tox_options_free(log_options); } return tox; } Tox *tox_new_log(struct Tox_Options *options, Tox_Err_New *err, void *log_user_data) { return tox_new_log_lan(options, err, log_user_data, false); } c-toxcore-0.2.18/auto_tests/auto_test_support.h0000777000175000017500000000317014227324767020705 0ustar robinrobin#ifndef RUN_AUTO_TEST_H #define RUN_AUTO_TEST_H #include // calloc, free #include "check_compat.h" #include "../testing/misc_tools.h" #include "../toxcore/Messenger.h" #include "../toxcore/mono_time.h" typedef struct AutoTox { Tox *tox; uint32_t index; uint64_t clock; size_t save_size; uint8_t *save_state; bool alive; void *state; } AutoTox; bool all_connected(const AutoTox *autotoxes, uint32_t tox_count); bool all_friends_connected(const AutoTox *autotoxes, uint32_t tox_count); void iterate_all_wait(AutoTox *autotoxes, uint32_t tox_count, uint32_t wait); void save_autotox(AutoTox *autotox); void kill_autotox(AutoTox *autotox); void reload(AutoTox *autotox); void set_mono_time_callback(AutoTox *autotox); typedef enum Graph_Type { GRAPH_COMPLETE = 0, GRAPH_LINEAR, } Graph_Type; typedef struct Run_Auto_Options { Graph_Type graph; void (*init_autotox)(AutoTox *autotox, uint32_t n); uint16_t tcp_port; } Run_Auto_Options; Run_Auto_Options default_run_auto_options(void); void run_auto_test(struct Tox_Options *options, uint32_t tox_count, void test(AutoTox *autotoxes), uint32_t state_size, Run_Auto_Options *autotest_opts); void bootstrap_tox_live_network(Tox *tox, bool enable_tcp); void print_debug_log(Tox *m, Tox_Log_Level level, const char *file, uint32_t line, const char *func, const char *message, void *user_data); Tox *tox_new_log(struct Tox_Options *options, Tox_Err_New *err, void *log_user_data); Tox *tox_new_log_lan(struct Tox_Options *options, Tox_Err_New *err, void *log_user_data, bool lan_discovery); #endif c-toxcore-0.2.18/auto_tests/bootstrap_test.c0000777000175000017500000000152514227324767020153 0ustar robinrobin#include #include "../testing/misc_tools.h" #include "check_compat.h" #include "auto_test_support.h" int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Tox *tox_udp = tox_new_log(nullptr, nullptr, nullptr); bootstrap_tox_live_network(tox_udp, false); printf("Waiting for connection"); do { printf("."); fflush(stdout); tox_iterate(tox_udp, nullptr); c_sleep(ITERATION_INTERVAL); } while (tox_self_get_connection_status(tox_udp) == TOX_CONNECTION_NONE); const Tox_Connection status = tox_self_get_connection_status(tox_udp); ck_assert_msg(status == TOX_CONNECTION_UDP, "expected connection status to be UDP, but got %d", status); printf("Connection (UDP): %d\n", tox_self_get_connection_status(tox_udp)); tox_kill(tox_udp); return 0; } c-toxcore-0.2.18/auto_tests/BUILD.bazel0000777000175000017500000000376614227324767016622 0ustar robinrobinload("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") package(features = ["layering_check"]) cc_library( name = "check_compat", testonly = True, hdrs = ["check_compat.h"], ) cc_library( name = "auto_test_support", testonly = True, srcs = ["auto_test_support.c"], hdrs = ["auto_test_support.h"], deps = [ ":check_compat", "//c-toxcore/testing:misc_tools", "//c-toxcore/toxcore:Messenger", "//c-toxcore/toxcore:mono_time", "//c-toxcore/toxcore:tox", ], ) flaky_tests = { "crypto_core_test": True, "lan_discovery_test": True, "save_load_test": True, "tox_many_tcp_test": True, } [cc_test( name = src[:-2], size = "small", srcs = [src], args = ["$(location %s)" % src] + ["$(location //c-toxcore/other/proxy)"], data = glob(["data/*"]) + ["//c-toxcore/other/proxy"], flaky = flaky_tests.get( src[:-2], False, ), deps = [ ":auto_test_support", ":check_compat", "//c-toxcore/testing:misc_tools", "//c-toxcore/toxav", "//c-toxcore/toxcore:TCP_client", "//c-toxcore/toxcore:TCP_common", "//c-toxcore/toxcore:TCP_connection", "//c-toxcore/toxcore:TCP_server", "//c-toxcore/toxcore:announce", "//c-toxcore/toxcore:ccompat", "//c-toxcore/toxcore:crypto_core", "//c-toxcore/toxcore:forwarding", "//c-toxcore/toxcore:friend_connection", "//c-toxcore/toxcore:logger", "//c-toxcore/toxcore:mono_time", "//c-toxcore/toxcore:net_crypto", "//c-toxcore/toxcore:network", "//c-toxcore/toxcore:onion", "//c-toxcore/toxcore:onion_announce", "//c-toxcore/toxcore:onion_client", "//c-toxcore/toxcore:tox", "//c-toxcore/toxcore:tox_dispatch", "//c-toxcore/toxcore:tox_events", "//c-toxcore/toxcore:util", "//c-toxcore/toxencryptsave", "@libsodium", "@libvpx", ], ) for src in glob(["*_test.c"])] c-toxcore-0.2.18/auto_tests/check_compat.h0000777000175000017500000000274114227324767017525 0ustar robinrobin#ifndef C_TOXCORE_AUTO_TESTS_CHECK_COMPAT_H #define C_TOXCORE_AUTO_TESTS_CHECK_COMPAT_H #include "../toxcore/ccompat.h" #include #include #define ck_assert(ok) do { \ if (!(ok)) { \ fprintf(stderr, "%s:%d: failed `%s'\n", __FILE__, __LINE__, #ok); \ abort(); \ } \ } while (0) #define ck_assert_msg(ok, ...) do { \ if (!(ok)) { \ fprintf(stderr, "%s:%d: failed `%s': ", __FILE__, __LINE__, #ok); \ fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, "\n"); \ abort(); \ } \ } while (0) #define ck_abort_msg(...) do { \ fprintf(stderr, "%s:%d: ", __FILE__, __LINE__); \ fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, "\n"); \ abort(); \ } while (0) #endif // C_TOXCORE_AUTO_TESTS_CHECK_COMPAT_H c-toxcore-0.2.18/auto_tests/CMakeLists.txt0000777000175000017500000000423714227324767017476 0ustar robinrobinset(TEST_TIMEOUT_SECONDS "" CACHE STRING "Limit runtime of each test to the number of seconds specified") add_library(auto_test_support auto_test_support.c auto_test_support.h) target_link_modules(auto_test_support toxcore misc_tools) function(auto_test target) if(AUTOTEST AND NOT (MSVC AND ARGV1 STREQUAL "MSVC_DONT_BUILD")) add_executable(auto_${target}_test ${target}_test.c) target_link_modules(auto_${target}_test toxcore misc_tools auto_test_support) if(NOT ARGV1 STREQUAL "DONT_RUN") add_test(NAME ${target} COMMAND ${CROSSCOMPILING_EMULATOR} auto_${target}_test) set_tests_properties(${target} PROPERTIES TIMEOUT "${TEST_TIMEOUT_SECONDS}") # add the source dir as environment variable, so the testdata can be found set_tests_properties(${target} PROPERTIES ENVIRONMENT "LLVM_PROFILE_FILE=${target}.profraw;srcdir=${CMAKE_CURRENT_SOURCE_DIR}") endif() endif() endfunction() auto_test(TCP) auto_test(announce) auto_test(conference) auto_test(conference_double_invite) auto_test(conference_invite_merge) auto_test(conference_peer_nick) auto_test(conference_simple) auto_test(conference_two) auto_test(crypto) #auto_test(dht) # Doesn't work with UNITY_BUILD. auto_test(dht_getnodes_api) auto_test(encryptsave) auto_test(file_transfer) auto_test(file_saving) auto_test(forwarding) auto_test(friend_connection) auto_test(friend_request) auto_test(friend_request_spam) auto_test(invalid_tcp_proxy) auto_test(invalid_udp_proxy) auto_test(lan_discovery) auto_test(lossless_packet) auto_test(lossy_packet) auto_test(network) auto_test(onion) auto_test(overflow_recvq) auto_test(overflow_sendq) auto_test(reconnect) auto_test(save_friend) auto_test(save_load) auto_test(send_message) auto_test(set_name) auto_test(set_status_message) auto_test(tox_dispatch) auto_test(tox_events) auto_test(tox_many) auto_test(tox_many_tcp) auto_test(tox_strncasecmp) auto_test(typing) auto_test(version) auto_test(save_compatibility) if(NON_HERMETIC_TESTS) auto_test(bootstrap) auto_test(tcp_relay) endif() if(BUILD_TOXAV) auto_test(conference_av MSVC_DONT_BUILD) auto_test(toxav_basic) auto_test(toxav_many) endif() if(PROXY_TEST) auto_test(proxy) endif() c-toxcore-0.2.18/auto_tests/conference_av_test.c0000777000175000017500000003571014227324767020736 0ustar robinrobin/* Auto Tests: Conferences AV. */ #include #include #include #include #include "../toxav/toxav.h" #include "check_compat.h" #define NUM_AV_GROUP_TOX 16 #define NUM_AV_DISCONNECT (NUM_AV_GROUP_TOX / 2) #define NUM_AV_DISABLE (NUM_AV_GROUP_TOX / 2) #include "auto_test_support.h" typedef struct State { bool invited_next; uint32_t received_audio_peers[NUM_AV_GROUP_TOX]; uint32_t received_audio_num; } State; static void handle_self_connection_status( Tox *tox, Tox_Connection connection_status, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; if (connection_status != TOX_CONNECTION_NONE) { printf("tox #%u: is now connected\n", autotox->index); } else { printf("tox #%u: is now disconnected\n", autotox->index); } } static void handle_friend_connection_status( Tox *tox, uint32_t friendnumber, Tox_Connection connection_status, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; if (connection_status != TOX_CONNECTION_NONE) { printf("tox #%u: is now connected to friend %u\n", autotox->index, friendnumber); } else { printf("tox #%u: is now disconnected from friend %u\n", autotox->index, friendnumber); } } static void audio_callback(void *tox, uint32_t groupnumber, uint32_t peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, uint32_t sample_rate, void *user_data) { if (samples == 0) { return; } const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; for (uint32_t i = 0; i < state->received_audio_num; ++i) { if (state->received_audio_peers[i] == peernumber) { return; } } ck_assert(state->received_audio_num < NUM_AV_GROUP_TOX); state->received_audio_peers[state->received_audio_num] = peernumber; ++state->received_audio_num; } static void handle_conference_invite( Tox *tox, uint32_t friendnumber, Tox_Conference_Type type, const uint8_t *data, size_t length, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; ck_assert_msg(type == TOX_CONFERENCE_TYPE_AV, "tox #%u: wrong conference type: %d", autotox->index, type); ck_assert_msg(toxav_join_av_groupchat(tox, friendnumber, data, length, audio_callback, user_data) == 0, "tox #%u: failed to join group", autotox->index); } static void handle_conference_connected( Tox *tox, uint32_t conference_number, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; if (state->invited_next || tox_self_get_friend_list_size(tox) <= 1) { return; } Tox_Err_Conference_Invite err; tox_conference_invite(tox, 1, 0, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox #%u failed to invite next friend: err = %d", autotox->index, err); printf("tox #%u: invited next friend\n", autotox->index); state->invited_next = true; } static bool toxes_are_disconnected_from_group(uint32_t tox_count, AutoTox *autotoxes, bool *disconnected) { uint32_t num_disconnected = 0; for (uint32_t i = 0; i < tox_count; ++i) { num_disconnected += disconnected[i]; } for (uint32_t i = 0; i < tox_count; ++i) { if (disconnected[i]) { continue; } if (tox_conference_peer_count(autotoxes[i].tox, 0, nullptr) > tox_count - num_disconnected) { return false; } } return true; } static void disconnect_toxes(uint32_t tox_count, AutoTox *autotoxes, const bool *disconnect, const bool *exclude) { /* Fake a network outage for a set of peers D by iterating only the other * peers D' until the connections time out according to D', then iterating * only D until the connections time out according to D. */ VLA(bool, disconnect_now, tox_count); bool invert = false; do { for (uint32_t i = 0; i < tox_count; ++i) { disconnect_now[i] = exclude[i] || (invert ^ disconnect[i]); } do { for (uint32_t i = 0; i < tox_count; ++i) { if (!disconnect_now[i]) { tox_iterate(autotoxes[i].tox, &autotoxes[i]); autotoxes[i].clock += 1000; } } c_sleep(20); } while (!toxes_are_disconnected_from_group(tox_count, autotoxes, disconnect_now)); invert = !invert; } while (invert); } static bool all_connected_to_group(uint32_t tox_count, AutoTox *autotoxes) { for (uint32_t i = 0; i < tox_count; ++i) { if (tox_conference_peer_count(autotoxes[i].tox, 0, nullptr) < tox_count) { return false; } } return true; } /** * returns a random index at which a list of booleans is false * (some such index is required to exist) */ static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t length) { uint32_t index; do { index = random_u32(rng) % length; } while (list[index]); return index; } static bool all_got_audio(AutoTox *autotoxes, const bool *disabled) { uint32_t num_disabled = 0; for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) { num_disabled += disabled[i]; } for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) { State *state = (State *)autotoxes[i].state; if (disabled[i] ^ (state->received_audio_num != NUM_AV_GROUP_TOX - num_disabled - 1)) { return false; } } return true; } static void reset_received_audio(AutoTox *autotoxes) { for (uint32_t j = 0; j < NUM_AV_GROUP_TOX; ++j) { ((State *)autotoxes[j].state)->received_audio_num = 0; } } #define GROUP_AV_TEST_SAMPLES 960 /* must have * GROUP_AV_AUDIO_ITERATIONS - NUM_AV_GROUP_TOX >= 2^n >= GROUP_JBUF_SIZE * for some n, to give messages time to be relayed and to let the jitter * buffers fill up. */ #define GROUP_AV_AUDIO_ITERATIONS (8 + NUM_AV_GROUP_TOX) static bool test_audio(AutoTox *autotoxes, const bool *disabled, bool quiet) { if (!quiet) { printf("testing sending and receiving audio\n"); } const int16_t PCM[GROUP_AV_TEST_SAMPLES] = {0}; reset_received_audio(autotoxes); for (uint32_t n = 0; n < GROUP_AV_AUDIO_ITERATIONS; ++n) { for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) { if (disabled[i]) { continue; } if (toxav_group_send_audio(autotoxes[i].tox, 0, PCM, GROUP_AV_TEST_SAMPLES, 1, 48000) != 0) { if (!quiet) { ck_abort_msg("#%u failed to send audio", autotoxes[i].index); } return false; } } iterate_all_wait(autotoxes, NUM_AV_GROUP_TOX, ITERATION_INTERVAL); if (all_got_audio(autotoxes, disabled)) { return true; } } if (!quiet) { ck_abort_msg("group failed to receive audio"); } return false; } static void test_eventual_audio(AutoTox *autotoxes, const bool *disabled, uint64_t timeout) { uint64_t start = autotoxes[0].clock; while (autotoxes[0].clock < start + timeout) { if (test_audio(autotoxes, disabled, true) && test_audio(autotoxes, disabled, true)) { printf("audio test successful after %d seconds\n", (int)((autotoxes[0].clock - start) / 1000)); return; } } printf("audio seems not to be getting through: testing again with errors.\n"); test_audio(autotoxes, disabled, false); } static void do_audio(AutoTox *autotoxes, uint32_t iterations) { const int16_t PCM[GROUP_AV_TEST_SAMPLES] = {0}; printf("running audio for %u iterations\n", iterations); for (uint32_t f = 0; f < iterations; ++f) { 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, "#%u failed to send audio", autotoxes[i].index); iterate_all_wait(autotoxes, NUM_AV_GROUP_TOX, ITERATION_INTERVAL); } } } // should agree with value in groupav.c #define GROUP_JBUF_DEAD_SECONDS 4 #define JITTER_SETTLE_TIME (GROUP_JBUF_DEAD_SECONDS*1000 + NUM_AV_GROUP_TOX*ITERATION_INTERVAL*(GROUP_AV_AUDIO_ITERATIONS+1)) static void run_conference_tests(AutoTox *autotoxes) { const Random *rng = system_random(); ck_assert(rng != nullptr); bool disabled[NUM_AV_GROUP_TOX] = {0}; test_audio(autotoxes, disabled, false); /* have everyone send audio for a bit so we can test that the audio * sequnums dropping to 0 on restart isn't a problem */ do_audio(autotoxes, 20); printf("letting random toxes timeout\n"); bool disconnected[NUM_AV_GROUP_TOX] = {0}; bool restarting[NUM_AV_GROUP_TOX] = {0}; ck_assert(NUM_AV_DISCONNECT < NUM_AV_GROUP_TOX); for (uint32_t i = 0; i < NUM_AV_DISCONNECT; ++i) { uint32_t disconnect = random_false_index(rng, disconnected, NUM_AV_GROUP_TOX); disconnected[disconnect] = true; if (i < NUM_AV_DISCONNECT / 2) { restarting[disconnect] = true; printf("Restarting #%u\n", autotoxes[disconnect].index); } else { printf("Disconnecting #%u\n", autotoxes[disconnect].index); } } for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) { if (restarting[i]) { save_autotox(&autotoxes[i]); kill_autotox(&autotoxes[i]); } } disconnect_toxes(NUM_AV_GROUP_TOX, autotoxes, disconnected, restarting); for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) { if (restarting[i]) { reload(&autotoxes[i]); } } printf("reconnecting toxes\n"); do { iterate_all_wait(autotoxes, NUM_AV_GROUP_TOX, ITERATION_INTERVAL); } while (!all_connected_to_group(NUM_AV_GROUP_TOX, autotoxes)); for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) { if (restarting[i]) { ck_assert_msg(!toxav_groupchat_av_enabled(autotoxes[i].tox, 0), "#%u restarted but av enabled", autotoxes[i].index); ck_assert_msg(toxav_groupchat_enable_av(autotoxes[i].tox, 0, audio_callback, &autotoxes[i]) == 0, "#%u failed to re-enable av", autotoxes[i].index); ck_assert_msg(toxav_groupchat_av_enabled(autotoxes[i].tox, 0), "#%u av not enabled even after enabling", autotoxes[i].index); } } printf("testing audio\n"); /* Allow time for the jitter buffers to reset and for the group to become * connected enough for lossy messages to get through * (all_connected_to_group() only checks lossless connectivity, which is a * looser condition). */ test_eventual_audio(autotoxes, disabled, JITTER_SETTLE_TIME + NUM_AV_GROUP_TOX * 1000); printf("testing disabling av\n"); ck_assert(NUM_AV_DISABLE < NUM_AV_GROUP_TOX); for (uint32_t i = 0; i < NUM_AV_DISABLE; ++i) { uint32_t disable = random_false_index(rng, disabled, NUM_AV_GROUP_TOX); disabled[disable] = true; printf("Disabling #%u\n", autotoxes[disable].index); ck_assert_msg(toxav_groupchat_enable_av(autotoxes[disable].tox, 0, audio_callback, &autotoxes[disable]) != 0, "#%u could enable already enabled av!", autotoxes[i].index); ck_assert_msg(toxav_groupchat_disable_av(autotoxes[disable].tox, 0) == 0, "#%u failed to disable av", autotoxes[i].index); } // Run test without error to clear out messages from now-disabled peers. test_audio(autotoxes, disabled, true); printf("testing audio with some peers having disabled their av\n"); test_audio(autotoxes, disabled, false); for (uint32_t i = 0; i < NUM_AV_DISABLE; ++i) { if (!disabled[i]) { continue; } disabled[i] = false; ck_assert_msg(toxav_groupchat_disable_av(autotoxes[i].tox, 0) != 0, "#%u could disable already disabled av!", autotoxes[i].index); ck_assert_msg(!toxav_groupchat_av_enabled(autotoxes[i].tox, 0), "#%u av enabled after disabling", autotoxes[i].index); ck_assert_msg(toxav_groupchat_enable_av(autotoxes[i].tox, 0, audio_callback, &autotoxes[i]) == 0, "#%u failed to re-enable av", autotoxes[i].index); } printf("testing audio after re-enabling all av\n"); test_eventual_audio(autotoxes, disabled, JITTER_SETTLE_TIME); } static void test_groupav(AutoTox *autotoxes) { const time_t test_start_time = time(nullptr); for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) { tox_callback_self_connection_status(autotoxes[i].tox, &handle_self_connection_status); tox_callback_friend_connection_status(autotoxes[i].tox, &handle_friend_connection_status); tox_callback_conference_invite(autotoxes[i].tox, &handle_conference_invite); tox_callback_conference_connected(autotoxes[i].tox, &handle_conference_connected); } ck_assert_msg(toxav_add_av_groupchat(autotoxes[0].tox, audio_callback, &autotoxes[0]) != UINT32_MAX, "failed to create group"); printf("tox #%u: inviting its first friend\n", autotoxes[0].index); ck_assert_msg(tox_conference_invite(autotoxes[0].tox, 0, 0, nullptr) != 0, "failed to invite friend"); ((State *)autotoxes[0].state)->invited_next = true; printf("waiting for invitations to be made\n"); uint32_t invited_count = 0; do { iterate_all_wait(autotoxes, NUM_AV_GROUP_TOX, ITERATION_INTERVAL); invited_count = 0; for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) { invited_count += ((State *)autotoxes[i].state)->invited_next; } } while (invited_count != NUM_AV_GROUP_TOX - 1); uint64_t pregroup_clock = autotoxes[0].clock; printf("waiting for all toxes to be in the group\n"); uint32_t fully_connected_count = 0; do { fully_connected_count = 0; iterate_all_wait(autotoxes, NUM_AV_GROUP_TOX, ITERATION_INTERVAL); for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) { Tox_Err_Conference_Peer_Query err; uint32_t peer_count = tox_conference_peer_count(autotoxes[i].tox, 0, &err); if (err != TOX_ERR_CONFERENCE_PEER_QUERY_OK) { peer_count = 0; } fully_connected_count += peer_count == NUM_AV_GROUP_TOX; } } while (fully_connected_count != NUM_AV_GROUP_TOX); printf("group connected, took %d seconds\n", (int)((autotoxes[0].clock - pregroup_clock) / 1000)); run_conference_tests(autotoxes); printf("test_many_group succeeded, took %d seconds\n", (int)(time(nullptr) - test_start_time)); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; run_auto_test(nullptr, NUM_AV_GROUP_TOX, test_groupav, sizeof(State), &options); return 0; } c-toxcore-0.2.18/auto_tests/conference_double_invite_test.c0000777000175000017500000000577514227324767023170 0ustar robinrobin#include #include typedef struct State { bool self_online; bool friend_online; bool joined; uint32_t conference; } State; #include "auto_test_support.h" static void handle_conference_invite( Tox *tox, uint32_t friend_number, Tox_Conference_Type type, const uint8_t *cookie, size_t length, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n", autotox->index, friend_number, type, (unsigned)length); fprintf(stderr, "tox%u joining conference\n", autotox->index); ck_assert_msg(!state->joined, "invitation callback generated for already joined conference"); if (friend_number != -1) { Tox_Err_Conference_Join err; state->conference = tox_conference_join(tox, friend_number, cookie, length, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "attempting to join the conference returned with an error: %d", err); fprintf(stderr, "tox%u joined conference %u\n", autotox->index, state->conference); state->joined = true; } } static void conference_double_invite_test(AutoTox *autotoxes) { // Conference callbacks. tox_callback_conference_invite(autotoxes[0].tox, handle_conference_invite); tox_callback_conference_invite(autotoxes[1].tox, handle_conference_invite); State *state[2]; state[0] = (State *)autotoxes[0].state; state[1] = (State *)autotoxes[1].state; { // Create new conference, tox0 is the founder. Tox_Err_Conference_New err; state[0]->conference = tox_conference_new(autotoxes[0].tox, &err); state[0]->joined = true; ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK, "attempting to create a new conference returned with an error: %d", err); fprintf(stderr, "Created conference: index=%u\n", state[0]->conference); } { // Invite friend. Tox_Err_Conference_Invite err; tox_conference_invite(autotoxes[0].tox, 0, state[0]->conference, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "attempting to invite a friend returned with an error: %d", err); fprintf(stderr, "tox0 invited tox1\n"); } fprintf(stderr, "Waiting for invitation to arrive\n"); do { iterate_all_wait(autotoxes, 2, ITERATION_INTERVAL); } while (!state[0]->joined || !state[1]->joined); fprintf(stderr, "Invitations accepted\n"); fprintf(stderr, "Sending second invitation; should be ignored\n"); tox_conference_invite(autotoxes[0].tox, 0, state[0]->conference, nullptr); iterate_all_wait(autotoxes, 2, ITERATION_INTERVAL); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; run_auto_test(nullptr, 2, conference_double_invite_test, sizeof(State), &options); return 0; } c-toxcore-0.2.18/auto_tests/conference_invite_merge_test.c0000777000175000017500000001312514227324767023001 0ustar robinrobin#include #include #include typedef struct State { bool connected; uint32_t conference; } State; #define NUM_INVITE_MERGE_TOX 5 #include "auto_test_support.h" static void handle_conference_invite( Tox *tox, uint32_t friend_number, Tox_Conference_Type type, const uint8_t *cookie, size_t length, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; if (friend_number != -1) { Tox_Err_Conference_Join err; state->conference = tox_conference_join(tox, friend_number, cookie, length, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "attempting to join the conference returned with an error: %d", err); fprintf(stderr, "#%u accepted invite to conference %u\n", autotox->index, state->conference); } } static void handle_conference_connected( Tox *tox, uint32_t conference_number, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; fprintf(stderr, "#%u connected to conference %u\n", autotox->index, state->conference); state->connected = true; } static void wait_connected(AutoTox *autotoxes, AutoTox *autotox, uint32_t friendnumber) { do { iterate_all_wait(autotoxes, NUM_INVITE_MERGE_TOX, ITERATION_INTERVAL); } while (tox_friend_get_connection_status(autotox->tox, friendnumber, nullptr) == TOX_CONNECTION_NONE); } static void do_invite(AutoTox *autotoxes, AutoTox *inviter, AutoTox *invitee, uint32_t friendnum) { fprintf(stderr, "#%u inviting #%u\n", inviter->index, invitee->index); Tox_Err_Conference_Invite err; tox_conference_invite(inviter->tox, friendnum, ((State *)inviter->state)->conference, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "#%u attempting to invite #%u (friendnumber %u) returned with an error: %d", inviter->index, invitee->index, friendnum, err); do { iterate_all_wait(autotoxes, NUM_INVITE_MERGE_TOX, ITERATION_INTERVAL); } while (!((State *)invitee->state)->connected); } static bool group_complete(AutoTox *autotoxes) { int c = -1, size = 0; for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) { if (!autotoxes[i].alive) { continue; } const int ct = tox_conference_peer_count(autotoxes[i].tox, ((State *)autotoxes[i].state)->conference, nullptr); if (c == -1) { c = ct; } else if (c != ct) { return false; } ++size; } return (c == size); } static void wait_group_complete(AutoTox *autotoxes) { do { iterate_all_wait(autotoxes, NUM_INVITE_MERGE_TOX, ITERATION_INTERVAL); } while (!group_complete(autotoxes)); } static void conference_invite_merge_test(AutoTox *autotoxes) { // Test that an explicit invite between peers in different connected // components will cause a split group to merge for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) { tox_callback_conference_invite(autotoxes[i].tox, &handle_conference_invite); tox_callback_conference_connected(autotoxes[i].tox, &handle_conference_connected); } State *state2 = (State *)autotoxes[2].state; { // Create new conference, tox 2 is the founder. Tox_Err_Conference_New err; state2->conference = tox_conference_new(autotoxes[2].tox, &err); state2->connected = true; ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK, "attempting to create a new conference returned with an error: %d", err); fprintf(stderr, "Created conference: index=%u\n", state2->conference); } save_autotox(&autotoxes[2]); do_invite(autotoxes, &autotoxes[2], &autotoxes[1], 0); do_invite(autotoxes, &autotoxes[1], &autotoxes[0], 0); save_autotox(&autotoxes[1]); kill_autotox(&autotoxes[1]); do { iterate_all_wait(autotoxes, NUM_INVITE_MERGE_TOX, ITERATION_INTERVAL); } while (tox_conference_peer_count(autotoxes[2].tox, state2->conference, nullptr) != 1); do_invite(autotoxes, &autotoxes[2], &autotoxes[3], 1); do_invite(autotoxes, &autotoxes[3], &autotoxes[4], 1); kill_autotox(&autotoxes[2]); reload(&autotoxes[1]); uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(autotoxes[1].tox, public_key); tox_friend_add_norequest(autotoxes[3].tox, public_key, nullptr); tox_self_get_public_key(autotoxes[3].tox, public_key); tox_friend_add_norequest(autotoxes[1].tox, public_key, nullptr); wait_connected(autotoxes, &autotoxes[1], 2); do_invite(autotoxes, &autotoxes[1], &autotoxes[3], 2); fprintf(stderr, "Waiting for group to merge\n"); wait_group_complete(autotoxes); fprintf(stderr, "Group merged\n"); reload(&autotoxes[2]); wait_connected(autotoxes, &autotoxes[2], 0); do_invite(autotoxes, &autotoxes[2], &autotoxes[1], 0); fprintf(stderr, "Waiting for #2 to rejoin\n"); wait_group_complete(autotoxes); kill_autotox(&autotoxes[2]); wait_group_complete(autotoxes); reload(&autotoxes[2]); wait_connected(autotoxes, &autotoxes[2], 0); wait_connected(autotoxes, &autotoxes[1], 1); do_invite(autotoxes, &autotoxes[1], &autotoxes[2], 1); fprintf(stderr, "Waiting for #2 to rejoin\n"); wait_group_complete(autotoxes); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; run_auto_test(nullptr, NUM_INVITE_MERGE_TOX, conference_invite_merge_test, sizeof(State), &options); return 0; } c-toxcore-0.2.18/auto_tests/conference_peer_nick_test.c0000777000175000017500000001251714227324767022267 0ustar robinrobin#include #include typedef struct State { bool self_online; bool friend_online; bool friend_in_group; bool joined; uint32_t conference; } State; #include "auto_test_support.h" static void handle_conference_invite( Tox *tox, uint32_t friend_number, Tox_Conference_Type type, const uint8_t *cookie, size_t length, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n", autotox->index, friend_number, type, (unsigned)length); fprintf(stderr, "tox%u joining conference\n", autotox->index); Tox_Err_Conference_Join err; state->conference = tox_conference_join(tox, friend_number, cookie, length, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "attempting to join the conference returned with an error: %d", err); fprintf(stderr, "tox%u joined conference %u\n", autotox->index, state->conference); state->joined = true; } static void handle_peer_list_changed(Tox *tox, uint32_t conference_number, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; fprintf(stderr, "handle_peer_list_changed(#%u, %u, _)\n", autotox->index, conference_number); Tox_Err_Conference_Peer_Query err; uint32_t const count = tox_conference_peer_count(tox, conference_number, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_PEER_QUERY_OK, "failed to get conference peer count: err = %d", err); printf("tox%u has %u peers\n", autotox->index, count); state->friend_in_group = count == 2; } static void rebuild_peer_list(Tox *tox) { for (uint32_t conference_number = 0; conference_number < tox_conference_get_chatlist_size(tox); ++conference_number) { Tox_Err_Conference_Peer_Query err; uint32_t const count = tox_conference_peer_count(tox, conference_number, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_PEER_QUERY_OK, "failed to get conference peer count for conference %u: err = %d", conference_number, err); for (uint32_t peer_number = 0; peer_number < count; peer_number++) { size_t size = tox_conference_peer_get_name_size(tox, conference_number, peer_number, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_PEER_QUERY_OK, "failed to get conference peer %u's name size (conference = %u): err = %d", peer_number, conference_number, err); uint8_t *const name = (uint8_t *)malloc(size); ck_assert(name != nullptr); tox_conference_peer_get_name(tox, conference_number, peer_number, name, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_PEER_QUERY_OK, "failed to get conference peer %u's name (conference = %u): err = %d", peer_number, conference_number, err); free(name); } } } static void conference_peer_nick_test(AutoTox *autotoxes) { // Conference callbacks. tox_callback_conference_invite(autotoxes[0].tox, handle_conference_invite); tox_callback_conference_invite(autotoxes[1].tox, handle_conference_invite); tox_callback_conference_peer_list_changed(autotoxes[0].tox, handle_peer_list_changed); tox_callback_conference_peer_list_changed(autotoxes[1].tox, handle_peer_list_changed); // Set the names of the toxes. tox_self_set_name(autotoxes[0].tox, (const uint8_t *)"test-tox-0", 10, nullptr); tox_self_set_name(autotoxes[1].tox, (const uint8_t *)"test-tox-1", 10, nullptr); State *state[2]; state[0] = (State *)autotoxes[0].state; state[1] = (State *)autotoxes[1].state; { // Create new conference, tox0 is the founder. Tox_Err_Conference_New err; state[0]->conference = tox_conference_new(autotoxes[0].tox, &err); state[0]->joined = true; ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK, "attempting to create a new conference returned with an error: %d", err); fprintf(stderr, "Created conference: index=%u\n", state[0]->conference); } { // Invite friend. Tox_Err_Conference_Invite err; tox_conference_invite(autotoxes[0].tox, 0, state[0]->conference, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "attempting to invite a friend returned with an error: %d", err); fprintf(stderr, "tox0 invited tox1\n"); } fprintf(stderr, "Waiting for invitation to arrive and peers to be in the group\n"); do { iterate_all_wait(autotoxes, 2, ITERATION_INTERVAL); } while (!state[0]->joined || !state[1]->joined || !state[0]->friend_in_group || !state[1]->friend_in_group); fprintf(stderr, "Running tox0, but not tox1, waiting for tox1 to drop out\n"); do { iterate_all_wait(autotoxes, 1, 1000); // Rebuild peer list after every iteration. rebuild_peer_list(autotoxes[0].tox); } while (state[0]->friend_in_group); fprintf(stderr, "Invitations accepted\n"); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; run_auto_test(nullptr, 2, conference_peer_nick_test, sizeof(State), &options); return 0; } c-toxcore-0.2.18/auto_tests/conference_simple_test.c0000777000175000017500000002152414227324767021617 0ustar robinrobin#include #include #include "../testing/misc_tools.h" #include "../toxcore/tox.h" #include "auto_test_support.h" #include "check_compat.h" typedef struct State { uint32_t id; bool self_online; bool friend_online; bool invited_next; bool joined; uint32_t conference; bool received; uint32_t peers; } State; static void handle_self_connection_status(Tox *tox, Tox_Connection connection_status, void *user_data) { State *state = (State *)user_data; fprintf(stderr, "self_connection_status(#%u, %d, _)\n", state->id, connection_status); state->self_online = connection_status != TOX_CONNECTION_NONE; } static void handle_friend_connection_status(Tox *tox, uint32_t friend_number, Tox_Connection connection_status, void *user_data) { State *state = (State *)user_data; fprintf(stderr, "handle_friend_connection_status(#%u, %u, %d, _)\n", state->id, friend_number, connection_status); state->friend_online = connection_status != TOX_CONNECTION_NONE; } static void handle_conference_invite(Tox *tox, uint32_t friend_number, Tox_Conference_Type type, const uint8_t *cookie, size_t length, void *user_data) { State *state = (State *)user_data; fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n", state->id, friend_number, type, (unsigned)length); fprintf(stderr, "tox%u joining conference\n", state->id); { Tox_Err_Conference_Join err; state->conference = tox_conference_join(tox, friend_number, cookie, length, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "failed to join a conference: err = %d", err); fprintf(stderr, "tox%u Joined conference %u\n", state->id, state->conference); state->joined = true; } } static void handle_conference_message(Tox *tox, uint32_t conference_number, uint32_t peer_number, Tox_Message_Type type, const uint8_t *message, size_t length, void *user_data) { State *state = (State *)user_data; fprintf(stderr, "handle_conference_message(#%u, %u, %u, %d, uint8_t[%u], _)\n", state->id, conference_number, peer_number, type, (unsigned)length); fprintf(stderr, "tox%u got message: %s\n", state->id, (const char *)message); state->received = true; } static void handle_conference_peer_list_changed(Tox *tox, uint32_t conference_number, void *user_data) { State *state = (State *)user_data; fprintf(stderr, "handle_conference_peer_list_changed(#%u, %u, _)\n", state->id, conference_number); Tox_Err_Conference_Peer_Query err; uint32_t count = tox_conference_peer_count(tox, conference_number, &err); if (err != TOX_ERR_CONFERENCE_PEER_QUERY_OK) { fprintf(stderr, "ERROR: %d\n", err); exit(EXIT_FAILURE); } fprintf(stderr, "tox%u has %u peers online\n", state->id, count); state->peers = count; } static void handle_conference_connected(Tox *tox, uint32_t conference_number, void *user_data) { State *state = (State *)user_data; // We're tox2, so now we invite tox3. if (state->id == 2 && !state->invited_next) { Tox_Err_Conference_Invite err; tox_conference_invite(tox, 1, state->conference, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox2 failed to invite tox3: err = %d", err); state->invited_next = true; fprintf(stderr, "tox2 invited tox3\n"); } } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); State state1 = {1}; State state2 = {2}; State state3 = {3}; // Create toxes. Tox *tox1 = tox_new_log(nullptr, nullptr, &state1.id); Tox *tox2 = tox_new_log(nullptr, nullptr, &state2.id); Tox *tox3 = tox_new_log(nullptr, nullptr, &state3.id); // tox1 <-> tox2, tox2 <-> tox3 uint8_t key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(tox2, key); tox_friend_add_norequest(tox1, key, nullptr); // tox1 -> tox2 tox_self_get_public_key(tox1, key); tox_friend_add_norequest(tox2, key, nullptr); // tox2 -> tox1 tox_self_get_public_key(tox3, key); tox_friend_add_norequest(tox2, key, nullptr); // tox2 -> tox3 tox_self_get_public_key(tox2, key); tox_friend_add_norequest(tox3, key, nullptr); // tox3 -> tox2 printf("bootstrapping tox2 and tox3 off tox1\n"); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(tox1, dht_key); const uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr); tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr); tox_bootstrap(tox3, "localhost", dht_port, dht_key, nullptr); // Connection callbacks. tox_callback_self_connection_status(tox1, handle_self_connection_status); tox_callback_self_connection_status(tox2, handle_self_connection_status); tox_callback_self_connection_status(tox3, handle_self_connection_status); tox_callback_friend_connection_status(tox1, handle_friend_connection_status); tox_callback_friend_connection_status(tox2, handle_friend_connection_status); tox_callback_friend_connection_status(tox3, handle_friend_connection_status); // Conference callbacks. tox_callback_conference_invite(tox1, handle_conference_invite); tox_callback_conference_invite(tox2, handle_conference_invite); tox_callback_conference_invite(tox3, handle_conference_invite); tox_callback_conference_connected(tox1, handle_conference_connected); tox_callback_conference_connected(tox2, handle_conference_connected); tox_callback_conference_connected(tox3, handle_conference_connected); tox_callback_conference_message(tox1, handle_conference_message); tox_callback_conference_message(tox2, handle_conference_message); tox_callback_conference_message(tox3, handle_conference_message); tox_callback_conference_peer_list_changed(tox1, handle_conference_peer_list_changed); tox_callback_conference_peer_list_changed(tox2, handle_conference_peer_list_changed); tox_callback_conference_peer_list_changed(tox3, handle_conference_peer_list_changed); // Wait for self connection. fprintf(stderr, "Waiting for toxes to come online\n"); do { tox_iterate(tox1, &state1); tox_iterate(tox2, &state2); tox_iterate(tox3, &state3); c_sleep(100); } while (!state1.self_online || !state2.self_online || !state3.self_online); fprintf(stderr, "Toxes are online\n"); // Wait for friend connection. fprintf(stderr, "Waiting for friends to connect\n"); do { tox_iterate(tox1, &state1); tox_iterate(tox2, &state2); tox_iterate(tox3, &state3); c_sleep(100); } while (!state1.friend_online || !state2.friend_online || !state3.friend_online); fprintf(stderr, "Friends are connected\n"); { // Create new conference, tox1 is the founder. Tox_Err_Conference_New err; state1.conference = tox_conference_new(tox1, &err); state1.joined = true; ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK, "failed to create a conference: err = %d", err); fprintf(stderr, "Created conference: id = %u\n", state1.conference); } { // Invite friend. Tox_Err_Conference_Invite err; tox_conference_invite(tox1, 0, state1.conference, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "failed to invite a friend: err = %d", err); state1.invited_next = true; fprintf(stderr, "tox1 invited tox2\n"); } fprintf(stderr, "Waiting for invitation to arrive\n"); do { tox_iterate(tox1, &state1); tox_iterate(tox2, &state2); tox_iterate(tox3, &state3); c_sleep(100); } while (!state1.joined || !state2.joined || !state3.joined); fprintf(stderr, "Invitations accepted\n"); fprintf(stderr, "Waiting for peers to come online\n"); do { tox_iterate(tox1, &state1); tox_iterate(tox2, &state2); tox_iterate(tox3, &state3); c_sleep(100); } while (state1.peers == 0 || state2.peers == 0 || state3.peers == 0); fprintf(stderr, "All peers are online\n"); { fprintf(stderr, "tox1 sends a message to the group: \"hello!\"\n"); Tox_Err_Conference_Send_Message err; tox_conference_send_message(tox1, state1.conference, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)"hello!", 7, &err); if (err != TOX_ERR_CONFERENCE_SEND_MESSAGE_OK) { fprintf(stderr, "ERROR: %d\n", err); exit(EXIT_FAILURE); } } fprintf(stderr, "Waiting for messages to arrive\n"); do { tox_iterate(tox1, &state1); tox_iterate(tox2, &state2); tox_iterate(tox3, &state3); c_sleep(100); } while (!state2.received || !state3.received); fprintf(stderr, "Messages received. Test complete.\n"); tox_kill(tox3); tox_kill(tox2); tox_kill(tox1); return 0; } c-toxcore-0.2.18/auto_tests/conference_test.c0000777000175000017500000003614714227324767020255 0ustar robinrobin/* Auto Tests: Conferences. */ #include #include #include #include #include "../toxcore/util.h" #include "check_compat.h" #define NUM_GROUP_TOX 16 #define NUM_DISCONNECT 8 #define GROUP_MESSAGE "Install Gentoo" #define NAMELEN 9 #define NAME_FORMAT_STR "Tox #%4u" #define NEW_NAME_FORMAT_STR "New #%4u" typedef struct State { bool invited_next; } State; #include "auto_test_support.h" static void handle_self_connection_status( Tox *tox, Tox_Connection connection_status, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; if (connection_status != TOX_CONNECTION_NONE) { printf("tox #%u: is now connected\n", autotox->index); } else { printf("tox #%u: is now disconnected\n", autotox->index); } } static void handle_friend_connection_status( Tox *tox, uint32_t friendnumber, Tox_Connection connection_status, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; if (connection_status != TOX_CONNECTION_NONE) { printf("tox #%u: is now connected to friend %u\n", autotox->index, friendnumber); } else { printf("tox #%u: is now disconnected from friend %u\n", autotox->index, friendnumber); } } static void handle_conference_invite( Tox *tox, uint32_t friendnumber, Tox_Conference_Type type, const uint8_t *data, size_t length, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; ck_assert_msg(type == TOX_CONFERENCE_TYPE_TEXT, "tox #%u: wrong conference type: %d", autotox->index, type); Tox_Err_Conference_Join err; uint32_t g_num = tox_conference_join(tox, friendnumber, data, length, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "tox #%u: error joining group: %d", autotox->index, err); ck_assert_msg(g_num == 0, "tox #%u: group number was not 0", autotox->index); // Try joining again. We should only be allowed to join once. tox_conference_join(tox, friendnumber, data, length, &err); ck_assert_msg(err != TOX_ERR_CONFERENCE_JOIN_OK, "tox #%u: joining groupchat twice should be impossible.", autotox->index); } static void handle_conference_connected( Tox *tox, uint32_t conference_number, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; if (state->invited_next || tox_self_get_friend_list_size(tox) <= 1) { return; } Tox_Err_Conference_Invite err; tox_conference_invite(tox, 1, 0, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox #%u failed to invite next friend: err = %d", autotox->index, err); printf("tox #%u: invited next friend\n", autotox->index); state->invited_next = true; } static uint32_t num_recv; static void handle_conference_message( Tox *tox, uint32_t groupnumber, uint32_t peernumber, Tox_Message_Type type, const uint8_t *message, size_t length, void *user_data) { if (length == (sizeof(GROUP_MESSAGE) - 1) && memcmp(message, GROUP_MESSAGE, sizeof(GROUP_MESSAGE) - 1) == 0) { ++num_recv; } } static bool toxes_are_disconnected_from_group(uint32_t tox_count, AutoTox *autotoxes, bool *disconnected) { uint32_t num_disconnected = 0; for (uint32_t i = 0; i < tox_count; ++i) { num_disconnected += disconnected[i]; } for (uint32_t i = 0; i < tox_count; i++) { if (disconnected[i]) { continue; } if (tox_conference_peer_count(autotoxes[i].tox, 0, nullptr) > tox_count - num_disconnected) { return false; } } return true; } static void disconnect_toxes(uint32_t tox_count, AutoTox *autotoxes, const bool *disconnect, const bool *exclude) { /* Fake a network outage for a set of peers D by iterating only the other * peers D' until the connections time out according to D', then iterating * only D until the connections time out according to D. */ VLA(bool, disconnect_now, tox_count); bool invert = false; do { for (uint32_t i = 0; i < tox_count; ++i) { disconnect_now[i] = exclude[i] || (invert ^ disconnect[i]); } do { for (uint32_t i = 0; i < tox_count; ++i) { if (!disconnect_now[i]) { tox_iterate(autotoxes[i].tox, &autotoxes[i]); autotoxes[i].clock += 1000; } } c_sleep(20); } while (!toxes_are_disconnected_from_group(tox_count, autotoxes, disconnect_now)); invert = !invert; } while (invert); } static bool all_connected_to_group(uint32_t tox_count, AutoTox *autotoxes) { for (uint32_t i = 0; i < tox_count; i++) { if (tox_conference_peer_count(autotoxes[i].tox, 0, nullptr) < tox_count) { return false; } } return true; } static bool names_propagated(uint32_t tox_count, AutoTox *autotoxes) { for (uint32_t i = 0; i < tox_count; ++i) { for (uint32_t j = 0; j < tox_count; ++j) { const size_t len = tox_conference_peer_get_name_size(autotoxes[i].tox, 0, j, nullptr); if (len != NAMELEN) { return false; } } } return true; } /** * returns a random index at which a list of booleans is false * (some such index is required to exist) */ static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t length) { uint32_t index; do { index = random_u32(rng) % length; } while (list[index]); return index; } static void run_conference_tests(AutoTox *autotoxes) { const Random *rng = system_random(); ck_assert(rng != nullptr); /* disabling name change propagation check for now, as it occasionally * fails due to disconnections too short to trigger freezing */ const bool check_name_change_propagation = false; /* each peer should freeze at least its two friends, but freezing more * should not be necessary */ const uint32_t max_frozen = max_u32(2, NUM_DISCONNECT / 2); printf("restricting number of frozen peers to %u\n", max_frozen); for (uint16_t i = 0; i < NUM_GROUP_TOX; ++i) { Tox_Err_Conference_Set_Max_Offline err; tox_conference_set_max_offline(autotoxes[i].tox, 0, max_frozen, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_OK, "tox #%u failed to set max offline: err = %d", autotoxes[i].index, err); } printf("letting random toxes timeout\n"); bool disconnected[NUM_GROUP_TOX] = {0}; bool restarting[NUM_GROUP_TOX] = {0}; ck_assert(NUM_DISCONNECT < NUM_GROUP_TOX); for (uint32_t i = 0; i < NUM_DISCONNECT; ++i) { uint32_t disconnect = random_false_index(rng, disconnected, NUM_GROUP_TOX); disconnected[disconnect] = true; if (i < NUM_DISCONNECT / 2) { restarting[disconnect] = true; printf("Restarting #%u\n", autotoxes[disconnect].index); } else { printf("Disconnecting #%u\n", autotoxes[disconnect].index); } } uint8_t *save[NUM_GROUP_TOX]; size_t save_size[NUM_GROUP_TOX]; for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) { if (restarting[i]) { save_size[i] = tox_get_savedata_size(autotoxes[i].tox); ck_assert_msg(save_size[i] != 0, "save is invalid size %u", (unsigned)save_size[i]); save[i] = (uint8_t *)malloc(save_size[i]); ck_assert_msg(save[i] != nullptr, "malloc failed"); tox_get_savedata(autotoxes[i].tox, save[i]); tox_kill(autotoxes[i].tox); } } disconnect_toxes(NUM_GROUP_TOX, autotoxes, disconnected, restarting); for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) { if (restarting[i]) { struct Tox_Options *const options = tox_options_new(nullptr); ck_assert(options != nullptr); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); tox_options_set_savedata_data(options, save[i], save_size[i]); autotoxes[i].tox = tox_new_log(options, nullptr, &autotoxes[i].index); ck_assert(autotoxes[i].tox != nullptr); tox_options_free(options); free(save[i]); set_mono_time_callback(&autotoxes[i]); tox_conference_set_max_offline(autotoxes[i].tox, 0, max_frozen, nullptr); } } if (check_name_change_propagation) { printf("changing names\n"); for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) { char name[NAMELEN + 1]; snprintf(name, NAMELEN + 1, NEW_NAME_FORMAT_STR, autotoxes[i].index); tox_self_set_name(autotoxes[i].tox, (const uint8_t *)name, NAMELEN, nullptr); } } for (uint16_t i = 0; i < NUM_GROUP_TOX; ++i) { const uint32_t num_frozen = tox_conference_offline_peer_count(autotoxes[i].tox, 0, nullptr); ck_assert_msg(num_frozen <= max_frozen, "tox #%u has too many offline peers: %u\n", autotoxes[i].index, num_frozen); } printf("reconnecting toxes\n"); do { iterate_all_wait(autotoxes, NUM_GROUP_TOX, ITERATION_INTERVAL); } while (!all_connected_to_group(NUM_GROUP_TOX, autotoxes)); printf("running conference tests\n"); for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) { tox_callback_conference_message(autotoxes[i].tox, &handle_conference_message); iterate_all_wait(autotoxes, NUM_GROUP_TOX, ITERATION_INTERVAL); } Tox_Err_Conference_Send_Message err; ck_assert_msg( tox_conference_send_message( autotoxes[random_u32(rng) % NUM_GROUP_TOX].tox, 0, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)GROUP_MESSAGE, sizeof(GROUP_MESSAGE) - 1, &err) != 0, "failed to send group message"); ck_assert_msg( err == TOX_ERR_CONFERENCE_SEND_MESSAGE_OK, "failed to send group message"); num_recv = 0; for (uint8_t j = 0; j < NUM_GROUP_TOX * 2; ++j) { iterate_all_wait(autotoxes, NUM_GROUP_TOX, ITERATION_INTERVAL); } ck_assert_msg(num_recv == NUM_GROUP_TOX, "failed to recv group messages"); if (check_name_change_propagation) { for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) { for (uint32_t j = 0; j < NUM_GROUP_TOX; ++j) { uint8_t name[NAMELEN]; tox_conference_peer_get_name(autotoxes[i].tox, 0, j, name, nullptr); /* Note the toxes will have been reordered */ ck_assert_msg(memcmp(name, "New", 3) == 0, "name of #%u according to #%u not updated", autotoxes[j].index, autotoxes[i].index); } } } for (uint32_t k = NUM_GROUP_TOX; k != 0 ; --k) { tox_conference_delete(autotoxes[k - 1].tox, 0, nullptr); for (uint8_t j = 0; j < 10 || j < NUM_GROUP_TOX; ++j) { iterate_all_wait(autotoxes, NUM_GROUP_TOX, ITERATION_INTERVAL); } for (uint32_t i = 0; i < k - 1; ++i) { uint32_t peer_count = tox_conference_peer_count(autotoxes[i].tox, 0, nullptr); ck_assert_msg(peer_count == (k - 1), "\n\tBad number of group peers (post check)." "\n\t\t\tExpected: %u but tox_instance(%u) only has: %u\n\n", k - 1, i, (unsigned)peer_count); } } } static void test_many_group(AutoTox *autotoxes) { const time_t test_start_time = time(nullptr); for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) { tox_callback_self_connection_status(autotoxes[i].tox, &handle_self_connection_status); tox_callback_friend_connection_status(autotoxes[i].tox, &handle_friend_connection_status); tox_callback_conference_invite(autotoxes[i].tox, &handle_conference_invite); tox_callback_conference_connected(autotoxes[i].tox, &handle_conference_connected); char name[NAMELEN + 1]; snprintf(name, NAMELEN + 1, NAME_FORMAT_STR, autotoxes[i].index); tox_self_set_name(autotoxes[i].tox, (const uint8_t *)name, NAMELEN, nullptr); } ck_assert_msg(tox_conference_new(autotoxes[0].tox, nullptr) != UINT32_MAX, "failed to create group"); printf("tox #%u: inviting its first friend\n", autotoxes[0].index); ck_assert_msg(tox_conference_invite(autotoxes[0].tox, 0, 0, nullptr) != 0, "failed to invite friend"); ((State *)autotoxes[0].state)->invited_next = true; ck_assert_msg(tox_conference_set_title(autotoxes[0].tox, 0, (const uint8_t *)"Gentoo", sizeof("Gentoo") - 1, nullptr) != 0, "failed to set group title"); printf("waiting for invitations to be made\n"); uint32_t invited_count = 0; do { iterate_all_wait(autotoxes, NUM_GROUP_TOX, ITERATION_INTERVAL); invited_count = 0; for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) { invited_count += ((State *)autotoxes[i].state)->invited_next; } } while (invited_count != NUM_GROUP_TOX - 1); uint64_t pregroup_clock = autotoxes[0].clock; printf("waiting for all toxes to be in the group\n"); uint32_t fully_connected_count = 0; do { fully_connected_count = 0; printf("current peer counts: ["); iterate_all_wait(autotoxes, NUM_GROUP_TOX, ITERATION_INTERVAL); for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) { Tox_Err_Conference_Peer_Query err; uint32_t peer_count = tox_conference_peer_count(autotoxes[i].tox, 0, &err); if (err != TOX_ERR_CONFERENCE_PEER_QUERY_OK) { peer_count = 0; } fully_connected_count += peer_count == NUM_GROUP_TOX; if (i != 0) { printf(", "); } printf("%u", peer_count); } printf("]\n"); fflush(stdout); } while (fully_connected_count != NUM_GROUP_TOX); for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) { uint32_t peer_count = tox_conference_peer_count(autotoxes[i].tox, 0, nullptr); ck_assert_msg(peer_count == NUM_GROUP_TOX, "\n\tBad number of group peers (pre check)." "\n\t\t\tExpected: %d but tox_instance(%u) only has: %u\n\n", NUM_GROUP_TOX, i, (unsigned)peer_count); uint8_t title[2048]; size_t ret = tox_conference_get_title_size(autotoxes[i].tox, 0, nullptr); ck_assert_msg(ret == sizeof("Gentoo") - 1, "Wrong title length"); tox_conference_get_title(autotoxes[i].tox, 0, title, nullptr); ck_assert_msg(memcmp("Gentoo", title, ret) == 0, "Wrong title"); } printf("waiting for names to propagate\n"); do { iterate_all_wait(autotoxes, NUM_GROUP_TOX, ITERATION_INTERVAL); } while (!names_propagated(NUM_GROUP_TOX, autotoxes)); printf("group connected, took %d seconds\n", (int)((autotoxes[0].clock - pregroup_clock) / 1000)); run_conference_tests(autotoxes); printf("test_many_group succeeded, took %d seconds\n", (int)(time(nullptr) - test_start_time)); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; run_auto_test(nullptr, NUM_GROUP_TOX, test_many_group, sizeof(State), &options); return 0; } c-toxcore-0.2.18/auto_tests/conference_two_test.c0000777000175000017500000000150214227324767021131 0ustar robinrobin// This test checks that we can create two conferences and quit properly. // // This test triggers a different code path than if we only allocate a single // conference. This is the simplest test possible that triggers it. #include "../testing/misc_tools.h" #include "../toxcore/tox.h" #include "auto_test_support.h" #include "check_compat.h" int main(void) { // Create toxes. uint32_t id = 1; Tox *tox1 = tox_new_log(nullptr, nullptr, &id); // Create two conferences and then exit. Tox_Err_Conference_New err; tox_conference_new(tox1, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK, "failed to create conference 1: %d", err); tox_conference_new(tox1, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK, "failed to create conference 2: %d", err); tox_kill(tox1); return 0; } c-toxcore-0.2.18/auto_tests/crypto_test.c0000777000175000017500000003010214227324767017447 0ustar robinrobin#include #include #include #include "../testing/misc_tools.h" #include "../toxcore/crypto_core.h" #include "../toxcore/net_crypto.h" #include "check_compat.h" static void rand_bytes(const Random *rng, uint8_t *b, size_t blen) { size_t i; for (i = 0; i < blen; i++) { b[i] = random_u08(rng); } } // These test vectors are from libsodium's test suite static const uint8_t alicesk[32] = { 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a }; static const uint8_t bobpk[32] = { 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f }; static const uint8_t test_nonce[24] = { 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8, 0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 }; static const uint8_t test_m[131] = { 0xbe, 0x07, 0x5f, 0xc5, 0x3c, 0x81, 0xf2, 0xd5, 0xcf, 0x14, 0x13, 0x16, 0xeb, 0xeb, 0x0c, 0x7b, 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4, 0x4b, 0x66, 0x84, 0x9b, 0x64, 0x24, 0x4f, 0xfc, 0xe5, 0xec, 0xba, 0xaf, 0x33, 0xbd, 0x75, 0x1a, 0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29, 0x6c, 0xdc, 0x3c, 0x01, 0x23, 0x35, 0x61, 0xf4, 0x1d, 0xb6, 0x6c, 0xce, 0x31, 0x4a, 0xdb, 0x31, 0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d, 0xce, 0xea, 0x3a, 0x7f, 0xa1, 0x34, 0x80, 0x57, 0xe2, 0xf6, 0x55, 0x6a, 0xd6, 0xb1, 0x31, 0x8a, 0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde, 0x04, 0x89, 0x77, 0xeb, 0x48, 0xf5, 0x9f, 0xfd, 0x49, 0x24, 0xca, 0x1c, 0x60, 0x90, 0x2e, 0x52, 0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40, 0xe0, 0x82, 0xf9, 0x37, 0x76, 0x38, 0x48, 0x64, 0x5e, 0x07, 0x05 }; static const uint8_t test_c[147] = { 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5, 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9, 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73, 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce, 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4, 0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a, 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b, 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72, 0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2, 0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38, 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a, 0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae, 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea, 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda, 0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde, 0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3, 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6, 0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74, 0xe3, 0x55, 0xa5 }; static void test_known(void) { uint8_t c[147]; uint8_t m[131]; uint16_t clen, mlen; ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), "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_m) == sizeof(m), "sanity check failed"); 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(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); 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"); } static void test_fast_known(void) { uint8_t k[CRYPTO_SHARED_KEY_SIZE]; uint8_t c[147]; uint8_t m[131]; uint16_t clen, mlen; encrypt_precompute(bobpk, alicesk, k); ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), "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_m) == sizeof(m), "sanity check failed"); 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(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); 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"); } static void test_endtoend(void) { const Random *rng = system_random(); ck_assert(rng != nullptr); // Test 100 random messages and keypairs for (uint8_t testno = 0; testno < 100; testno++) { uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t sk2[CRYPTO_SECRET_KEY_SIZE]; uint8_t k1[CRYPTO_SHARED_KEY_SIZE]; uint8_t k2[CRYPTO_SHARED_KEY_SIZE]; uint8_t n[CRYPTO_NONCE_SIZE]; enum { M_SIZE = 50 }; uint8_t m[M_SIZE]; uint8_t c1[sizeof(m) + CRYPTO_MAC_SIZE]; uint8_t c2[sizeof(m) + CRYPTO_MAC_SIZE]; uint8_t c3[sizeof(m) + CRYPTO_MAC_SIZE]; uint8_t c4[sizeof(m) + CRYPTO_MAC_SIZE]; uint8_t m1[sizeof(m)]; uint8_t m2[sizeof(m)]; uint8_t m3[sizeof(m)]; uint8_t m4[sizeof(m)]; //Generate random message (random length from 10 to 50) const uint16_t mlen = (random_u32(rng) % (M_SIZE - 10)) + 10; rand_bytes(rng, m, mlen); rand_bytes(rng, n, CRYPTO_NONCE_SIZE); //Generate keypairs crypto_new_keypair(rng, pk1, sk1); crypto_new_keypair(rng, pk2, sk2); //Precompute shared keys encrypt_precompute(pk2, sk1, k1); encrypt_precompute(pk1, sk2, k2); ck_assert_msg(memcmp(k1, k2, CRYPTO_SHARED_KEY_SIZE) == 0, "encrypt_precompute: bad"); //Encrypt all four ways const uint16_t c1len = encrypt_data(pk2, sk1, n, m, mlen, c1); const uint16_t c2len = encrypt_data(pk1, sk2, n, m, mlen, c2); const uint16_t c3len = encrypt_data_symmetric(k1, n, m, mlen, c3); const uint16_t c4len = encrypt_data_symmetric(k2, n, m, mlen, c4); ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ"); ck_assert_msg(c1len == mlen + (uint16_t)CRYPTO_MAC_SIZE, "wrong cyphertext length"); ck_assert_msg(memcmp(c1, c2, c1len) == 0 && memcmp(c1, c3, c1len) == 0 && memcmp(c1, c4, c1len) == 0, "crypertexts differ"); //Decrypt all four ways const uint16_t m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1); const uint16_t m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2); const uint16_t m3len = decrypt_data_symmetric(k1, n, c1, c1len, m3); const uint16_t m4len = decrypt_data_symmetric(k2, n, c1, c1len, m4); ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ"); ck_assert_msg(m1len == mlen, "wrong decrypted text length"); ck_assert_msg(memcmp(m1, m2, mlen) == 0 && memcmp(m1, m3, mlen) == 0 && memcmp(m1, m4, mlen) == 0, "decrypted texts differ"); ck_assert_msg(memcmp(m1, m, mlen) == 0, "wrong decrypted text"); } } static void test_large_data(void) { const Random *rng = system_random(); ck_assert(rng != nullptr); uint8_t k[CRYPTO_SHARED_KEY_SIZE]; uint8_t n[CRYPTO_NONCE_SIZE]; const size_t m1_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; uint8_t *m1 = (uint8_t *)malloc(m1_size); uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); uint8_t *m1prime = (uint8_t *)malloc(m1_size); const size_t m2_size = MAX_CRYPTO_PACKET_SIZE - CRYPTO_MAC_SIZE; uint8_t *m2 = (uint8_t *)malloc(m2_size); uint8_t *c2 = (uint8_t *)malloc(m2_size + CRYPTO_MAC_SIZE); ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr && m2 != nullptr && c2 != nullptr); //Generate random messages rand_bytes(rng, m1, m1_size); rand_bytes(rng, m2, m2_size); rand_bytes(rng, n, CRYPTO_NONCE_SIZE); //Generate key rand_bytes(rng, k, CRYPTO_SHARED_KEY_SIZE); const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1); const uint16_t c2len = encrypt_data_symmetric(k, n, m2, m2_size, c2); ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt"); ck_assert_msg(c2len == m2_size + CRYPTO_MAC_SIZE, "could not encrypt"); const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); free(c2); free(m2); free(m1prime); free(c1); free(m1); } static void test_large_data_symmetric(void) { const Random *rng = system_random(); ck_assert(rng != nullptr); uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE]; uint8_t n[CRYPTO_NONCE_SIZE]; const size_t m1_size = 16 * 16 * 16; uint8_t *m1 = (uint8_t *)malloc(m1_size); uint8_t *c1 = (uint8_t *)malloc(m1_size + CRYPTO_MAC_SIZE); uint8_t *m1prime = (uint8_t *)malloc(m1_size); ck_assert(m1 != nullptr && c1 != nullptr && m1prime != nullptr); //Generate random messages rand_bytes(rng, m1, m1_size); rand_bytes(rng, n, CRYPTO_NONCE_SIZE); //Generate key new_symmetric_key(rng, k); const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1); ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt data"); const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); free(m1prime); free(c1); free(m1); } static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num) { uint32_t num1, num2; memcpy(&num1, nonce + (CRYPTO_NONCE_SIZE - sizeof(num1)), sizeof(num1)); num1 = net_ntohl(num1); num2 = num + num1; if (num2 < num1) { for (uint16_t i = CRYPTO_NONCE_SIZE - sizeof(num1); i != 0; --i) { ++nonce[i - 1]; if (nonce[i - 1] != 0) { break; } } } num2 = net_htonl(num2); memcpy(nonce + (CRYPTO_NONCE_SIZE - sizeof(num2)), &num2, sizeof(num2)); } static void test_increment_nonce(void) { const Random *rng = system_random(); ck_assert(rng != nullptr); uint32_t i; uint8_t n[CRYPTO_NONCE_SIZE]; for (i = 0; i < CRYPTO_NONCE_SIZE; ++i) { n[i] = random_u08(rng); } uint8_t n1[CRYPTO_NONCE_SIZE]; memcpy(n1, n, CRYPTO_NONCE_SIZE); for (i = 0; i < (1 << 18); ++i) { increment_nonce_number_cmp(n, 1); increment_nonce(n1); ck_assert_msg(memcmp(n, n1, CRYPTO_NONCE_SIZE) == 0, "Bad increment_nonce function"); } for (i = 0; i < (1 << 18); ++i) { const uint32_t r = random_u32(rng); increment_nonce_number_cmp(n, r); increment_nonce_number(n1, r); ck_assert_msg(memcmp(n, n1, CRYPTO_NONCE_SIZE) == 0, "Bad increment_nonce_number function"); } } static void test_memzero(void) { uint8_t src[sizeof(test_c)]; memcpy(src, test_c, sizeof(test_c)); crypto_memzero(src, sizeof(src)); size_t i; for (i = 0; i < sizeof(src); i++) { ck_assert_msg(src[i] == 0, "Memory is not zeroed"); } } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_known(); test_fast_known(); test_endtoend(); /* waiting up to 15 seconds */ test_large_data(); test_large_data_symmetric(); test_increment_nonce(); test_memzero(); return 0; } c-toxcore-0.2.18/auto_tests/data/0000777000175000017500000000000014227324767015636 5ustar robinrobinc-toxcore-0.2.18/auto_tests/data/save.tox0000777000175000017500000001037314227324767017337 0ustar robinrobinDLv,}i*[ǽzv[0|oī[!5޻f!=Ix+ّެzw Yk%UvFkJRVƬQ~NFo':4f䂥O<Ϩwvy236'ߵbvh=E;]"w 6#ŰT3*@#_r]W{˱ȃY(G1 |A I;=(*e6v/Ղa[l)QL 6u^5wc25MQaAgi ʘ^(*`D2eh!, $$х7]긂Vk %kD/.UP3],_@W)L\vOp>I 22(^~(ֶtlsyt2ra_'ӮdႥNjp~T_Y9U/U uW<?uZONe{eǎ[gͷb_l=o;,wc3%I2ɉe FeQb5L٭/T`ݕUO%uUnZsI/Ղa[l)QL 6u^5wc25MQaAgi ʘ^(*`D2eh!W{˱ȃY(G1 |A I;=(*e6v4f䂥O<Ϩwvy236'ߵbvh=E;]"w 6#ŰT3*@#_r]Ne{eǎ[gͷb_l=o;٭/T`ݕUO%uUnZsI,wc3%I2ɉe FeQb5L>FkJRVƬQ~NFo':4f䂥O<Ϩwvy236'ߵbvh=W{˱ȃY(G1 |A I;=(*e6vMQaAgi ʘ^(*`D2eh!/Ղa[l)QL 6u^5wc25" [y'1|r讐aŠwCAdd me.Y*name Hello World 8 Ne{eǎ[gͷb_l=o;MQaAgi ʘ^(*`D2eh!/Ղa[l)QL 6u^5wc25T/ĵoyDq͎vH ^W{˱ȃY(G1 |A I;=(*e6vE;]"w 6#ŰT3*@#_r]>FkJRVƬQ~NFo':4f䂥O<Ϩwvy236'ߵbvh=c-toxcore-0.2.18/auto_tests/dht_getnodes_api_test.c0000777000175000017500000001016014227324767021431 0ustar robinrobin/** * This autotest creates a small local DHT and makes sure that each peer can crawl * the entire DHT using the DHT getnodes api functions. */ #include #include #include #include #include "../toxcore/tox.h" #include "../toxcore/tox_private.h" #include "auto_test_support.h" #include "check_compat.h" #define NUM_TOXES 30 typedef struct Dht_Node { uint8_t public_key[TOX_DHT_NODE_PUBLIC_KEY_SIZE]; char ip[TOX_DHT_NODE_IP_STRING_SIZE]; uint16_t port; } Dht_Node; typedef struct State { Dht_Node **nodes; size_t num_nodes; uint8_t **public_key_list; } State; static void free_nodes(Dht_Node **nodes, size_t num_nodes) { for (size_t i = 0; i < num_nodes; ++i) { free(nodes[i]); } free(nodes); } static bool node_crawled(Dht_Node **nodes, size_t num_nodes, const uint8_t *public_key) { for (size_t i = 0; i < num_nodes; ++i) { if (memcmp(nodes[i]->public_key, public_key, TOX_DHT_NODE_PUBLIC_KEY_SIZE) == 0) { return true; } } return false; } static bool all_nodes_crawled(const AutoTox *autotoxes, uint32_t num_toxes, uint8_t **public_key_list) { for (uint32_t i = 0; i < num_toxes; ++i) { const State *state = (const State *)autotoxes[i].state; // make sure each peer has crawled the correct number of nodes if (state->num_nodes < num_toxes) { return false; } } for (uint32_t i = 0; i < num_toxes; ++i) { const State *state = (const State *)autotoxes[i].state; // make sure each peer has the full list of public keys for (uint32_t j = 0; j < num_toxes; ++j) { if (!node_crawled(state->nodes, state->num_nodes, public_key_list[j])) { return false; } } } return true; } static void getnodes_response_cb(Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port, void *user_data) { ck_assert(user_data != nullptr); AutoTox *autotoxes = (AutoTox *)user_data; State *state = (State *)autotoxes->state; if (node_crawled(state->nodes, state->num_nodes, public_key)) { return; } ck_assert(state->num_nodes < NUM_TOXES); Dht_Node *node = (Dht_Node *)calloc(1, sizeof(Dht_Node)); ck_assert(node != nullptr); memcpy(node->public_key, public_key, TOX_DHT_NODE_PUBLIC_KEY_SIZE); snprintf(node->ip, sizeof(node->ip), "%s", ip); node->port = port; state->nodes[state->num_nodes] = node; ++state->num_nodes; // ask new node to give us their close nodes to every public key for (size_t i = 0; i < NUM_TOXES; ++i) { tox_dht_get_nodes(tox, public_key, ip, port, state->public_key_list[i], nullptr); } } static void test_dht_getnodes(AutoTox *autotoxes) { ck_assert(NUM_TOXES >= 2); uint8_t **public_key_list = (uint8_t **)calloc(NUM_TOXES, sizeof(uint8_t *)); ck_assert(public_key_list != nullptr); for (size_t i = 0; i < NUM_TOXES; ++i) { State *state = (State *)autotoxes[i].state; state->nodes = (Dht_Node **)calloc(NUM_TOXES, sizeof(Dht_Node *)); ck_assert(state->nodes != nullptr); state->num_nodes = 0; state->public_key_list = public_key_list; public_key_list[i] = (uint8_t *)malloc(sizeof(uint8_t) * TOX_PUBLIC_KEY_SIZE); ck_assert(public_key_list[i] != nullptr); tox_self_get_dht_id(autotoxes[i].tox, public_key_list[i]); tox_callback_dht_get_nodes_response(autotoxes[i].tox, getnodes_response_cb); } while (!all_nodes_crawled(autotoxes, NUM_TOXES, public_key_list)) { iterate_all_wait(autotoxes, NUM_TOXES, ITERATION_INTERVAL); } for (size_t i = 0; i < NUM_TOXES; ++i) { State *state = (State *)autotoxes[i].state; free_nodes(state->nodes, state->num_nodes); free(public_key_list[i]); } free(public_key_list); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; run_auto_test(nullptr, NUM_TOXES, test_dht_getnodes, sizeof(State), &options); return 0; } #undef NUM_TOXES c-toxcore-0.2.18/auto_tests/encryptsave_test.c0000777000175000017500000002521114227324767020477 0ustar robinrobin#include #include #include #include #ifndef VANILLA_NACL #include #include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" #include "../toxcore/crypto_core.h" #include "../toxcore/tox.h" #include "../toxencryptsave/toxencryptsave.h" #include "auto_test_support.h" #include "check_compat.h" static unsigned char test_salt[TOX_PASS_SALT_LENGTH] = {0xB1, 0xC2, 0x09, 0xEE, 0x50, 0x6C, 0xF0, 0x20, 0xC4, 0xD6, 0xEB, 0xC0, 0x44, 0x51, 0x3B, 0x60, 0x4B, 0x39, 0x4A, 0xCF, 0x09, 0x53, 0x4F, 0xEA, 0x08, 0x41, 0xFA, 0xCA, 0x66, 0xD2, 0x68, 0x7F}; static unsigned char known_key[TOX_PASS_KEY_LENGTH] = {0x29, 0x36, 0x1c, 0x9e, 0x65, 0xbb, 0x46, 0x8b, 0xde, 0xa1, 0xac, 0xf, 0xd5, 0x11, 0x81, 0xc8, 0x29, 0x28, 0x17, 0x23, 0xa6, 0xc3, 0x6b, 0x77, 0x2e, 0xd7, 0xd3, 0x10, 0xeb, 0xd2, 0xf7, 0xc8}; static const char *pw = "hunter2"; static unsigned int pwlen = 7; static unsigned char known_key2[CRYPTO_SHARED_KEY_SIZE] = {0x7a, 0xfa, 0x95, 0x45, 0x36, 0x8a, 0xa2, 0x5c, 0x40, 0xfd, 0xc0, 0xe2, 0x35, 0x8, 0x7, 0x88, 0xfa, 0xf9, 0x37, 0x86, 0xeb, 0xff, 0x50, 0x4f, 0x3, 0xe2, 0xf6, 0xd9, 0xef, 0x9, 0x17, 0x1}; // same as above, except standard opslimit instead of extra ops limit for test_known_kdf, and hash pw before kdf for compat /* cause I'm shameless */ static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) { if (*((uint32_t *)userdata) != 974536) { return; } if (length == 7 && memcmp("Gentoo", data, 7) == 0) { tox_friend_add_norequest(m, public_key, nullptr); } } static void test_known_kdf(void) { unsigned char out[CRYPTO_SHARED_KEY_SIZE]; int16_t res = crypto_pwhash_scryptsalsa208sha256(out, CRYPTO_SHARED_KEY_SIZE, pw, pwlen, test_salt, crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 8, crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE); ck_assert_msg(res != -1, "crypto function failed"); ck_assert_msg(memcmp(out, known_key, CRYPTO_SHARED_KEY_SIZE) == 0, "derived key is wrong"); } static void test_save_friend(void) { Tox *tox1 = tox_new_log(nullptr, nullptr, nullptr); Tox *tox2 = tox_new_log(nullptr, nullptr, nullptr); ck_assert_msg(tox1 || tox2, "Failed to create 2 tox instances"); tox_callback_friend_request(tox2, accept_friend_request); uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(tox2, address); uint32_t test = tox_friend_add(tox1, address, (const uint8_t *)"Gentoo", 7, nullptr); ck_assert_msg(test != UINT32_MAX, "Failed to add friend"); size_t size = tox_get_savedata_size(tox1); uint8_t *data = (uint8_t *)malloc(size); ck_assert(data != nullptr); tox_get_savedata(tox1, data); size_t size2 = size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH; uint8_t *enc_data = (uint8_t *)malloc(size2); ck_assert(enc_data != nullptr); Tox_Err_Encryption error1; bool ret = tox_pass_encrypt(data, size, (const uint8_t *)"correcthorsebatterystaple", 25, enc_data, &error1); ck_assert_msg(ret, "failed to encrypted save: %d", error1); ck_assert_msg(tox_is_data_encrypted(enc_data), "magic number missing"); struct Tox_Options *options = tox_options_new(nullptr); ck_assert(options != nullptr); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); tox_options_set_savedata_data(options, enc_data, size2); Tox_Err_New err2; Tox *tox3 = tox_new_log(options, &err2, nullptr); ck_assert_msg(err2 == TOX_ERR_NEW_LOAD_ENCRYPTED, "wrong error! %d. should fail with %d", err2, TOX_ERR_NEW_LOAD_ENCRYPTED); ck_assert_msg(tox3 == nullptr, "tox_new with error should return NULL"); uint8_t *dec_data = (uint8_t *)malloc(size); ck_assert(dec_data != nullptr); Tox_Err_Decryption err3; ret = tox_pass_decrypt(enc_data, size2, (const uint8_t *)"correcthorsebatterystaple", 25, dec_data, &err3); ck_assert_msg(ret, "failed to decrypt save: %d", err3); tox_options_set_savedata_data(options, dec_data, size); tox3 = tox_new_log(options, &err2, nullptr); ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to load from decrypted data: %d", err2); uint8_t address2[TOX_PUBLIC_KEY_SIZE]; ret = tox_friend_get_public_key(tox3, 0, address2, nullptr); ck_assert_msg(ret, "no friends!"); ck_assert_msg(memcmp(address, address2, TOX_PUBLIC_KEY_SIZE) == 0, "addresses don't match!"); size = tox_get_savedata_size(tox3); uint8_t *data2 = (uint8_t *)malloc(size); ck_assert(data2 != nullptr); tox_get_savedata(tox3, data2); Tox_Err_Key_Derivation keyerr; Tox_Pass_Key *key = tox_pass_key_derive((const uint8_t *)"123qweasdzxc", 12, &keyerr); ck_assert_msg(key != nullptr, "pass key allocation failure"); memcpy((uint8_t *)key, test_salt, TOX_PASS_SALT_LENGTH); memcpy((uint8_t *)key + TOX_PASS_SALT_LENGTH, known_key2, TOX_PASS_KEY_LENGTH); size2 = size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH; uint8_t *encdata2 = (uint8_t *)malloc(size2); ck_assert(encdata2 != nullptr); ret = tox_pass_key_encrypt(key, data2, size, encdata2, &error1); ck_assert_msg(ret, "failed to key encrypt %d", error1); ck_assert_msg(tox_is_data_encrypted(encdata2), "magic number the second missing"); uint8_t *out1 = (uint8_t *)malloc(size); ck_assert(out1 != nullptr); uint8_t *out2 = (uint8_t *)malloc(size); ck_assert(out2 != nullptr); ret = tox_pass_decrypt(encdata2, size2, (const uint8_t *)pw, pwlen, out1, &err3); ck_assert_msg(ret, "failed to pw decrypt %d", err3); ret = tox_pass_key_decrypt(key, encdata2, size2, out2, &err3); ck_assert_msg(ret, "failed to key decrypt %d", err3); ck_assert_msg(memcmp(out1, out2, size) == 0, "differing output data"); // and now with the code in use (I only bothered with manually to debug this, and it seems a waste // to remove the manual check now that it's there) tox_options_set_savedata_data(options, out1, size); Tox *tox4 = tox_new_log(options, &err2, nullptr); ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to new the third"); uint8_t address5[TOX_PUBLIC_KEY_SIZE]; ret = tox_friend_get_public_key(tox4, 0, address5, nullptr); ck_assert_msg(ret, "no friends! the third"); ck_assert_msg(memcmp(address, address2, TOX_PUBLIC_KEY_SIZE) == 0, "addresses don't match! the third"); tox_pass_key_free(key); tox_options_free(options); tox_kill(tox1); tox_kill(tox2); tox_kill(tox3); tox_kill(tox4); free(out2); free(out1); free(encdata2); free(data2); free(dec_data); free(enc_data); free(data); } static void test_keys(void) { Tox_Err_Encryption encerr; Tox_Err_Decryption decerr; Tox_Err_Key_Derivation keyerr; const uint8_t *key_char = (const uint8_t *)"123qweasdzxc"; Tox_Pass_Key *key = tox_pass_key_derive(key_char, 12, &keyerr); ck_assert_msg(key != nullptr, "generic failure 1: %d", keyerr); const uint8_t *string = (const uint8_t *)"No Patrick, mayonnaise is not an instrument."; // 44 uint8_t encrypted[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH]; bool ret = tox_pass_key_encrypt(key, string, 44, encrypted, &encerr); ck_assert_msg(ret, "generic failure 2: %d", encerr); // Testing how tox handles encryption of large messages. int size_large = 30 * 1024 * 1024; int ciphertext_length2a = size_large + TOX_PASS_ENCRYPTION_EXTRA_LENGTH; int plaintext_length2a = size_large; uint8_t *encrypted2a = (uint8_t *)malloc(ciphertext_length2a); ck_assert(encrypted2a != nullptr); uint8_t *in_plaintext2a = (uint8_t *)malloc(plaintext_length2a); ck_assert(in_plaintext2a != nullptr); const Random *rng = system_random(); ck_assert(rng != nullptr); random_bytes(rng, in_plaintext2a, plaintext_length2a); ret = tox_pass_encrypt(in_plaintext2a, plaintext_length2a, key_char, 12, encrypted2a, &encerr); ck_assert_msg(ret, "tox_pass_encrypt failure 2a: %d", encerr); // Decryption of same message. uint8_t *out_plaintext2a = (uint8_t *)malloc(plaintext_length2a); ck_assert(out_plaintext2a != nullptr); ret = tox_pass_decrypt(encrypted2a, ciphertext_length2a, key_char, 12, out_plaintext2a, &decerr); ck_assert_msg(ret, "tox_pass_decrypt failure 2a: %d", decerr); ck_assert_msg(memcmp(in_plaintext2a, out_plaintext2a, plaintext_length2a) == 0, "Large message decryption failed"); free(encrypted2a); free(in_plaintext2a); free(out_plaintext2a); uint8_t encrypted2[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH]; ret = tox_pass_encrypt(string, 44, key_char, 12, encrypted2, &encerr); ck_assert_msg(ret, "generic failure 3: %d", encerr); uint8_t out1[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH]; uint8_t out2[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH]; ret = tox_pass_key_decrypt(key, encrypted, 44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH, out1, &decerr); ck_assert_msg(ret, "generic failure 4: %d", decerr); ck_assert_msg(memcmp(out1, string, 44) == 0, "decryption 1 failed"); ret = tox_pass_decrypt(encrypted2, 44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH, (const uint8_t *)"123qweasdzxc", 12, out2, &decerr); ck_assert_msg(ret, "generic failure 5: %d", decerr); ck_assert_msg(memcmp(out2, string, 44) == 0, "decryption 2 failed"); ret = tox_pass_decrypt(encrypted2, 44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH, nullptr, 0, out2, &decerr); ck_assert_msg(!ret, "Decrypt succeeded with wrong pass"); ck_assert_msg(decerr != TOX_ERR_DECRYPTION_FAILED, "Bad error code %d", decerr); // test that pass_decrypt can decrypt things from pass_key_encrypt ret = tox_pass_decrypt(encrypted, 44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH, (const uint8_t *)"123qweasdzxc", 12, out1, &decerr); ck_assert_msg(ret, "generic failure 6: %d", decerr); ck_assert_msg(memcmp(out1, string, 44) == 0, "decryption 3 failed"); uint8_t salt[TOX_PASS_SALT_LENGTH]; Tox_Err_Get_Salt salt_err; ck_assert_msg(tox_get_salt(encrypted, salt, &salt_err), "couldn't get salt"); ck_assert_msg(salt_err == TOX_ERR_GET_SALT_OK, "get_salt returned an error"); Tox_Pass_Key *key2 = tox_pass_key_derive_with_salt((const uint8_t *)"123qweasdzxc", 12, salt, &keyerr); ck_assert_msg(key2 != nullptr, "generic failure 7: %d", keyerr); ck_assert_msg(0 == memcmp(key, key2, TOX_PASS_KEY_LENGTH + TOX_PASS_SALT_LENGTH), "salt comparison failed"); tox_pass_key_free(key2); tox_pass_key_free(key); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_known_kdf(); test_save_friend(); test_keys(); return 0; } #else // VANILLA_NACL int main(void) { return 0; } #endif c-toxcore-0.2.18/auto_tests/file_saving_test.c0000777000175000017500000000665614227324767020436 0ustar robinrobin/* SPDX-License-Identifier: GPL-3.0-or-later * Copyright © 2016-2018 The TokTok team. * Copyright © 2016 Tox project. */ /* * Small test for checking if obtaining savedata, saving it to disk and using * works correctly. */ #include #include #include #include #include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" #include "auto_test_support.h" #include "check_compat.h" #include "../toxencryptsave/toxencryptsave.h" static const char *pphrase = "bar"; static const char *name = "foo"; static const char *savefile = "./save"; static void save_data_encrypted(void) { struct Tox_Options *options = tox_options_new(nullptr); Tox *t = tox_new_log(options, nullptr, nullptr); tox_options_free(options); tox_self_set_name(t, (const uint8_t *)name, strlen(name), nullptr); FILE *f = fopen(savefile, "wb"); size_t size = tox_get_savedata_size(t); uint8_t *clear = (uint8_t *)malloc(size); /*this function does not write any data at all*/ tox_get_savedata(t, clear); size += TOX_PASS_ENCRYPTION_EXTRA_LENGTH; uint8_t *cipher = (uint8_t *)malloc(size); Tox_Err_Encryption eerr; ck_assert_msg(tox_pass_encrypt(clear, size - TOX_PASS_ENCRYPTION_EXTRA_LENGTH, (const uint8_t *)pphrase, strlen(pphrase), cipher, &eerr), "Could not encrypt, error code %d.", eerr); size_t written_value = fwrite(cipher, sizeof(*cipher), size, f); printf("written written_value = %u of %u\n", (unsigned)written_value, (unsigned)size); free(cipher); free(clear); fclose(f); tox_kill(t); } static void load_data_decrypted(void) { FILE *f = fopen(savefile, "rb"); ck_assert(f != nullptr); fseek(f, 0, SEEK_END); int64_t size = ftell(f); fseek(f, 0, SEEK_SET); ck_assert_msg(0 <= size && size <= UINT_MAX, "file size out of range"); uint8_t *cipher = (uint8_t *)malloc(size); ck_assert(cipher != nullptr); uint8_t *clear = (uint8_t *)malloc(size - TOX_PASS_ENCRYPTION_EXTRA_LENGTH); ck_assert(clear != nullptr); size_t read_value = fread(cipher, sizeof(*cipher), size, f); printf("Read read_value = %u of %u\n", (unsigned)read_value, (unsigned)size); Tox_Err_Decryption derr; ck_assert_msg(tox_pass_decrypt(cipher, size, (const uint8_t *)pphrase, strlen(pphrase), clear, &derr), "Could not decrypt, error code %d.", derr); struct Tox_Options *options = tox_options_new(nullptr); ck_assert(options != nullptr); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); tox_options_set_savedata_data(options, clear, size); Tox_Err_New err; Tox *t = tox_new_log(options, &err, nullptr); tox_options_free(options); ck_assert_msg(t != nullptr, "tox_new returned the error value %d", err); uint8_t *readname = (uint8_t *)malloc(tox_self_get_name_size(t)); ck_assert(readname != nullptr); tox_self_get_name(t, readname); ck_assert_msg(memcmp(readname, name, tox_self_get_name_size(t)) == 0, "name returned by tox_self_get_name does not match expected result"); tox_kill(t); free(clear); free(cipher); free(readname); fclose(f); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); save_data_encrypted(); load_data_decrypted(); ck_assert_msg(remove(savefile) == 0, "Could not remove the savefile."); return 0; } c-toxcore-0.2.18/auto_tests/file_transfer_test.c0000777000175000017500000003523314227324767020764 0ustar robinrobin/* File transfer test. */ #include #include #include #include #include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" /* The Travis-CI container responds poorly to ::1 as a localhost address * You're encouraged to -D FORCE_TESTS_IPV6 on a local test */ #ifdef FORCE_TESTS_IPV6 #define TOX_LOCALHOST "::1" #else #define TOX_LOCALHOST "127.0.0.1" #endif static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) { if (length == 7 && memcmp("Gentoo", data, 7) == 0) { tox_friend_add_norequest(m, public_key, nullptr); } } static uint64_t size_recv; static uint64_t sending_pos; static uint8_t file_cmp_id[TOX_FILE_ID_LENGTH]; static uint32_t file_accepted; static uint64_t file_size; static void tox_file_receive(Tox *tox, uint32_t friend_number, uint32_t file_number, uint32_t kind, uint64_t filesize, const uint8_t *filename, size_t filename_length, void *userdata) { ck_assert_msg(kind == TOX_FILE_KIND_DATA, "bad kind"); ck_assert_msg(filename_length == sizeof("Gentoo.exe") && memcmp(filename, "Gentoo.exe", sizeof("Gentoo.exe")) == 0, "bad filename"); uint8_t file_id[TOX_FILE_ID_LENGTH]; ck_assert_msg(tox_file_get_file_id(tox, friend_number, file_number, file_id, nullptr), "tox_file_get_file_id error"); ck_assert_msg(memcmp(file_id, file_cmp_id, TOX_FILE_ID_LENGTH) == 0, "bad file_id"); uint8_t empty[TOX_FILE_ID_LENGTH] = {0}; ck_assert_msg(memcmp(empty, file_cmp_id, TOX_FILE_ID_LENGTH) != 0, "empty file_id"); file_size = filesize; if (filesize) { sending_pos = size_recv = 1337; Tox_Err_File_Seek err_s; ck_assert_msg(tox_file_seek(tox, friend_number, file_number, 1337, &err_s), "tox_file_seek error"); ck_assert_msg(err_s == TOX_ERR_FILE_SEEK_OK, "tox_file_seek wrong error"); } else { sending_pos = size_recv = 0; } Tox_Err_File_Control error; ck_assert_msg(tox_file_control(tox, friend_number, file_number, TOX_FILE_CONTROL_RESUME, &error), "tox_file_control failed. %i", error); ++file_accepted; Tox_Err_File_Seek err_s; ck_assert_msg(!tox_file_seek(tox, friend_number, file_number, 1234, &err_s), "tox_file_seek no error"); ck_assert_msg(err_s == TOX_ERR_FILE_SEEK_DENIED, "tox_file_seek wrong error"); } static uint32_t sendf_ok; static void file_print_control(Tox *tox, uint32_t friend_number, uint32_t file_number, Tox_File_Control control, void *userdata) { /* First send file num is 0.*/ if (file_number == 0 && control == TOX_FILE_CONTROL_RESUME) { sendf_ok = 1; } } static uint64_t max_sending; static bool m_send_reached; static uint8_t sending_num; static bool file_sending_done; static void tox_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, size_t length, void *user_data) { ck_assert_msg(sendf_ok, "didn't get resume control"); ck_assert_msg(sending_pos == position, "bad position %lu", (unsigned long)position); if (length == 0) { ck_assert_msg(!file_sending_done, "file sending already done"); file_sending_done = 1; return; } if (position + length > max_sending) { ck_assert_msg(!m_send_reached, "requested done file transfer"); length = max_sending - position; m_send_reached = 1; } VLA(uint8_t, f_data, length); memset(f_data, sending_num, length); Tox_Err_File_Send_Chunk error; tox_file_send_chunk(tox, friend_number, file_number, position, f_data, length, &error); ck_assert_msg(error == TOX_ERR_FILE_SEND_CHUNK_OK, "could not send chunk, error num=%d pos=%d len=%d", (int)error, (int)position, (int)length); ++sending_num; sending_pos += length; } static uint8_t num; static bool file_recv; static void write_file(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, const uint8_t *data, size_t length, void *user_data) { ck_assert_msg(size_recv == position, "bad position"); if (length == 0) { file_recv = 1; return; } VLA(uint8_t, f_data, length); memset(f_data, num, length); ++num; ck_assert_msg(memcmp(f_data, data, length) == 0, "FILE_CORRUPTED"); size_recv += length; } static void file_transfer_test(void) { printf("Starting test: few_clients\n"); uint32_t index[] = { 1, 2, 3 }; long long unsigned int cur_time = time(nullptr); Tox_Err_New t_n_error; Tox *tox1 = tox_new_log(nullptr, &t_n_error, &index[0]); ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "wrong error"); Tox *tox2 = tox_new_log(nullptr, &t_n_error, &index[1]); ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "wrong error"); Tox *tox3 = tox_new_log(nullptr, &t_n_error, &index[2]); ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "wrong error"); ck_assert_msg(tox1 && tox2 && tox3, "Failed to create 3 tox instances"); tox_callback_friend_request(tox2, accept_friend_request); uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(tox2, address); 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); uint8_t dhtKey[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(tox1, dhtKey); uint16_t dhtPort = tox_self_get_udp_port(tox1, nullptr); tox_bootstrap(tox2, TOX_LOCALHOST, dhtPort, dhtKey, nullptr); tox_bootstrap(tox3, TOX_LOCALHOST, dhtPort, dhtKey, nullptr); printf("Waiting for toxes to come online\n"); do { tox_iterate(tox1, nullptr); tox_iterate(tox2, nullptr); tox_iterate(tox3, nullptr); printf("Connections: self (%d, %d, %d), friends (%d, %d)\n", tox_self_get_connection_status(tox1), tox_self_get_connection_status(tox2), tox_self_get_connection_status(tox3), tox_friend_get_connection_status(tox2, 0, nullptr), tox_friend_get_connection_status(tox3, 0, nullptr)); c_sleep(ITERATION_INTERVAL); } while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE || tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE || tox_self_get_connection_status(tox3) == TOX_CONNECTION_NONE || tox_friend_get_connection_status(tox2, 0, nullptr) == TOX_CONNECTION_NONE || tox_friend_get_connection_status(tox3, 0, nullptr) == TOX_CONNECTION_NONE); printf("Starting file transfer test: 100MiB file.\n"); file_accepted = file_size = sendf_ok = size_recv = 0; file_recv = 0; max_sending = UINT64_MAX; uint64_t f_time = time(nullptr); tox_callback_file_recv_chunk(tox3, write_file); tox_callback_file_recv_control(tox2, file_print_control); tox_callback_file_chunk_request(tox2, tox_file_chunk_request); tox_callback_file_recv_control(tox3, file_print_control); tox_callback_file_recv(tox3, tox_file_receive); uint64_t totalf_size = 100 * 1024 * 1024; uint32_t fnum = tox_file_send(tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr, (const uint8_t *)"Gentoo.exe", sizeof("Gentoo.exe"), nullptr); ck_assert_msg(fnum != UINT32_MAX, "tox_new_file_sender fail"); Tox_Err_File_Get gfierr; ck_assert_msg(!tox_file_get_file_id(tox2, 1, fnum, file_cmp_id, &gfierr), "tox_file_get_file_id didn't fail"); ck_assert_msg(gfierr == TOX_ERR_FILE_GET_FRIEND_NOT_FOUND, "wrong error"); ck_assert_msg(!tox_file_get_file_id(tox2, 0, fnum + 1, file_cmp_id, &gfierr), "tox_file_get_file_id didn't fail"); ck_assert_msg(gfierr == TOX_ERR_FILE_GET_NOT_FOUND, "wrong error"); ck_assert_msg(tox_file_get_file_id(tox2, 0, fnum, file_cmp_id, &gfierr), "tox_file_get_file_id failed"); ck_assert_msg(gfierr == TOX_ERR_FILE_GET_OK, "wrong error"); const size_t max_iterations = INT16_MAX; for (size_t i = 0; i < max_iterations; i++) { tox_iterate(tox1, nullptr); tox_iterate(tox2, nullptr); tox_iterate(tox3, nullptr); if (file_sending_done) { ck_assert_msg(sendf_ok && file_recv && totalf_size == file_size && size_recv == file_size && sending_pos == size_recv && file_accepted == 1, "Something went wrong in file transfer %u %u %u %u %u %u %lu %lu %lu", sendf_ok, file_recv, totalf_size == file_size, size_recv == file_size, sending_pos == size_recv, file_accepted == 1, (unsigned long)totalf_size, (unsigned long)size_recv, (unsigned long)sending_pos); break; } uint32_t tox1_interval = tox_iteration_interval(tox1); uint32_t tox2_interval = tox_iteration_interval(tox2); uint32_t tox3_interval = tox_iteration_interval(tox3); if ((i + 1) % 500 == 0) { printf("after %u iterations: %.2fMiB done\n", (unsigned int)i + 1, (double)size_recv / 1024 / 1024); } c_sleep(min_u32(tox1_interval, min_u32(tox2_interval, tox3_interval))); } ck_assert_msg(file_sending_done, "file sending did not complete after %u iterations: sendf_ok:%u file_recv:%u " "totalf_size==file_size:%u size_recv==file_size:%u sending_pos==size_recv:%u file_accepted:%u " "totalf_size:%lu size_recv:%lu sending_pos:%lu", (unsigned int)max_iterations, sendf_ok, file_recv, totalf_size == file_size, size_recv == file_size, sending_pos == size_recv, file_accepted == 1, (unsigned long)totalf_size, (unsigned long)size_recv, (unsigned long)sending_pos); printf("100MiB file sent in %lu seconds\n", (unsigned long)(time(nullptr) - f_time)); printf("Starting file streaming transfer test.\n"); file_sending_done = 0; file_accepted = 0; file_size = 0; sendf_ok = 0; size_recv = 0; file_recv = 0; tox_callback_file_recv_chunk(tox3, write_file); tox_callback_file_recv_control(tox2, file_print_control); tox_callback_file_chunk_request(tox2, tox_file_chunk_request); tox_callback_file_recv_control(tox3, file_print_control); tox_callback_file_recv(tox3, tox_file_receive); totalf_size = UINT64_MAX; fnum = tox_file_send(tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr, (const uint8_t *)"Gentoo.exe", sizeof("Gentoo.exe"), nullptr); ck_assert_msg(fnum != UINT32_MAX, "tox_new_file_sender fail"); ck_assert_msg(!tox_file_get_file_id(tox2, 1, fnum, file_cmp_id, &gfierr), "tox_file_get_file_id didn't fail"); ck_assert_msg(gfierr == TOX_ERR_FILE_GET_FRIEND_NOT_FOUND, "wrong error"); ck_assert_msg(!tox_file_get_file_id(tox2, 0, fnum + 1, file_cmp_id, &gfierr), "tox_file_get_file_id didn't fail"); ck_assert_msg(gfierr == TOX_ERR_FILE_GET_NOT_FOUND, "wrong error"); ck_assert_msg(tox_file_get_file_id(tox2, 0, fnum, file_cmp_id, &gfierr), "tox_file_get_file_id failed"); ck_assert_msg(gfierr == TOX_ERR_FILE_GET_OK, "wrong error"); max_sending = 100 * 1024; m_send_reached = 0; do { tox_iterate(tox1, nullptr); tox_iterate(tox2, nullptr); tox_iterate(tox3, nullptr); uint32_t tox1_interval = tox_iteration_interval(tox1); uint32_t tox2_interval = tox_iteration_interval(tox2); uint32_t tox3_interval = tox_iteration_interval(tox3); c_sleep(min_u32(tox1_interval, min_u32(tox2_interval, tox3_interval))); } while (!file_sending_done); ck_assert_msg(sendf_ok && file_recv && m_send_reached && totalf_size == file_size && size_recv == max_sending && sending_pos == size_recv && file_accepted == 1, "something went wrong in file transfer %u %u %u %u %u %u %u %lu %lu %lu %lu", sendf_ok, file_recv, m_send_reached, totalf_size == file_size, size_recv == max_sending, sending_pos == size_recv, file_accepted == 1, (unsigned long)totalf_size, (unsigned long)file_size, (unsigned long)size_recv, (unsigned long)sending_pos); printf("starting file 0 transfer test.\n"); file_sending_done = 0; file_accepted = 0; file_size = 0; sendf_ok = 0; size_recv = 0; file_recv = 0; tox_callback_file_recv_chunk(tox3, write_file); tox_callback_file_recv_control(tox2, file_print_control); tox_callback_file_chunk_request(tox2, tox_file_chunk_request); tox_callback_file_recv_control(tox3, file_print_control); tox_callback_file_recv(tox3, tox_file_receive); totalf_size = 0; fnum = tox_file_send(tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr, (const uint8_t *)"Gentoo.exe", sizeof("Gentoo.exe"), nullptr); ck_assert_msg(fnum != UINT32_MAX, "tox_new_file_sender fail"); ck_assert_msg(!tox_file_get_file_id(tox2, 1, fnum, file_cmp_id, &gfierr), "tox_file_get_file_id didn't fail"); ck_assert_msg(gfierr == TOX_ERR_FILE_GET_FRIEND_NOT_FOUND, "wrong error"); ck_assert_msg(!tox_file_get_file_id(tox2, 0, fnum + 1, file_cmp_id, &gfierr), "tox_file_get_file_id didn't fail"); ck_assert_msg(gfierr == TOX_ERR_FILE_GET_NOT_FOUND, "wrong error"); ck_assert_msg(tox_file_get_file_id(tox2, 0, fnum, file_cmp_id, &gfierr), "tox_file_get_file_id failed"); ck_assert_msg(gfierr == TOX_ERR_FILE_GET_OK, "wrong error"); do { uint32_t tox1_interval = tox_iteration_interval(tox1); uint32_t tox2_interval = tox_iteration_interval(tox2); uint32_t tox3_interval = tox_iteration_interval(tox3); c_sleep(min_u32(tox1_interval, min_u32(tox2_interval, tox3_interval))); tox_iterate(tox1, nullptr); tox_iterate(tox2, nullptr); tox_iterate(tox3, nullptr); } while (!file_sending_done); ck_assert_msg(sendf_ok && file_recv && totalf_size == file_size && size_recv == file_size && sending_pos == size_recv && file_accepted == 1, "something went wrong in file transfer %u %u %u %u %u %u %llu %llu %llu", sendf_ok, file_recv, totalf_size == file_size, size_recv == file_size, sending_pos == size_recv, file_accepted == 1, (unsigned long long)totalf_size, (unsigned long long)size_recv, (unsigned long long)sending_pos); printf("file_transfer_test succeeded, took %llu seconds\n", time(nullptr) - cur_time); tox_kill(tox1); tox_kill(tox2); tox_kill(tox3); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); file_transfer_test(); return 0; } c-toxcore-0.2.18/auto_tests/forwarding_test.c0000777000175000017500000002560114227324767020301 0ustar robinrobin#include #include #include #include "../toxcore/tox.h" #include "../toxcore/announce.h" #include "../testing/misc_tools.h" #include "../toxcore/mono_time.h" #include "../toxcore/forwarding.h" #include "../toxcore/net_crypto.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" #ifndef USE_IPV6 #define USE_IPV6 1 #endif static inline IP get_loopback(void) { IP ip; #if USE_IPV6 ip.family = net_family_ipv6(); ip.ip.v6 = get_ip6_loopback(); #else ip.family = net_family_ipv4(); ip.ip.v4 = get_ip4_loopback(); #endif return ip; } #define NUM_FORWARDER 20 #define NUM_FORWARDER_TCP 5 #define NUM_FORWARDER_DHT (NUM_FORWARDER - NUM_FORWARDER_TCP) #define NUM_FORWARDING_ITERATIONS 1 #define FORWARD_SEND_INTERVAL 2 #define FORWARDING_BASE_PORT 36571 typedef struct Test_Data { Networking_Core *net; uint32_t send_back; uint64_t sent; bool returned; } Test_Data; static void test_forwarded_request_cb(void *object, const IP_Port *forwarder, const uint8_t *sendback, uint16_t sendback_length, const uint8_t *data, uint16_t length, void *userdata) { Test_Data *test_data = (Test_Data *)object; uint8_t *index = (uint8_t *)userdata; if (length != 12 || memcmp("hello: ", data, 8) != 0) { printf("[%u] got unexpected data of length %d\n", *index, length); return; } uint8_t reply[12]; memcpy(reply, "reply: ", 8); memcpy(reply + 8, data + 8, 4); ck_assert_msg(forward_reply(test_data->net, forwarder, sendback, sendback_length, reply, 12), "[%u] forward_reply failed", *index); } static void test_forwarded_response_cb(void *object, const uint8_t *data, uint16_t length, void *userdata) { Test_Data *test_data = (Test_Data *)object; uint8_t *index = (uint8_t *)userdata; if (length != 12 || memcmp("reply: ", data, 8) != 0) { printf("[%u] got unexpected data of length %d\n", *index, length); return; } uint32_t send_back; net_unpack_u32(data + 8, &send_back); if (test_data->send_back == send_back) { test_data->returned = true; } } static bool all_returned(Test_Data *test_data) { for (uint32_t i = 0; i < NUM_FORWARDER; ++i) { if (!test_data[i].returned) { return false; } } return true; } typedef struct Forwarding_Subtox { Logger *log; Mono_Time *mono_time; Networking_Core *net; DHT *dht; Net_Crypto *c; Forwarding *forwarding; Announcements *announce; } Forwarding_Subtox; static Forwarding_Subtox *new_forwarding_subtox(bool no_udp, uint32_t *index, uint16_t port) { Forwarding_Subtox *subtox = (Forwarding_Subtox *)calloc(1, sizeof(Forwarding_Subtox)); ck_assert(subtox != nullptr); subtox->log = logger_new(); ck_assert(subtox->log != nullptr); logger_callback_log(subtox->log, (logger_cb *)print_debug_log, nullptr, index); subtox->mono_time = mono_time_new(nullptr, nullptr); const Random *rng= system_random(); ck_assert(rng != nullptr); const Network *ns = system_network(); ck_assert(ns != nullptr); if (no_udp) { subtox->net = new_networking_no_udp(subtox->log, ns); } else { const IP ip = get_loopback(); subtox->net = new_networking_ex(subtox->log, ns, &ip, port, port, nullptr); } subtox->dht = new_dht(subtox->log, rng, ns, subtox->mono_time, subtox->net, true, true); const TCP_Proxy_Info inf = {{{{0}}}}; subtox->c = new_net_crypto(subtox->log, rng, ns, subtox->mono_time, subtox->dht, &inf); subtox->forwarding = new_forwarding(subtox->log, rng, subtox->mono_time, subtox->dht); ck_assert(subtox->forwarding != nullptr); subtox->announce = new_announcements(subtox->log, rng, subtox->mono_time, subtox->forwarding); ck_assert(subtox->announce != nullptr); return subtox; } static void kill_forwarding_subtox(Forwarding_Subtox *subtox) { kill_announcements(subtox->announce); kill_forwarding(subtox->forwarding); kill_net_crypto(subtox->c); kill_dht(subtox->dht); kill_networking(subtox->net); mono_time_free(subtox->mono_time); logger_kill(subtox->log); free(subtox); } static void test_forwarding(void) { const Random *rng = system_random(); ck_assert(rng != nullptr); const Network *ns = system_network(); ck_assert(ns != nullptr); uint32_t index[NUM_FORWARDER]; Forwarding_Subtox *subtoxes[NUM_FORWARDER]; Test_Data test_data[NUM_FORWARDER]; const IP ip = get_loopback(); for (uint32_t i = 0; i < NUM_FORWARDER; ++i) { index[i] = i + 1; subtoxes[i] = new_forwarding_subtox(i < NUM_FORWARDER_TCP, &index[i], FORWARDING_BASE_PORT + i); test_data[i].net = subtoxes[i]->net; test_data[i].send_back = 0; test_data[i].sent = 0; test_data[i].returned = false; set_callback_forwarded_request(subtoxes[i]->forwarding, test_forwarded_request_cb, &test_data[i]); set_callback_forwarded_response(subtoxes[i]->forwarding, test_forwarded_response_cb, &test_data[i]); set_forwarding_packet_tcp_connection_callback(nc_get_tcp_c(subtoxes[i]->c), test_forwarded_response_cb, &test_data[i]); } printf("testing forwarding via tcp relays and dht\n"); struct Tox_Options *opts = tox_options_new(nullptr); uint16_t forwarder_tcp_relay_port = 36570; Tox *relay = nullptr; // Try a few different ports. for (uint8_t i = 0; i < 100; ++i) { tox_options_set_tcp_port(opts, forwarder_tcp_relay_port); relay = tox_new_log(opts, nullptr, nullptr); if (relay != nullptr) { break; } ++forwarder_tcp_relay_port; } tox_options_free(opts); ck_assert_msg(relay != nullptr, "Failed to create TCP relay"); IP_Port relay_ipport_tcp = {ip, net_htons(forwarder_tcp_relay_port)}; uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(relay, dpk); printf("1-%d connected only to TCP server; %d-%d connected only to DHT\n", NUM_FORWARDER_TCP, NUM_FORWARDER_TCP + 1, NUM_FORWARDER); for (uint32_t i = 0; i < NUM_FORWARDER_TCP; ++i) { set_tcp_onion_status(nc_get_tcp_c(subtoxes[i]->c), 1); ck_assert_msg(add_tcp_relay(subtoxes[i]->c, &relay_ipport_tcp, dpk) == 0, "Failed to add TCP relay"); } IP_Port relay_ipport_udp = {ip, net_htons(tox_self_get_udp_port(relay, nullptr))}; for (uint32_t i = NUM_FORWARDER_TCP; i < NUM_FORWARDER; ++i) { dht_bootstrap(subtoxes[i]->dht, &relay_ipport_udp, dpk); } printf("allowing DHT to populate\n"); uint16_t dht_establish_iterations = NUM_FORWARDER * 5; for (uint32_t n = 0; n < NUM_FORWARDING_ITERATIONS; ++n) { for (uint32_t i = 0; i < NUM_FORWARDER; ++i) { test_data[i].sent = 0; test_data[i].returned = false; } do { for (uint32_t i = 0; i < NUM_FORWARDER; ++i) { Forwarding_Subtox *const subtox = subtoxes[i]; mono_time_update(subtox->mono_time); networking_poll(subtox->net, &index[i]); do_net_crypto(subtox->c, &index[i]); do_dht(subtox->dht); if (dht_establish_iterations || test_data[i].returned || !mono_time_is_timeout(subtox->mono_time, test_data[i].sent, FORWARD_SEND_INTERVAL)) { continue; } printf("%u", i + 1); if (i < NUM_FORWARDER_TCP) { printf(" --> TCPRelay"); } const uint16_t chain_length = i < NUM_FORWARDER_TCP ? i % 5 : i % 4 + 1; uint8_t chain_keys[4 * CRYPTO_PUBLIC_KEY_SIZE]; uint32_t chain_i = NUM_FORWARDER_TCP + (random_u32(rng) % NUM_FORWARDER_DHT); const IP_Port first_ipp = {ip, net_htons(FORWARDING_BASE_PORT + chain_i)}; printf(" --> %u", chain_i + 1); for (uint16_t j = 0; j < chain_length; ++j) { // pick random different dht node: chain_i += 1 + random_u32(rng) % (NUM_FORWARDER_DHT - 1); chain_i = NUM_FORWARDER_TCP + (chain_i - NUM_FORWARDER_TCP) % NUM_FORWARDER_DHT; const uint8_t *dest_pubkey = dht_get_self_public_key(subtoxes[chain_i]->dht); memcpy(chain_keys + j * CRYPTO_PUBLIC_KEY_SIZE, dest_pubkey, CRYPTO_PUBLIC_KEY_SIZE); printf(" --> %u", chain_i + 1); } printf("\n"); const uint16_t length = 12; uint8_t data[12]; memcpy(data, "hello: ", 8); test_data[i].send_back = random_u32(rng); net_pack_u32(data + 8, test_data[i].send_back); if (i < NUM_FORWARDER_TCP) { IP_Port tcp_forwarder; if (!get_random_tcp_conn_ip_port(subtox->c, &tcp_forwarder)) { continue; } if (send_tcp_forward_request(subtox->log, subtox->c, &tcp_forwarder, &first_ipp, chain_keys, chain_length, data, length) == 0) { test_data[i].sent = mono_time_get(subtox->mono_time); } } else { if (send_forward_request(subtox->net, &first_ipp, chain_keys, chain_length, data, length)) { test_data[i].sent = mono_time_get(subtox->mono_time); } } } tox_iterate(relay, nullptr); if (dht_establish_iterations) { --dht_establish_iterations; if (!dht_establish_iterations) { printf("making forward requests and expecting replies\n"); } } c_sleep(50); } while (!all_returned(test_data)); // This doesn't really belong in this test. // It can be removed once the full announce client test is in place. printf("checking that nodes are marked as announce nodes\n"); Node_format nodes[MAX_SENT_NODES]; ck_assert(NUM_FORWARDER - NUM_FORWARDER_TCP > 1); for (uint32_t i = NUM_FORWARDER_TCP; i < NUM_FORWARDER; ++i) { ck_assert_msg(get_close_nodes(subtoxes[i]->dht, dht_get_self_public_key(subtoxes[i]->dht), nodes, net_family_unspec(), true, true) > 0, "node %u has no nodes marked as announce nodes", i); } } for (uint32_t i = 0; i < NUM_FORWARDER; ++i) { kill_forwarding_subtox(subtoxes[i]); } tox_kill(relay); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_forwarding(); return 0; } c-toxcore-0.2.18/auto_tests/friend_connection_test.c0000777000175000017500000000120514227324767021617 0ustar robinrobin/* Tests that we can make a friend connection. * * This is the simplest test that brings up two toxes that can talk to each * other. It's useful as a copy/pasteable starting point for testing other * features. */ #include #include "auto_test_support.h" static void friend_connection_test(AutoTox *toxes) { // Nothing to do here. When copying this test, add test-specific code here. } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; run_auto_test(nullptr, 2, friend_connection_test, 0, &options); return 0; } c-toxcore-0.2.18/auto_tests/friend_request_spam_test.c0000777000175000017500000000442114227324767022173 0ustar robinrobin/* Tests what happens when spamming friend requests from lots of temporary toxes. */ #include #include #include #include #include "../toxcore/ccompat.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" #include "../testing/misc_tools.h" #include "auto_test_support.h" #include "check_compat.h" #define FR_MESSAGE "Gentoo" // TODO(iphydf): Investigate friend request spam: receiving more than 32 at a time means any further // friend requests are dropped on the floor and aren't seen again. #define FR_TOX_COUNT 33 typedef struct State { bool unused; } State; static void accept_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) { ck_assert_msg(length == sizeof(FR_MESSAGE) && memcmp(FR_MESSAGE, data, sizeof(FR_MESSAGE)) == 0, "unexpected friend request message"); tox_friend_add_norequest(tox, public_key, nullptr); } static void test_friend_request(AutoTox *autotoxes) { const time_t con_time = time(nullptr); printf("All toxes add tox1 as friend.\n"); tox_callback_friend_request(autotoxes[0].tox, accept_friend_request); uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(autotoxes[0].tox, address); for (uint32_t i = 2; i < FR_TOX_COUNT; ++i) { Tox_Err_Friend_Add err; tox_friend_add(autotoxes[i].tox, address, (const uint8_t *)FR_MESSAGE, sizeof(FR_MESSAGE), &err); ck_assert_msg(err == TOX_ERR_FRIEND_ADD_OK, "tox %u failed to add friend error code: %d", autotoxes[i].index, err); } for (uint32_t t = 0; t < 100; ++t) { if (all_friends_connected(autotoxes, FR_TOX_COUNT)) { break; } iterate_all_wait(autotoxes, FR_TOX_COUNT, ITERATION_INTERVAL); } const size_t size = tox_self_get_friend_list_size(autotoxes[0].tox); printf("Tox clients connected took %lu seconds; tox1 has %u friends.\n", (unsigned long)(time(nullptr) - con_time), (unsigned int)size); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; run_auto_test(nullptr, FR_TOX_COUNT, test_friend_request, sizeof(State), &options); return 0; } c-toxcore-0.2.18/auto_tests/friend_request_test.c0000777000175000017500000000533014227324767021153 0ustar robinrobin/* Tests that we can add friends. */ #include #include #include #include #include "../toxcore/ccompat.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" #include "../testing/misc_tools.h" #include "auto_test_support.h" #include "check_compat.h" #define FR_MESSAGE "Gentoo" static void accept_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) { ck_assert_msg(length == sizeof(FR_MESSAGE) && memcmp(FR_MESSAGE, data, sizeof(FR_MESSAGE)) == 0, "unexpected friend request message"); tox_friend_add_norequest(tox, public_key, nullptr); } static void test_friend_request(void) { printf("Initialising 2 toxes.\n"); uint32_t index[] = { 1, 2 }; const time_t cur_time = time(nullptr); Tox *const tox1 = tox_new_log(nullptr, nullptr, &index[0]); Tox *const tox2 = tox_new_log(nullptr, nullptr, &index[1]); ck_assert_msg(tox1 && tox2, "failed to create 2 tox instances"); printf("Bootstrapping tox2 off tox1.\n"); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(tox1, dht_key); const uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr); tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr); do { tox_iterate(tox1, nullptr); tox_iterate(tox2, nullptr); c_sleep(ITERATION_INTERVAL); } while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE || tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE); printf("Toxes are online, took %lu seconds.\n", (unsigned long)(time(nullptr) - cur_time)); const time_t con_time = time(nullptr); printf("Tox1 adds tox2 as friend, tox2 accepts.\n"); tox_callback_friend_request(tox2, accept_friend_request); uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(tox2, address); const uint32_t test = tox_friend_add(tox1, address, (const uint8_t *)FR_MESSAGE, sizeof(FR_MESSAGE), nullptr); ck_assert_msg(test == 0, "failed to add friend error code: %u", test); do { tox_iterate(tox1, nullptr); tox_iterate(tox2, nullptr); c_sleep(ITERATION_INTERVAL); } while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP || tox_friend_get_connection_status(tox2, 0, nullptr) != TOX_CONNECTION_UDP); printf("Tox clients connected took %lu seconds.\n", (unsigned long)(time(nullptr) - con_time)); printf("friend_request_test succeeded, took %lu seconds.\n", (unsigned long)(time(nullptr) - cur_time)); tox_kill(tox1); tox_kill(tox2); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_friend_request(); return 0; } c-toxcore-0.2.18/auto_tests/invalid_tcp_proxy_test.c0000777000175000017500000000312014227324767021664 0ustar robinrobin// Test to make sure that when UDP is disabled, and we set an invalid proxy, // i.e. one that doesn't run a proxy server, then we don't get any connection. #include #include "../testing/misc_tools.h" #include "auto_test_support.h" #include "check_compat.h" static uint8_t const key[] = { 0x15, 0xE9, 0xC3, 0x09, 0xCF, 0xCB, 0x79, 0xFD, 0xDF, 0x0E, 0xBA, 0x05, 0x7D, 0xAB, 0xB4, 0x9F, 0xE1, 0x5F, 0x38, 0x03, 0xB1, 0xBF, 0xF0, 0x65, 0x36, 0xAE, 0x2E, 0x5B, 0xA5, 0xE4, 0x69, 0x0E, }; // Try to bootstrap for 30 seconds. #define NUM_ITERATIONS (unsigned)(30.0 / (ITERATION_INTERVAL / 1000.0)) int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); struct Tox_Options *opts = tox_options_new(nullptr); tox_options_set_udp_enabled(opts, false); tox_options_set_proxy_type(opts, TOX_PROXY_TYPE_SOCKS5); tox_options_set_proxy_host(opts, "localhost"); tox_options_set_proxy_port(opts, 51724); Tox *tox = tox_new_log(opts, nullptr, nullptr); tox_options_free(opts); tox_add_tcp_relay(tox, "tox.ngc.zone", 33445, key, nullptr); tox_bootstrap(tox, "tox.ngc.zone", 33445, key, nullptr); printf("Waiting for connection...\n"); for (uint16_t i = 0; i < NUM_ITERATIONS; i++) { tox_iterate(tox, nullptr); c_sleep(ITERATION_INTERVAL); // None of the iterations should have a connection. const Tox_Connection status = tox_self_get_connection_status(tox); ck_assert_msg(status == TOX_CONNECTION_NONE, "unexpectedly got a connection (%d)", status); } tox_kill(tox); return 0; } c-toxcore-0.2.18/auto_tests/invalid_udp_proxy_test.c0000777000175000017500000000304014227324767021667 0ustar robinrobin// Test that if UDP is enabled, and a proxy is provided that does not support // UDP proxying, we disable UDP. #include #include "../testing/misc_tools.h" #include "auto_test_support.h" #include "check_compat.h" static uint8_t const key[] = { 0x15, 0xE9, 0xC3, 0x09, 0xCF, 0xCB, 0x79, 0xFD, 0xDF, 0x0E, 0xBA, 0x05, 0x7D, 0xAB, 0xB4, 0x9F, 0xE1, 0x5F, 0x38, 0x03, 0xB1, 0xBF, 0xF0, 0x65, 0x36, 0xAE, 0x2E, 0x5B, 0xA5, 0xE4, 0x69, 0x0E, }; // Try to bootstrap for 30 seconds. #define NUM_ITERATIONS (unsigned)(30.0 / (ITERATION_INTERVAL / 1000.0)) int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); struct Tox_Options *opts = tox_options_new(nullptr); tox_options_set_udp_enabled(opts, true); tox_options_set_proxy_type(opts, TOX_PROXY_TYPE_SOCKS5); tox_options_set_proxy_host(opts, "localhost"); tox_options_set_proxy_port(opts, 51724); Tox *tox = tox_new_log(opts, nullptr, nullptr); tox_options_free(opts); tox_add_tcp_relay(tox, "tox.ngc.zone", 33445, key, nullptr); tox_bootstrap(tox, "tox.ngc.zone", 33445, key, nullptr); printf("Waiting for connection..."); for (uint16_t i = 0; i < NUM_ITERATIONS; i++) { tox_iterate(tox, nullptr); c_sleep(ITERATION_INTERVAL); // None of the iterations should have a connection. const Tox_Connection status = tox_self_get_connection_status(tox); ck_assert_msg(status == TOX_CONNECTION_NONE, "unexpectedly got a connection (%d)", status); } tox_kill(tox); return 0; } c-toxcore-0.2.18/auto_tests/lan_discovery_test.c0000777000175000017500000000277314227324767021005 0ustar robinrobin#include #include #include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" #include "../toxcore/tox_struct.h" #include "auto_test_support.h" static uint64_t get_state_clock_callback(void *user_data) { const uint64_t *clock = (const uint64_t *)user_data; return *clock; } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Tox *tox1 = tox_new_log_lan(nullptr, nullptr, nullptr, /* lan_discovery */true); Tox *tox2 = tox_new_log_lan(nullptr, nullptr, nullptr, /* lan_discovery */true); ck_assert(tox1 != nullptr); ck_assert(tox2 != nullptr); uint64_t clock = current_time_monotonic(tox1->mono_time); Mono_Time *mono_time; mono_time = tox1->mono_time; mono_time_set_current_time_callback(mono_time, get_state_clock_callback, &clock); mono_time = tox2->mono_time; mono_time_set_current_time_callback(mono_time, get_state_clock_callback, &clock); printf("Waiting for LAN discovery. This loop will attempt to run until successful."); do { printf("."); fflush(stdout); tox_iterate(tox1, nullptr); tox_iterate(tox2, nullptr); c_sleep(5); clock += 100; } while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE || tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE); printf(" %d <-> %d\n", tox_self_get_connection_status(tox1), tox_self_get_connection_status(tox2)); tox_kill(tox2); tox_kill(tox1); return 0; } c-toxcore-0.2.18/auto_tests/lossless_packet_test.c0000777000175000017500000000407414227324767021336 0ustar robinrobin/* Tests that we can send lossless packets. */ #include #include #include #include #include "../testing/misc_tools.h" #include "../toxcore/util.h" #include "check_compat.h" typedef struct State { bool custom_packet_received; } State; #include "auto_test_support.h" #define LOSSLESS_PACKET_FILLER 160 static void handle_lossless_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data) { uint8_t *cmp_packet = (uint8_t *)malloc(tox_max_custom_packet_size()); ck_assert(cmp_packet != nullptr); memset(cmp_packet, LOSSLESS_PACKET_FILLER, tox_max_custom_packet_size()); if (length == tox_max_custom_packet_size() && memcmp(data, cmp_packet, tox_max_custom_packet_size()) == 0) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; state->custom_packet_received = true; } free(cmp_packet); } static void test_lossless_packet(AutoTox *autotoxes) { tox_callback_friend_lossless_packet(autotoxes[1].tox, &handle_lossless_packet); const size_t packet_size = tox_max_custom_packet_size() + 1; uint8_t *packet = (uint8_t *)malloc(packet_size); ck_assert(packet != nullptr); memset(packet, LOSSLESS_PACKET_FILLER, packet_size); bool ret = tox_friend_send_lossless_packet(autotoxes[0].tox, 0, packet, packet_size, nullptr); ck_assert_msg(ret == false, "should not be able to send custom packets this big %i", ret); ret = tox_friend_send_lossless_packet(autotoxes[0].tox, 0, packet, tox_max_custom_packet_size(), nullptr); ck_assert_msg(ret == true, "tox_friend_send_lossless_packet fail %i", ret); free(packet); do { iterate_all_wait(autotoxes, 2, ITERATION_INTERVAL); } while (!((State *)autotoxes[1].state)->custom_packet_received); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; run_auto_test(nullptr, 2, test_lossless_packet, sizeof(State), &options); return 0; } c-toxcore-0.2.18/auto_tests/lossy_packet_test.c0000777000175000017500000000403014227324767020630 0ustar robinrobin/* Tests that we can send lossy packets. */ #include #include #include #include #include "../testing/misc_tools.h" #include "../toxcore/util.h" #include "check_compat.h" typedef struct State { bool custom_packet_received; } State; #include "auto_test_support.h" #define LOSSY_PACKET_FILLER 200 static void handle_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data) { uint8_t *cmp_packet = (uint8_t *)malloc(tox_max_custom_packet_size()); ck_assert(cmp_packet != nullptr); memset(cmp_packet, LOSSY_PACKET_FILLER, tox_max_custom_packet_size()); if (length == tox_max_custom_packet_size() && memcmp(data, cmp_packet, tox_max_custom_packet_size()) == 0) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; state->custom_packet_received = true; } free(cmp_packet); } static void test_lossy_packet(AutoTox *autotoxes) { tox_callback_friend_lossy_packet(autotoxes[1].tox, &handle_lossy_packet); const size_t packet_size = tox_max_custom_packet_size() + 1; uint8_t *packet = (uint8_t *)malloc(packet_size); ck_assert(packet != nullptr); memset(packet, LOSSY_PACKET_FILLER, packet_size); bool ret = tox_friend_send_lossy_packet(autotoxes[0].tox, 0, packet, packet_size, nullptr); ck_assert_msg(ret == false, "should not be able to send custom packets this big %i", ret); ret = tox_friend_send_lossy_packet(autotoxes[0].tox, 0, packet, tox_max_custom_packet_size(), nullptr); ck_assert_msg(ret == true, "tox_friend_send_lossy_packet fail %i", ret); free(packet); do { iterate_all_wait(autotoxes, 2, ITERATION_INTERVAL); } while (!((State *)autotoxes[1].state)->custom_packet_received); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; run_auto_test(nullptr, 2, test_lossy_packet, sizeof(State), &options); return 0; } c-toxcore-0.2.18/auto_tests/Makefile.inc0000777000175000017500000001723714227324767017152 0ustar robinrobinif BUILD_TESTS noinst_LTLIBRARIES += libauto_test_support.la libauto_test_support_la_SOURCES = ../auto_tests/auto_test_support.c ../auto_tests/auto_test_support.h libauto_test_support_la_LIBADD = libmisc_tools.la libtoxcore.la TESTS = \ announce_test \ conference_double_invite_test \ conference_invite_merge_test \ conference_peer_nick_test \ conference_simple_test \ conference_test \ conference_two_test \ crypto_test \ file_transfer_test \ forwarding_test \ friend_connection_test \ friend_request_test \ invalid_tcp_proxy_test \ invalid_udp_proxy_test \ lan_discovery_test \ lossless_packet_test \ lossy_packet_test \ network_test \ onion_test \ overflow_recvq_test \ overflow_sendq_test \ reconnect_test \ save_compatibility_test \ save_friend_test \ send_message_test \ set_name_test \ set_status_message_test \ TCP_test \ tox_events_test \ tox_dispatch_test \ tox_many_tcp_test \ tox_many_test \ tox_strncasecmp_test \ typing_test \ version_test if !WITH_NACL TESTS += \ encryptsave_test \ file_saving_test endif AUTOTEST_CFLAGS = \ $(LIBSODIUM_CFLAGS) \ $(NACL_CFLAGS) AUTOTEST_LDADD = \ $(LIBSODIUM_LDFLAGS) \ $(NACL_LDFLAGS) \ libmisc_tools.la \ libauto_test_support.la \ libtoxcore.la \ libtoxencryptsave.la \ $(LIBSODIUM_LIBS) \ $(NACL_OBJECTS) \ $(NACL_LIBS) if BUILD_AV TESTS += conference_av_test toxav_basic_test toxav_many_test AUTOTEST_LDADD += libtoxav.la endif check_PROGRAMS = $(TESTS) announce_test_SOURCES = ../auto_tests/announce_test.c announce_test_CFLAGS = $(AUTOTEST_CFLAGS) announce_test_LDADD = $(AUTOTEST_LDADD) conference_double_invite_test_SOURCES = ../auto_tests/conference_double_invite_test.c conference_double_invite_test_CFLAGS = $(AUTOTEST_CFLAGS) conference_double_invite_test_LDADD = $(AUTOTEST_LDADD) conference_invite_merge_test_SOURCES = ../auto_tests/conference_invite_merge_test.c conference_invite_merge_test_CFLAGS = $(AUTOTEST_CFLAGS) conference_invite_merge_test_LDADD = $(AUTOTEST_LDADD) conference_peer_nick_test_SOURCES = ../auto_tests/conference_peer_nick_test.c conference_peer_nick_test_CFLAGS = $(AUTOTEST_CFLAGS) conference_peer_nick_test_LDADD = $(AUTOTEST_LDADD) conference_simple_test_SOURCES = ../auto_tests/conference_simple_test.c conference_simple_test_CFLAGS = $(AUTOTEST_CFLAGS) conference_simple_test_LDADD = $(AUTOTEST_LDADD) conference_test_SOURCES = ../auto_tests/conference_test.c conference_test_CFLAGS = $(AUTOTEST_CFLAGS) conference_test_LDADD = $(AUTOTEST_LDADD) conference_two_test_SOURCES = ../auto_tests/conference_two_test.c conference_two_test_CFLAGS = $(AUTOTEST_CFLAGS) conference_two_test_LDADD = $(AUTOTEST_LDADD) crypto_test_SOURCES = ../auto_tests/crypto_test.c crypto_test_CFLAGS = $(AUTOTEST_CFLAGS) crypto_test_LDADD = $(AUTOTEST_LDADD) encryptsave_test_SOURCES = ../auto_tests/encryptsave_test.c encryptsave_test_CFLAGS = $(AUTOTEST_CFLAGS) encryptsave_test_LDADD = $(AUTOTEST_LDADD) file_saving_test_SOURCES = ../auto_tests/file_saving_test.c file_saving_test_CFLAGS = $(AUTOTEST_CFLAGS) file_saving_test_LDADD = $(AUTOTEST_LDADD) file_transfer_test_SOURCES = ../auto_tests/file_transfer_test.c file_transfer_test_CFLAGS = $(AUTOTEST_CFLAGS) file_transfer_test_LDADD = $(AUTOTEST_LDADD) forwarding_test_SOURCES = ../auto_tests/forwarding_test.c forwarding_test_CFLAGS = $(AUTOTEST_CFLAGS) forwarding_test_LDADD = $(AUTOTEST_LDADD) friend_connection_test_SOURCES = ../auto_tests/friend_connection_test.c friend_connection_test_CFLAGS = $(AUTOTEST_CFLAGS) friend_connection_test_LDADD = $(AUTOTEST_LDADD) friend_request_test_SOURCES = ../auto_tests/friend_request_test.c friend_request_test_CFLAGS = $(AUTOTEST_CFLAGS) friend_request_test_LDADD = $(AUTOTEST_LDADD) invalid_tcp_proxy_test_SOURCES = ../auto_tests/invalid_tcp_proxy_test.c invalid_tcp_proxy_test_CFLAGS = $(AUTOTEST_CFLAGS) invalid_tcp_proxy_test_LDADD = $(AUTOTEST_LDADD) invalid_udp_proxy_test_SOURCES = ../auto_tests/invalid_udp_proxy_test.c invalid_udp_proxy_test_CFLAGS = $(AUTOTEST_CFLAGS) invalid_udp_proxy_test_LDADD = $(AUTOTEST_LDADD) lan_discovery_test_SOURCES = ../auto_tests/lan_discovery_test.c lan_discovery_test_CFLAGS = $(AUTOTEST_CFLAGS) lan_discovery_test_LDADD = $(AUTOTEST_LDADD) lossless_packet_test_SOURCES = ../auto_tests/lossless_packet_test.c lossless_packet_test_CFLAGS = $(AUTOTEST_CFLAGS) lossless_packet_test_LDADD = $(AUTOTEST_LDADD) lossy_packet_test_SOURCES = ../auto_tests/lossy_packet_test.c lossy_packet_test_CFLAGS = $(AUTOTEST_CFLAGS) lossy_packet_test_LDADD = $(AUTOTEST_LDADD) network_test_SOURCES = ../auto_tests/network_test.c network_test_CFLAGS = $(AUTOTEST_CFLAGS) network_test_LDADD = $(AUTOTEST_LDADD) onion_test_SOURCES = ../auto_tests/onion_test.c onion_test_CFLAGS = $(AUTOTEST_CFLAGS) onion_test_LDADD = $(AUTOTEST_LDADD) overflow_recvq_test_SOURCES = ../auto_tests/overflow_recvq_test.c overflow_recvq_test_CFLAGS = $(AUTOTEST_CFLAGS) overflow_recvq_test_LDADD = $(AUTOTEST_LDADD) overflow_sendq_test_SOURCES = ../auto_tests/overflow_sendq_test.c overflow_sendq_test_CFLAGS = $(AUTOTEST_CFLAGS) overflow_sendq_test_LDADD = $(AUTOTEST_LDADD) reconnect_test_SOURCES = ../auto_tests/reconnect_test.c reconnect_test_CFLAGS = $(AUTO_TEST_CFLAGS) reconnect_test_LDADD = $(AUTOTEST_LDADD) save_compatibility_test_SOURCES = ../auto_tests/save_compatibility_test.c save_compatibility_test_CFLAGS = $(AUTOTEST_CFLAGS) save_compatibility_test_LDADD = $(AUTOTEST_LDADD) save_friend_test_SOURCES = ../auto_tests/save_friend_test.c save_friend_test_CFLAGS = $(AUTOTEST_CFLAGS) save_friend_test_LDADD = $(AUTOTEST_LDADD) send_message_test_SOURCES = ../auto_tests/send_message_test.c send_message_test_CFLAGS = $(AUTOTEST_CFLAGS) send_message_test_LDADD = $(AUTOTEST_LDADD) set_name_test_SOURCES = ../auto_tests/set_name_test.c set_name_test_CFLAGS = $(AUTOTEST_CFLAGS) set_name_test_LDADD = $(AUTOTEST_LDADD) set_status_message_test_SOURCES = ../auto_tests/set_status_message_test.c set_status_message_test_CFLAGS = $(AUTOTEST_CFLAGS) set_status_message_test_LDADD = $(AUTOTEST_LDADD) TCP_test_SOURCES = ../auto_tests/TCP_test.c TCP_test_CFLAGS = $(AUTOTEST_CFLAGS) TCP_test_LDADD = $(AUTOTEST_LDADD) tox_events_test_SOURCES = ../auto_tests/tox_events_test.c tox_events_test_CFLAGS = $(AUTOTEST_CFLAGS) tox_events_test_LDADD = $(AUTOTEST_LDADD) tox_dispatch_test_SOURCES = ../auto_tests/tox_dispatch_test.c tox_dispatch_test_CFLAGS = $(AUTOTEST_CFLAGS) tox_dispatch_test_LDADD = $(AUTOTEST_LDADD) tox_many_tcp_test_SOURCES = ../auto_tests/tox_many_tcp_test.c tox_many_tcp_test_CFLAGS = $(AUTOTEST_CFLAGS) tox_many_tcp_test_LDADD = $(AUTOTEST_LDADD) tox_many_test_SOURCES = ../auto_tests/tox_many_test.c tox_many_test_CFLAGS = $(AUTOTEST_CFLAGS) tox_many_test_LDADD = $(AUTOTEST_LDADD) tox_strncasecmp_test_SOURCES = ../auto_tests/tox_strncasecmp_test.c tox_strncasecmp_test_CFLAGS = $(AUTOTEST_CFLAGS) tox_strncasecmp_test_LDADD = $(AUTOTEST_LDADD) typing_test_SOURCES = ../auto_tests/typing_test.c typing_test_CFLAGS = $(AUTOTEST_CFLAGS) typing_test_LDADD = $(AUTOTEST_LDADD) version_test_SOURCES = ../auto_tests/version_test.c version_test_CFLAGS = $(AUTOTEST_CFLAGS) version_test_LDADD = $(AUTOTEST_LDADD) if BUILD_AV conference_av_test_SOURCES = ../auto_tests/conference_av_test.c conference_av_test_CFLAGS = $(AUTOTEST_CFLAGS) conference_av_test_LDADD = $(AUTOTEST_LDADD) toxav_basic_test_SOURCES = ../auto_tests/toxav_basic_test.c toxav_basic_test_CFLAGS = $(AUTOTEST_CFLAGS) toxav_basic_test_LDADD = $(AUTOTEST_LDADD) $(AV_LIBS) toxav_many_test_SOURCES = ../auto_tests/toxav_many_test.c toxav_many_test_CFLAGS = $(AUTOTEST_CFLAGS) toxav_many_test_LDADD = $(AUTOTEST_LDADD) endif endif EXTRA_DIST += \ $(top_srcdir)/auto_tests/data/save.tox \ $(top_srcdir)/auto_tests/check_compat.h \ $(top_srcdir)/auto_tests/auto_test_support.h c-toxcore-0.2.18/auto_tests/network_test.c0000777000175000017500000001333714227324767017633 0ustar robinrobin#include #include #include "../testing/misc_tools.h" #include "../toxcore/network.h" #include "check_compat.h" #ifndef USE_IPV6 #define USE_IPV6 1 #endif static void test_addr_resolv_localhost(void) { #ifdef __CYGWIN__ /* force initialization of network stack * normally this should happen automatically * cygwin doesn't do it for every network related function though * e.g. not for getaddrinfo... */ net_socket(0, 0, 0); errno = 0; #endif const Network *ns = system_network(); ck_assert(ns != nullptr); const char localhost[] = "localhost"; IP ip; ip_init(&ip, 0); // ipv6enabled = 0 bool res = addr_resolve_or_parse_ip(ns, localhost, &ip, nullptr); int error = net_error(); char *strerror = net_new_strerror(error); ck_assert_msg(res, "Resolver failed: %d, %s", error, strerror); net_kill_strerror(strerror); Ip_Ntoa ip_str; ck_assert_msg(net_family_is_ipv4(ip.family), "Expected family TOX_AF_INET, got %u.", ip.family.value); const uint32_t loopback = get_ip4_loopback().uint32; ck_assert_msg(ip.ip.v4.uint32 == loopback, "Expected 127.0.0.1, got %s.", net_ip_ntoa(&ip, &ip_str)); ip_init(&ip, 1); // ipv6enabled = 1 res = addr_resolve_or_parse_ip(ns, localhost, &ip, nullptr); #if USE_IPV6 int localhost_split = 0; if (!net_family_is_ipv6(ip.family)) { res = addr_resolve_or_parse_ip(ns, "ip6-localhost", &ip, nullptr); localhost_split = 1; } error = net_error(); strerror = net_new_strerror(error); ck_assert_msg(res, "Resolver failed: %d, %s", error, strerror); net_kill_strerror(strerror); ck_assert_msg(net_family_is_ipv6(ip.family), "Expected family TOX_AF_INET6 (%d), got %u.", TOX_AF_INET6, ip.family.value); IP6 ip6_loopback = get_ip6_loopback(); ck_assert_msg(!memcmp(&ip.ip.v6, &ip6_loopback, sizeof(IP6)), "Expected ::1, got %s.", net_ip_ntoa(&ip, &ip_str)); if (localhost_split) { printf("Localhost seems to be split in two.\n"); return; } #endif ip_init(&ip, 1); // ipv6enabled = 1 ip.family = net_family_unspec(); IP extra; ip_reset(&extra); res = addr_resolve_or_parse_ip(ns, localhost, &ip, &extra); error = net_error(); strerror = net_new_strerror(error); ck_assert_msg(res, "Resolver failed: %d, %s", error, strerror); net_kill_strerror(strerror); #if USE_IPV6 ck_assert_msg(net_family_is_ipv6(ip.family), "Expected family TOX_AF_INET6 (%d), got %u.", TOX_AF_INET6, ip.family.value); ck_assert_msg(!memcmp(&ip.ip.v6, &ip6_loopback, sizeof(IP6)), "Expected ::1, got %s.", net_ip_ntoa(&ip, &ip_str)); ck_assert_msg(net_family_is_ipv4(extra.family), "Expected family TOX_AF_INET (%d), got %u.", TOX_AF_INET, extra.family.value); ck_assert_msg(extra.ip.v4.uint32 == loopback, "Expected 127.0.0.1, got %s.", net_ip_ntoa(&ip, &ip_str)); #elif 0 // TODO(iphydf): Fix this to work on IPv6-supporting systems. ck_assert_msg(net_family_is_ipv4(ip.family), "Expected family TOX_AF_INET (%d), got %u.", TOX_AF_INET, ip.family.value); ck_assert_msg(ip.ip.v4.uint32 == loopback, "Expected 127.0.0.1, got %s.", net_ip_ntoa(&ip, &ip_str)); #endif } static void test_ip_equal(void) { int res; IP ip1, ip2; ip_reset(&ip1); ip_reset(&ip2); res = ip_equal(nullptr, nullptr); ck_assert_msg(res == 0, "ip_equal(NULL, NULL): expected result 0, got %d.", res); res = ip_equal(&ip1, nullptr); ck_assert_msg(res == 0, "ip_equal(PTR, NULL): expected result 0, got %d.", res); res = ip_equal(nullptr, &ip1); ck_assert_msg(res == 0, "ip_equal(NULL, PTR): expected result 0, got %d.", res); ip1.family = net_family_ipv4(); ip1.ip.v4.uint32 = net_htonl(0x7F000001); res = ip_equal(&ip1, &ip2); ck_assert_msg(res == 0, "ip_equal( {TOX_AF_INET, 127.0.0.1}, {TOX_AF_UNSPEC, 0} ): " "expected result 0, got %d.", res); ip2.family = net_family_ipv4(); ip2.ip.v4.uint32 = net_htonl(0x7F000001); res = ip_equal(&ip1, &ip2); ck_assert_msg(res != 0, "ip_equal( {TOX_AF_INET, 127.0.0.1}, {TOX_AF_INET, 127.0.0.1} ): " "expected result != 0, got 0."); ip2.ip.v4.uint32 = net_htonl(0x7F000002); res = ip_equal(&ip1, &ip2); ck_assert_msg(res == 0, "ip_equal( {TOX_AF_INET, 127.0.0.1}, {TOX_AF_INET, 127.0.0.2} ): " "expected result 0, got %d.", res); ip2.family = net_family_ipv6(); ip2.ip.v6.uint32[0] = 0; ip2.ip.v6.uint32[1] = 0; ip2.ip.v6.uint32[2] = net_htonl(0xFFFF); ip2.ip.v6.uint32[3] = net_htonl(0x7F000001); ck_assert_msg(ipv6_ipv4_in_v6(&ip2.ip.v6) != 0, "ipv6_ipv4_in_v6(::ffff:127.0.0.1): expected != 0, got 0."); res = ip_equal(&ip1, &ip2); ck_assert_msg(res != 0, "ip_equal( {TOX_AF_INET, 127.0.0.1}, {TOX_AF_INET6, ::ffff:127.0.0.1} ): " "expected result != 0, got 0."); IP6 ip6_loopback = get_ip6_loopback(); memcpy(&ip2.ip.v6, &ip6_loopback, sizeof(IP6)); res = ip_equal(&ip1, &ip2); ck_assert_msg(res == 0, "ip_equal( {TOX_AF_INET, 127.0.0.1}, {TOX_AF_INET6, ::1} ): expected result 0, got %d.", res); memcpy(&ip1, &ip2, sizeof(IP)); res = ip_equal(&ip1, &ip2); ck_assert_msg(res != 0, "ip_equal( {TOX_AF_INET6, ::1}, {TOX_AF_INET6, ::1} ): expected result != 0, got 0."); ip2.ip.v6.uint8[15]++; res = ip_equal(&ip1, &ip2); ck_assert_msg(res == 0, "ip_equal( {TOX_AF_INET6, ::1}, {TOX_AF_INET6, ::2} ): expected result 0, got %d.", res); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_addr_resolv_localhost(); test_ip_equal(); return 0; } c-toxcore-0.2.18/auto_tests/onion_test.c0000777000175000017500000004571214227324767017266 0ustar robinrobin#include #include #include "../testing/misc_tools.h" #include "../toxcore/mono_time.h" #include "../toxcore/onion.h" #include "../toxcore/onion_announce.h" #include "../toxcore/onion_client.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" #ifndef USE_IPV6 #define USE_IPV6 1 #endif static inline IP get_loopback(void) { IP ip; #if USE_IPV6 ip.family = net_family_ipv6(); ip.ip.v6 = get_ip6_loopback(); #else ip.family = net_family_ipv4(); ip.ip.v4 = get_ip4_loopback(); #endif return ip; } static void do_onion(Mono_Time *mono_time, Onion *onion) { mono_time_update(mono_time); networking_poll(onion->net, nullptr); do_dht(onion->dht); } static int handled_test_1; static int handle_test_1(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { Onion *onion = (Onion *)object; const char req_message[] = "Install Gentoo"; uint8_t req_packet[1 + sizeof(req_message)]; req_packet[0] = NET_PACKET_ANNOUNCE_REQUEST_OLD; memcpy(req_packet + 1, req_message, sizeof(req_message)); if (memcmp(packet, req_packet, sizeof(req_packet)) != 0) { return 1; } const char res_message[] = "install gentoo"; uint8_t res_packet[1 + sizeof(res_message)]; res_packet[0] = NET_PACKET_ANNOUNCE_RESPONSE_OLD; memcpy(res_packet + 1, res_message, sizeof(res_message)); if (send_onion_response(onion->net, source, res_packet, sizeof(res_packet), packet + sizeof(res_packet)) == -1) { return 1; } handled_test_1 = 1; return 0; } static int handled_test_2; static int handle_test_2(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { const char res_message[] = "install gentoo"; uint8_t res_packet[1 + sizeof(res_message)]; res_packet[0] = NET_PACKET_ANNOUNCE_RESPONSE_OLD; memcpy(res_packet + 1, res_message, sizeof(res_message)); if (length != sizeof(res_packet)) { return 1; } if (memcmp(packet, res_packet, sizeof(res_packet)) != 0) { return 1; } handled_test_2 = 1; return 0; } #if 0 void print_client_id(uint8_t *client_id, uint32_t length) { uint32_t j; for (j = 0; j < length; j++) { printf("%02X", client_id[j]); } printf("\n"); } #endif static uint8_t sb_data[ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; static int handled_test_3; static uint8_t test_3_pub_key[CRYPTO_PUBLIC_KEY_SIZE]; static uint8_t test_3_ping_id[CRYPTO_SHA256_SIZE]; static int handle_test_3(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { Onion *onion = (Onion *)object; if (length != (1 + CRYPTO_NONCE_SIZE + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + 1 + CRYPTO_SHA256_SIZE + CRYPTO_MAC_SIZE)) { return 1; } uint8_t plain[1 + CRYPTO_SHA256_SIZE]; #if 0 print_client_id(packet, length); #endif int len = decrypt_data(test_3_pub_key, dht_get_self_secret_key(onion->dht), packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE, 1 + CRYPTO_SHA256_SIZE + CRYPTO_MAC_SIZE, plain); if (len == -1) { return 1; } if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0) { return 1; } memcpy(test_3_ping_id, plain + 1, CRYPTO_SHA256_SIZE); #if 0 print_client_id(test_3_ping_id, sizeof(test_3_ping_id)); #endif handled_test_3 = 1; return 0; } static uint8_t nonce[CRYPTO_NONCE_SIZE]; static int handled_test_4; static int handle_test_4(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { Onion *onion = (Onion *)object; if (length != (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + sizeof("Install gentoo") + CRYPTO_MAC_SIZE)) { return 1; } uint8_t plain[sizeof("Install gentoo")] = {0}; if (memcmp(nonce, packet + 1, CRYPTO_NONCE_SIZE) != 0) { return 1; } int len = decrypt_data(packet + 1 + CRYPTO_NONCE_SIZE, dht_get_self_secret_key(onion->dht), packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, sizeof("Install gentoo") + CRYPTO_MAC_SIZE, plain); if (len == -1) { return 1; } if (memcmp(plain, "Install gentoo", sizeof("Install gentoo")) != 0) { return 1; } handled_test_4 = 1; return 0; } /** Create and send a onion packet. * * Use Onion_Path path to send data of length to dest. * Maximum length of data is ONION_MAX_DATA_SIZE. */ static void send_onion_packet(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length) { uint8_t packet[ONION_MAX_PACKET_SIZE]; const int len = create_onion_packet(rng, packet, sizeof(packet), path, dest, data, length); ck_assert_msg(len != -1, "failed to create onion packet"); ck_assert_msg(sendpacket(net, &path->ip_port1, packet, len) == len, "failed to send onion packet"); } /** Initialize networking. * 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) { return new_networking_ex(log, ns, ip, port, port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM), nullptr); } static void test_basic(void) { uint32_t index[] = { 1, 2, 3 }; const Network *ns = system_network(); Logger *log1 = logger_new(); logger_callback_log(log1, (logger_cb *)print_debug_log, nullptr, &index[0]); Logger *log2 = logger_new(); logger_callback_log(log2, (logger_cb *)print_debug_log, nullptr, &index[1]); const Random *rng = system_random(); ck_assert(rng != nullptr); Mono_Time *mono_time1 = mono_time_new(nullptr, nullptr); Mono_Time *mono_time2 = mono_time_new(nullptr, nullptr); 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 *onion2 = new_onion(log2, mono_time2, rng, new_dht(log2, rng, ns, mono_time2, new_networking(log2, ns, &ip, 36568), true, false)); ck_assert_msg((onion1 != nullptr) && (onion2 != nullptr), "Onion failed initializing."); networking_registerhandler(onion2->net, NET_PACKET_ANNOUNCE_REQUEST_OLD, &handle_test_1, onion2); IP_Port on1 = {ip, net_port(onion1->net)}; Node_format n1; memcpy(n1.public_key, dht_get_self_public_key(onion1->dht), CRYPTO_PUBLIC_KEY_SIZE); n1.ip_port = on1; IP_Port on2 = {ip, net_port(onion2->net)}; Node_format n2; memcpy(n2.public_key, dht_get_self_public_key(onion2->dht), CRYPTO_PUBLIC_KEY_SIZE); n2.ip_port = on2; const char req_message[] = "Install Gentoo"; uint8_t req_packet[1 + sizeof(req_message)]; req_packet[0] = NET_PACKET_ANNOUNCE_REQUEST_OLD; memcpy(req_packet + 1, req_message, sizeof(req_message)); Node_format nodes[4]; nodes[0] = n1; nodes[1] = n2; nodes[2] = n1; nodes[3] = n2; Onion_Path path; create_onion_path(rng, onion1->dht, &path, nodes); send_onion_packet(onion1->net, rng, &path, &nodes[3].ip_port, req_packet, sizeof(req_packet)); handled_test_1 = 0; do { do_onion(mono_time1, onion1); do_onion(mono_time2, onion2); } while (handled_test_1 == 0); networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_test_2, onion1); handled_test_2 = 0; do { do_onion(mono_time1, onion1); do_onion(mono_time2, onion2); } while (handled_test_2 == 0); Onion_Announce *onion1_a = new_onion_announce(log1, rng, mono_time1, onion1->dht); Onion_Announce *onion2_a = new_onion_announce(log2, rng, mono_time2, onion2->dht); networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_test_3, onion1); ck_assert_msg((onion1_a != nullptr) && (onion2_a != nullptr), "Onion_Announce failed initializing."); uint8_t zeroes[64] = {0}; random_bytes(rng, sb_data, sizeof(sb_data)); uint64_t s; memcpy(&s, sb_data, sizeof(uint64_t)); memcpy(test_3_pub_key, nodes[3].public_key, CRYPTO_PUBLIC_KEY_SIZE); int ret = send_announce_request(onion1->net, rng, &path, &nodes[3], dht_get_self_public_key(onion1->dht), dht_get_self_secret_key(onion1->dht), zeroes, dht_get_self_public_key(onion1->dht), dht_get_self_public_key(onion1->dht), s); ck_assert_msg(ret == 0, "Failed to create/send onion announce_request packet."); handled_test_3 = 0; do { do_onion(mono_time1, onion1); do_onion(mono_time2, onion2); c_sleep(50); } while (handled_test_3 == 0); random_bytes(rng, sb_data, sizeof(sb_data)); memcpy(&s, sb_data, sizeof(uint64_t)); memcpy(onion_announce_entry_public_key(onion2_a, 1), dht_get_self_public_key(onion2->dht), CRYPTO_PUBLIC_KEY_SIZE); onion_announce_entry_set_time(onion2_a, 1, mono_time_get(mono_time2)); networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1); send_announce_request(onion1->net, rng, &path, &nodes[3], dht_get_self_public_key(onion1->dht), dht_get_self_secret_key(onion1->dht), test_3_ping_id, dht_get_self_public_key(onion1->dht), dht_get_self_public_key(onion1->dht), s); do { do_onion(mono_time1, onion1); do_onion(mono_time2, onion2); c_sleep(50); } while (memcmp(onion_announce_entry_public_key(onion2_a, ONION_ANNOUNCE_MAX_ENTRIES - 2), dht_get_self_public_key(onion1->dht), CRYPTO_PUBLIC_KEY_SIZE) != 0); c_sleep(1000); Logger *log3 = logger_new(); logger_callback_log(log3, (logger_cb *)print_debug_log, nullptr, &index[2]); Mono_Time *mono_time3 = mono_time_new(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)); ck_assert_msg((onion3 != nullptr), "Onion failed initializing."); random_nonce(rng, nonce); ret = send_data_request(onion3->net, rng, &path, &nodes[3].ip_port, dht_get_self_public_key(onion1->dht), dht_get_self_public_key(onion1->dht), nonce, (const uint8_t *)"Install gentoo", sizeof("Install gentoo")); ck_assert_msg(ret == 0, "Failed to create/send onion data_request packet."); handled_test_4 = 0; do { do_onion(mono_time1, onion1); do_onion(mono_time2, onion2); c_sleep(50); } while (handled_test_4 == 0); kill_onion_announce(onion2_a); kill_onion_announce(onion1_a); { Onion *onion = onion3; Networking_Core *net = dht_get_net(onion->dht); DHT *dht = onion->dht; kill_onion(onion); kill_dht(dht); kill_networking(net); mono_time_free(mono_time3); logger_kill(log3); } { Onion *onion = onion2; Networking_Core *net = dht_get_net(onion->dht); DHT *dht = onion->dht; kill_onion(onion); kill_dht(dht); kill_networking(net); mono_time_free(mono_time2); logger_kill(log2); } { Onion *onion = onion1; Networking_Core *net = dht_get_net(onion->dht); DHT *dht = onion->dht; kill_onion(onion); kill_dht(dht); kill_networking(net); mono_time_free(mono_time1); logger_kill(log1); } } typedef struct { Logger *log; Mono_Time *mono_time; Onion *onion; Onion_Announce *onion_a; Onion_Client *onion_c; } Onions; static Onions *new_onions(const Random *rng, uint16_t port, uint32_t *index) { IP ip = get_loopback(); ip.ip.v6.uint8[15] = 1; const Network *ns = system_network(); Onions *on = (Onions *)malloc(sizeof(Onions)); if (!on) { return nullptr; } on->log = logger_new(); if (!on->log) { free(on); return nullptr; } logger_callback_log(on->log, (logger_cb *)print_debug_log, nullptr, index); on->mono_time = mono_time_new(nullptr, nullptr); if (!on->mono_time) { logger_kill(on->log); free(on); return nullptr; } Networking_Core *net = new_networking(on->log, ns, &ip, port); if (!net) { mono_time_free(on->mono_time); logger_kill(on->log); free(on); return nullptr; } DHT *dht = new_dht(on->log, rng, ns, on->mono_time, net, true, false); if (!dht) { kill_networking(net); mono_time_free(on->mono_time); logger_kill(on->log); free(on); return nullptr; } on->onion = new_onion(on->log, on->mono_time, rng, dht); if (!on->onion) { kill_dht(dht); kill_networking(net); mono_time_free(on->mono_time); logger_kill(on->log); free(on); return nullptr; } on->onion_a = new_onion_announce(on->log, rng, on->mono_time, dht); if (!on->onion_a) { kill_onion(on->onion); kill_dht(dht); kill_networking(net); mono_time_free(on->mono_time); logger_kill(on->log); free(on); return nullptr; } 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)); if (!on->onion_c) { kill_onion_announce(on->onion_a); kill_onion(on->onion); kill_dht(dht); kill_networking(net); mono_time_free(on->mono_time); logger_kill(on->log); free(on); return nullptr; } return on; } static void do_onions(Onions *on) { mono_time_update(on->mono_time); networking_poll(on->onion->net, nullptr); do_dht(on->onion->dht); do_onion_client(on->onion_c); } static void kill_onions(Onions *on) { Networking_Core *net = dht_get_net(on->onion->dht); DHT *dht = on->onion->dht; Net_Crypto *c = onion_get_net_crypto(on->onion_c); kill_onion_client(on->onion_c); kill_onion_announce(on->onion_a); kill_onion(on->onion); kill_net_crypto(c); kill_dht(dht); kill_networking(net); mono_time_free(on->mono_time); logger_kill(on->log); free(on); } #define NUM_ONIONS 50 #define NUM_FIRST 7 #define NUM_LAST 37 static bool first_ip, last_ip; static void dht_ip_callback(void *object, int32_t number, const IP_Port *ip_port) { if (NUM_FIRST == number) { first_ip = 1; return; } if (NUM_LAST == number) { last_ip = 1; return; } ck_abort_msg("Error."); } static bool first, last; static uint8_t first_dht_pk[CRYPTO_PUBLIC_KEY_SIZE]; static uint8_t last_dht_pk[CRYPTO_PUBLIC_KEY_SIZE]; static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_public_key, void *userdata) { if ((NUM_FIRST == number && !first) || (NUM_LAST == number && !last)) { Onions *on = (Onions *)object; uint16_t count = 0; int ret = dht_addfriend(on->onion->dht, dht_public_key, &dht_ip_callback, object, number, &count); ck_assert_msg(ret == 0, "dht_addfriend() did not return 0"); ck_assert_msg(count == 1, "Count not 1, count is %u", count); if (NUM_FIRST == number && !first) { first = 1; if (memcmp(dht_public_key, last_dht_pk, CRYPTO_PUBLIC_KEY_SIZE) != 0) { ck_abort_msg("Error wrong dht key."); } return; } if (NUM_LAST == number && !last) { last = 1; if (memcmp(dht_public_key, first_dht_pk, CRYPTO_PUBLIC_KEY_SIZE) != 0) { ck_abort_msg("Error wrong dht key."); } return; } ck_abort_msg("Error."); } } static void test_announce(void) { uint32_t i, j; uint32_t index[NUM_ONIONS]; Onions *onions[NUM_ONIONS]; const Random *rng = system_random(); ck_assert(rng != nullptr); for (i = 0; i < NUM_ONIONS; ++i) { index[i] = i + 1; onions[i] = new_onions(rng, i + 36655, &index[i]); ck_assert_msg(onions[i] != nullptr, "Failed to create onions. %u", i); } IP ip = get_loopback(); for (i = 3; i < NUM_ONIONS; ++i) { 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)); IP_Port ip_port1 = {ip, net_port(onions[i - 2]->onion->net)}; dht_bootstrap(onions[i]->onion->dht, &ip_port1, dht_get_self_public_key(onions[i - 2]->onion->dht)); IP_Port ip_port2 = {ip, net_port(onions[i - 3]->onion->net)}; dht_bootstrap(onions[i]->onion->dht, &ip_port2, dht_get_self_public_key(onions[i - 3]->onion->dht)); } uint32_t connected = 0; do { connected = 0; for (i = 0; i < NUM_ONIONS; ++i) { do_onions(onions[i]); connected += dht_isconnected(onions[i]->onion->dht); } c_sleep(50); } while (connected != NUM_ONIONS); printf("connected\n"); for (i = 0; i < 25 * 2; ++i) { for (j = 0; j < NUM_ONIONS; ++j) { do_onions(onions[j]); } c_sleep(50); } memcpy(first_dht_pk, dht_get_self_public_key(onions[NUM_FIRST]->onion->dht), CRYPTO_PUBLIC_KEY_SIZE); memcpy(last_dht_pk, dht_get_self_public_key(onions[NUM_LAST]->onion->dht), CRYPTO_PUBLIC_KEY_SIZE); printf("adding friend\n"); int frnum_f = onion_addfriend(onions[NUM_FIRST]->onion_c, nc_get_self_public_key(onion_get_net_crypto(onions[NUM_LAST]->onion_c))); int frnum = onion_addfriend(onions[NUM_LAST]->onion_c, nc_get_self_public_key(onion_get_net_crypto(onions[NUM_FIRST]->onion_c))); onion_dht_pk_callback(onions[NUM_FIRST]->onion_c, frnum_f, &dht_pk_callback, onions[NUM_FIRST], NUM_FIRST); onion_dht_pk_callback(onions[NUM_LAST]->onion_c, frnum, &dht_pk_callback, onions[NUM_LAST], NUM_LAST); IP_Port ip_port; do { for (i = 0; i < NUM_ONIONS; ++i) { do_onions(onions[i]); } c_sleep(50); } while (!first || !last); printf("Waiting for ips\n"); do { for (i = 0; i < NUM_ONIONS; ++i) { do_onions(onions[i]); } c_sleep(50); } while (!first_ip || !last_ip); 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."); for (i = 0; i < NUM_ONIONS; ++i) { kill_onions(onions[i]); } } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_basic(); test_announce(); return 0; } c-toxcore-0.2.18/auto_tests/overflow_recvq_test.c0000777000175000017500000000375714227324767021212 0ustar robinrobin/* Try to overflow the net_crypto packet buffer. */ #include typedef struct State { uint32_t recv_count; } State; #include "auto_test_support.h" #define NUM_MSGS 40000 static void handle_friend_message(Tox *tox, uint32_t friend_number, Tox_Message_Type type, const uint8_t *message, size_t length, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; state->recv_count++; } static void net_crypto_overflow_test(AutoTox *autotoxes) { tox_callback_friend_message(autotoxes[0].tox, handle_friend_message); printf("sending many messages to tox0\n"); for (uint32_t tox_index = 1; tox_index < 3; tox_index++) { for (uint32_t i = 0; i < NUM_MSGS; i++) { uint8_t message[128] = {0}; snprintf((char *)message, sizeof(message), "%u-%u", tox_index, i); Tox_Err_Friend_Send_Message err; tox_friend_send_message(autotoxes[tox_index].tox, 0, TOX_MESSAGE_TYPE_NORMAL, message, sizeof message, &err); if (err == TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ) { printf("tox%u sent %u messages to friend 0\n", tox_index, i); break; } ck_assert_msg(err == TOX_ERR_FRIEND_SEND_MESSAGE_OK, "tox%u failed to send message number %u: %d", tox_index, i, err); } } // TODO(iphydf): Wait until all messages have arrived. Currently, not all // messages arrive, so this test would always fail. for (uint32_t i = 0; i < 200; i++) { iterate_all_wait(autotoxes, 3, ITERATION_INTERVAL); } printf("tox%u received %u messages\n", autotoxes[0].index, ((State *)autotoxes[0].state)->recv_count); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; run_auto_test(nullptr, 3, net_crypto_overflow_test, sizeof(State), &options); return 0; } c-toxcore-0.2.18/auto_tests/overflow_sendq_test.c0000777000175000017500000000250214227324767021167 0ustar robinrobin/* Try to overflow the net_crypto packet buffer. */ #include #include "auto_test_support.h" #define NUM_MSGS 40000 static void net_crypto_overflow_test(AutoTox *autotoxes) { const uint8_t message[] = {0}; bool errored = false; for (uint32_t i = 0; i < NUM_MSGS; i++) { Tox_Err_Friend_Send_Message err; tox_friend_send_message(autotoxes[0].tox, 0, TOX_MESSAGE_TYPE_NORMAL, message, sizeof message, &err); if (err != TOX_ERR_FRIEND_SEND_MESSAGE_OK) { errored = true; } if (errored) { // As soon as we get the first error, we expect the same error (SENDQ) // every time we try to send. ck_assert_msg(err == TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ, "expected SENDQ error on message %u, but got %d", i, err); } else { ck_assert_msg(err == TOX_ERR_FRIEND_SEND_MESSAGE_OK, "failed to send message number %u: %d", i, err); } } ck_assert_msg(errored, "expected SENDQ error at some point (increase NUM_MSGS?)"); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; run_auto_test(nullptr, 2, net_crypto_overflow_test, 0, &options); return 0; } c-toxcore-0.2.18/auto_tests/proxy_test.c0000777000175000017500000001034614227324767017320 0ustar robinrobin/* Tests that we can send messages to friends. */ #include #include #include #include "auto_test_support.h" static void *proxy_routine(void *arg) { const char *proxy_bin = (const char *)arg; ck_assert(proxy_bin != nullptr); printf("starting http/sock5 proxy: %s\n", proxy_bin); ck_assert(system(proxy_bin) == 0); return nullptr; } static bool try_bootstrap(Tox *tox1, Tox *tox2, Tox *tox3, Tox *tox4) { for (uint32_t i = 0; i < 400; ++i) { if (tox_self_get_connection_status(tox1) != TOX_CONNECTION_NONE && tox_self_get_connection_status(tox2) != TOX_CONNECTION_NONE && tox_self_get_connection_status(tox3) != TOX_CONNECTION_NONE && tox_self_get_connection_status(tox4) != TOX_CONNECTION_NONE) { printf("%d %d %d %d\n", tox_self_get_connection_status(tox1), tox_self_get_connection_status(tox2), tox_self_get_connection_status(tox3), tox_self_get_connection_status(tox4)); return true; } tox_iterate(tox1, nullptr); tox_iterate(tox2, nullptr); tox_iterate(tox3, nullptr); tox_iterate(tox4, nullptr); if (i % 10 == 0) { printf("%d %d %d %d\n", tox_self_get_connection_status(tox1), tox_self_get_connection_status(tox2), tox_self_get_connection_status(tox3), tox_self_get_connection_status(tox4)); } c_sleep(tox_iteration_interval(tox1)); } return false; } int main(int argc, char **argv) { setvbuf(stdout, nullptr, _IONBF, 0); if (argc >= 3) { char *proxy_bin = argv[2]; pthread_t proxy_thread; pthread_create(&proxy_thread, nullptr, proxy_routine, proxy_bin); c_sleep(100); } const uint16_t tcp_port = 8082; uint32_t index[] = { 1, 2, 3, 4 }; struct Tox_Options *tox_options = tox_options_new(nullptr); ck_assert(tox_options != nullptr); // tox1 is a TCP server and has UDP enabled. tox_options_set_udp_enabled(tox_options, true); tox_options_set_tcp_port(tox_options, tcp_port); Tox *tox1 = tox_new_log(tox_options, nullptr, &index[0]); ck_assert(tox1 != nullptr); // Get tox1's DHT key and port. uint8_t dht_pk[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(tox1, dht_pk); uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr); ck_assert(dht_port != 0); // tox2 is a regular DHT node bootstrapping against tox1. tox_options_set_udp_enabled(tox_options, true); tox_options_set_tcp_port(tox_options, 0); Tox *tox2 = tox_new_log(tox_options, nullptr, &index[1]); ck_assert(tox2 != nullptr); // tox2 bootstraps against tox1 with UDP. ck_assert(tox_bootstrap(tox2, "127.0.0.1", dht_port, dht_pk, nullptr)); // tox3 has UDP disabled and connects to tox1 via an HTTP proxy tox_options_set_udp_enabled(tox_options, false); tox_options_set_proxy_host(tox_options, "127.0.0.1"); tox_options_set_proxy_port(tox_options, 8080); tox_options_set_proxy_type(tox_options, TOX_PROXY_TYPE_HTTP); Tox *tox3 = tox_new_log(tox_options, nullptr, &index[2]); ck_assert(tox3 != nullptr); // tox4 has UDP disabled and connects to tox1 via a SOCKS5 proxy tox_options_set_udp_enabled(tox_options, false); tox_options_set_proxy_host(tox_options, "127.0.0.1"); tox_options_set_proxy_port(tox_options, 8081); tox_options_set_proxy_type(tox_options, TOX_PROXY_TYPE_SOCKS5); Tox *tox4 = tox_new_log(tox_options, nullptr, &index[3]); ck_assert(tox4 != nullptr); // tox3 and tox4 bootstrap against tox1 and add it as a TCP relay ck_assert(tox_bootstrap(tox3, "127.0.0.1", dht_port, dht_pk, nullptr)); ck_assert(tox_add_tcp_relay(tox3, "127.0.0.1", tcp_port, dht_pk, nullptr)); ck_assert(tox_bootstrap(tox4, "127.0.0.1", dht_port, dht_pk, nullptr)); ck_assert(tox_add_tcp_relay(tox4, "127.0.0.1", tcp_port, dht_pk, nullptr)); int ret = 1; if (try_bootstrap(tox1, tox2, tox3, tox4)) { ret = 0; } tox_options_free(tox_options); tox_kill(tox4); tox_kill(tox3); tox_kill(tox2); tox_kill(tox1); return ret; } c-toxcore-0.2.18/auto_tests/reconnect_test.c0000777000175000017500000000564714227324767020127 0ustar robinrobin/* Auto Tests: Reconnection. * * This test checks that when a tox instance is suspended for long enough that * its friend connections time out, those connections are promptly * re-established when the instance is resumed. */ #include #include #include #include "../testing/misc_tools.h" #include "../toxcore/friend_connection.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" #include "check_compat.h" #define TOX_COUNT 2 #define RECONNECT_TIME_MAX (FRIEND_CONNECTION_TIMEOUT + 3) #include "auto_test_support.h" static uint32_t tox_connected_count(uint32_t tox_count, AutoTox *autotoxes, uint32_t index) { const size_t friend_count = tox_self_get_friend_list_size(autotoxes[index].tox); uint32_t connected_count = 0; for (size_t j = 0; j < friend_count; j++) { if (tox_friend_get_connection_status(autotoxes[index].tox, j, nullptr) != TOX_CONNECTION_NONE) { ++connected_count; } } return connected_count; } static bool all_disconnected_from(uint32_t tox_count, AutoTox *autotoxes, uint32_t index) { for (uint32_t i = 0; i < tox_count; i++) { if (i == index) { continue; } if (tox_connected_count(tox_count, autotoxes, i) >= tox_count - 1) { return false; } } return true; } static void test_reconnect(AutoTox *autotoxes) { const Random *rng = system_random(); ck_assert(rng != nullptr); const time_t test_start_time = time(nullptr); printf("letting connections settle\n"); do { iterate_all_wait(autotoxes, TOX_COUNT, ITERATION_INTERVAL); } while (time(nullptr) - test_start_time < 2); const uint16_t disconnect = random_u16(rng) % TOX_COUNT; printf("disconnecting #%u\n", autotoxes[disconnect].index); do { for (uint16_t i = 0; i < TOX_COUNT; ++i) { if (i != disconnect) { tox_iterate(autotoxes[i].tox, &autotoxes[i]); autotoxes[i].clock += 1000; } } c_sleep(20); } while (!all_disconnected_from(TOX_COUNT, autotoxes, disconnect)); const uint64_t reconnect_start_time = autotoxes[0].clock; printf("reconnecting\n"); do { iterate_all_wait(autotoxes, TOX_COUNT, ITERATION_INTERVAL); } while (!all_friends_connected(autotoxes, TOX_COUNT)); const uint64_t reconnect_time = autotoxes[0].clock - reconnect_start_time; ck_assert_msg(reconnect_time <= RECONNECT_TIME_MAX * 1000, "reconnection took %d seconds; expected at most %d seconds", (int)(reconnect_time / 1000), RECONNECT_TIME_MAX); printf("test_reconnect succeeded, took %d seconds\n", (int)(time(nullptr) - test_start_time)); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; run_auto_test(nullptr, TOX_COUNT, test_reconnect, 0, &options); return 0; } c-toxcore-0.2.18/auto_tests/save_compatibility_test.c0000777000175000017500000001173314227324767022027 0ustar robinrobin// Tests to make sure new save code is compatible with old save files #include "../testing/misc_tools.h" #include "../toxcore/tox.h" #include "auto_test_support.h" #include "check_compat.h" #include #include #include #define LOADED_SAVE_FILE "../auto_tests/data/save.tox" // Information from the save file #define EXPECTED_NAME "name" #define EXPECTED_NAME_SIZE strlen(EXPECTED_NAME) #define EXPECTED_STATUS_MESSAGE "Hello World" #define EXPECTED_STATUS_MESSAGE_SIZE strlen(EXPECTED_STATUS_MESSAGE) #define EXPECTED_NUM_FRIENDS 1 #define EXPECTED_NOSPAM "4C762C7D" #define EXPECTED_TOX_ID "B70E97D41F69B7F4C42A5BC7BD7A76B95B8030BE1B7C0E9E6FC19FC4ABEB195B4C762C7D800B" static size_t get_file_size(const char *save_path) { FILE *const fp = fopen(save_path, "rb"); if (fp == nullptr) { return 0; } fseek(fp, 0, SEEK_END); const size_t size = ftell(fp); fclose(fp); return size; } static uint8_t *read_save(const char *save_path, size_t *length) { const size_t size = get_file_size(save_path); if (size == 0) { return nullptr; } FILE *const fp = fopen(save_path, "rb"); if (!fp) { return nullptr; } uint8_t *const data = (uint8_t *)malloc(size); if (!data) { fclose(fp); return nullptr; } if (fread(data, size, 1, fp) != 1) { free(data); fclose(fp); return nullptr; } *length = size; fclose(fp); return data; } static void test_save_compatibility(const char *save_path) { struct Tox_Options options = {0}; tox_options_default(&options); size_t size = 0; uint8_t *save_data = read_save(save_path, &size); ck_assert_msg(save_data != nullptr, "error while reading save file '%s'", save_path); options.savedata_data = save_data; options.savedata_length = size; options.savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE; size_t index = 0; Tox_Err_New err; Tox *tox = tox_new_log(&options, &err, &index); ck_assert_msg(tox, "failed to create tox, error number: %d", err); free(save_data); const size_t name_size = tox_self_get_name_size(tox); ck_assert_msg(name_size == EXPECTED_NAME_SIZE, "name sizes do not match expected %zu got %zu", EXPECTED_NAME_SIZE, name_size); uint8_t *name = (uint8_t *)malloc(tox_self_get_name_size(tox)); ck_assert(name != nullptr); tox_self_get_name(tox, name); ck_assert_msg(strncmp((const char *)name, EXPECTED_NAME, name_size) == 0, "names do not match, expected %s got %s", EXPECTED_NAME, name); const size_t status_message_size = tox_self_get_status_message_size(tox); ck_assert_msg(status_message_size == EXPECTED_STATUS_MESSAGE_SIZE, "status message sizes do not match, expected %zu got %zu", EXPECTED_STATUS_MESSAGE_SIZE, status_message_size); uint8_t *status_message = (uint8_t *)malloc(tox_self_get_status_message_size(tox)); ck_assert(status_message != nullptr); tox_self_get_status_message(tox, status_message); ck_assert_msg(strncmp((const char *)status_message, EXPECTED_STATUS_MESSAGE, status_message_size) == 0, "status messages do not match, expected %s got %s", EXPECTED_STATUS_MESSAGE, status_message); const size_t num_friends = tox_self_get_friend_list_size(tox); ck_assert_msg(num_friends == EXPECTED_NUM_FRIENDS, "number of friends do not match, expected %d got %zu", EXPECTED_NUM_FRIENDS, num_friends); const uint32_t nospam = tox_self_get_nospam(tox); char nospam_str[TOX_NOSPAM_SIZE * 2 + 1]; const size_t length = snprintf(nospam_str, sizeof(nospam_str), "%08X", nospam); nospam_str[length] = '\0'; ck_assert_msg(strcmp(nospam_str, EXPECTED_NOSPAM) == 0, "nospam does not match, expected %s got %s", EXPECTED_NOSPAM, nospam_str); uint8_t tox_id[TOX_ADDRESS_SIZE]; char tox_id_str[TOX_ADDRESS_SIZE * 2 + 1] = {0}; tox_self_get_address(tox, tox_id); to_hex(tox_id_str, tox_id, TOX_ADDRESS_SIZE); ck_assert_msg(strncmp(tox_id_str, EXPECTED_TOX_ID, TOX_ADDRESS_SIZE * 2) == 0, "tox ids do not match, expected %s got %s", EXPECTED_TOX_ID, tox_id_str); /* Giving the tox a chance to error on iterate due to corrupted loaded structures */ tox_iterate(tox, nullptr); free(status_message); free(name); tox_kill(tox); } int main(int argc, char *argv[]) { char base_path[4096] = {0}; if (argc <= 1) { const char *srcdir = getenv("srcdir"); if (srcdir == nullptr) { srcdir = "."; } snprintf(base_path, sizeof(base_path), "%s", srcdir); } else { snprintf(base_path, sizeof(base_path), "%s", argv[1]); base_path[strrchr(base_path, '/') - base_path] = '\0'; } char save_path[4096 + sizeof(LOADED_SAVE_FILE)]; snprintf(save_path, sizeof(save_path), "%s/%s", base_path, LOADED_SAVE_FILE); test_save_compatibility(save_path); return 0; } c-toxcore-0.2.18/auto_tests/save_friend_test.c0000777000175000017500000001233314227324767020422 0ustar robinrobin/* Auto Tests: Save and load friends. */ #include #include #include #include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" #include "../toxcore/crypto_core.h" #include "../toxcore/tox.h" #include "auto_test_support.h" #include "check_compat.h" struct test_data { uint8_t *name; uint8_t *status_message; bool received_name; bool received_status_message; }; static void set_random(Tox *m, const Random *rng, bool (*setter)(Tox *, const uint8_t *, size_t, Tox_Err_Set_Info *), size_t length) { VLA(uint8_t, text, length); uint32_t i; for (i = 0; i < length; ++i) { text[i] = random_u08(rng); } setter(m, text, SIZEOF_VLA(text), nullptr); } static void alloc_string(uint8_t **to, size_t length) { free(*to); *to = (uint8_t *)malloc(length); ck_assert(*to != nullptr); } static void set_string(uint8_t **to, const uint8_t *from, size_t length) { alloc_string(to, length); memcpy(*to, from, length); } static void namechange_callback(Tox *tox, uint32_t friend_number, const uint8_t *name, size_t length, void *user_data) { struct test_data *to_compare = (struct test_data *)user_data; set_string(&to_compare->name, name, length); to_compare->received_name = true; } static void statuschange_callback(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length, void *user_data) { struct test_data *to_compare = (struct test_data *)user_data; set_string(&to_compare->status_message, message, length); to_compare->received_status_message = true; } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Tox *const tox1 = tox_new_log(nullptr, nullptr, nullptr); Tox *const tox2 = tox_new_log(nullptr, nullptr, nullptr); printf("bootstrapping tox2 off tox1\n"); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(tox1, dht_key); const uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr); tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr); struct test_data to_compare = {nullptr}; uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(tox1, public_key); tox_friend_add_norequest(tox2, public_key, nullptr); tox_self_get_public_key(tox2, public_key); tox_friend_add_norequest(tox1, public_key, nullptr); uint8_t *reference_name = (uint8_t *)malloc(tox_max_name_length()); uint8_t *reference_status = (uint8_t *)malloc(tox_max_status_message_length()); ck_assert(reference_name != nullptr); ck_assert(reference_status != nullptr); const Random *rng = system_random(); ck_assert(rng != nullptr); set_random(tox1, rng, tox_self_set_name, tox_max_name_length()); set_random(tox2, rng, tox_self_set_name, tox_max_name_length()); set_random(tox1, rng, tox_self_set_status_message, tox_max_status_message_length()); set_random(tox2, rng, tox_self_set_status_message, tox_max_status_message_length()); tox_self_get_name(tox2, reference_name); tox_self_get_status_message(tox2, reference_status); tox_callback_friend_name(tox1, namechange_callback); tox_callback_friend_status_message(tox1, statuschange_callback); while (true) { if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2) && tox_friend_get_connection_status(tox1, 0, nullptr) == TOX_CONNECTION_UDP) { printf("Connected.\n"); break; } tox_iterate(tox1, &to_compare); tox_iterate(tox2, nullptr); c_sleep(tox_iteration_interval(tox1)); } while (true) { if (to_compare.received_name && to_compare.received_status_message) { printf("Exchanged names and status messages.\n"); break; } tox_iterate(tox1, &to_compare); tox_iterate(tox2, nullptr); c_sleep(tox_iteration_interval(tox1)); } size_t save_size = tox_get_savedata_size(tox1); uint8_t *savedata = (uint8_t *)malloc(save_size); tox_get_savedata(tox1, savedata); struct Tox_Options *const options = tox_options_new(nullptr); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); tox_options_set_savedata_data(options, savedata, save_size); Tox *const tox_to_compare = tox_new_log(options, nullptr, nullptr); alloc_string(&to_compare.name, tox_friend_get_name_size(tox_to_compare, 0, nullptr)); tox_friend_get_name(tox_to_compare, 0, to_compare.name, nullptr); alloc_string(&to_compare.status_message, tox_friend_get_status_message_size(tox_to_compare, 0, nullptr)); tox_friend_get_status_message(tox_to_compare, 0, to_compare.status_message, nullptr); ck_assert_msg(memcmp(reference_name, to_compare.name, tox_max_name_length()) == 0, "incorrect name: should be all zeroes"); ck_assert_msg(memcmp(reference_status, to_compare.status_message, tox_max_status_message_length()) == 0, "incorrect status message: should be all zeroes"); tox_options_free(options); tox_kill(tox1); tox_kill(tox2); tox_kill(tox_to_compare); free(savedata); free(to_compare.name); free(to_compare.status_message); free(reference_status); free(reference_name); return 0; } c-toxcore-0.2.18/auto_tests/save_load_test.c0000777000175000017500000002142614227324767020075 0ustar robinrobin/* Tests that we can save and load Tox data. */ #include #include #include #include #include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" #include "../toxcore/tox.h" #include "../toxcore/tox_struct.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" /* The Travis-CI container responds poorly to ::1 as a localhost address * You're encouraged to -D FORCE_TESTS_IPV6 on a local test */ #ifdef TOX_LOCALHOST #undef TOX_LOCALHOST #endif #ifdef FORCE_TESTS_IPV6 #define TOX_LOCALHOST "::1" #else #define TOX_LOCALHOST "127.0.0.1" #endif #ifdef TCP_RELAY_PORT #undef TCP_RELAY_PORT #endif #define TCP_RELAY_PORT 33431 static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) { if (length == 7 && memcmp("Gentoo", data, 7) == 0) { tox_friend_add_norequest(m, public_key, nullptr); } } static unsigned int connected_t1; static void tox_connection_status(Tox *tox, Tox_Connection connection_status, void *user_data) { if (connected_t1 && !connection_status) { ck_abort_msg("Tox went offline"); } ck_assert_msg(connection_status != TOX_CONNECTION_NONE, "wrong status %d", connection_status); connected_t1 = connection_status; } /* validate that: * a) saving stays within the confined space * b) a saved state can be loaded back successfully * c) a second save is of equal size * d) the second save is of equal content */ static void reload_tox(Tox **tox, struct Tox_Options *const in_opts, void *user_data) { const size_t extra = 64; const size_t save_size1 = tox_get_savedata_size(*tox); ck_assert_msg(save_size1 != 0, "save is invalid size %u", (unsigned)save_size1); printf("%u\n", (unsigned)save_size1); uint8_t *buffer = (uint8_t *)malloc(save_size1 + 2 * extra); ck_assert_msg(buffer != nullptr, "malloc failed"); memset(buffer, 0xCD, extra); memset(buffer + extra + save_size1, 0xCD, extra); tox_get_savedata(*tox, buffer + extra); tox_kill(*tox); for (size_t i = 0; i < extra; ++i) { ck_assert_msg(buffer[i] == 0xCD, "Buffer underwritten from tox_get_savedata() @%u", (unsigned)i); ck_assert_msg(buffer[extra + save_size1 + i] == 0xCD, "Buffer overwritten from tox_get_savedata() @%u", (unsigned)i); } struct Tox_Options *const options = (in_opts == nullptr) ? tox_options_new(nullptr) : in_opts; tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); tox_options_set_savedata_data(options, buffer + extra, save_size1); *tox = tox_new_log(options, nullptr, user_data); if (in_opts == nullptr) { tox_options_free(options); } ck_assert_msg(*tox != nullptr, "Failed to load back stored buffer"); const size_t save_size2 = tox_get_savedata_size(*tox); ck_assert_msg(save_size1 == save_size2, "Tox save data changed in size from a store/load cycle: %u -> %u", (unsigned)save_size1, (unsigned)save_size2); uint8_t *buffer2 = (uint8_t *)malloc(save_size2); ck_assert_msg(buffer2 != nullptr, "malloc failed"); tox_get_savedata(*tox, buffer2); ck_assert_msg(!memcmp(buffer + extra, buffer2, save_size2), "Tox state changed by store/load/store cycle"); free(buffer2); free(buffer); } typedef struct Time_Data { pthread_mutex_t lock; uint64_t clock; } Time_Data; static uint64_t get_state_clock_callback(void *user_data) { Time_Data *time_data = (Time_Data *)user_data; pthread_mutex_lock(&time_data->lock); uint64_t clock = time_data->clock; pthread_mutex_unlock(&time_data->lock); return clock; } static void increment_clock(Time_Data *time_data, uint64_t count) { pthread_mutex_lock(&time_data->lock); time_data->clock += count; pthread_mutex_unlock(&time_data->lock); } static void set_current_time_callback(Tox *tox, Time_Data *time_data) { Mono_Time *mono_time = tox->mono_time; mono_time_set_current_time_callback(mono_time, get_state_clock_callback, time_data); } static void test_few_clients(void) { uint32_t index[] = { 1, 2, 3 }; time_t con_time = 0, cur_time = time(nullptr); struct Tox_Options *opts1 = tox_options_new(nullptr); tox_options_set_tcp_port(opts1, TCP_RELAY_PORT); Tox_Err_New t_n_error; Tox *tox1 = tox_new_log(opts1, &t_n_error, &index[0]); ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "Failed to create tox instance: %d", t_n_error); tox_options_free(opts1); struct Tox_Options *opts2 = tox_options_new(nullptr); tox_options_set_udp_enabled(opts2, false); tox_options_set_local_discovery_enabled(opts2, false); Tox *tox2 = tox_new_log(opts2, &t_n_error, &index[1]); ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "Failed to create tox instance: %d", t_n_error); struct Tox_Options *opts3 = tox_options_new(nullptr); tox_options_set_local_discovery_enabled(opts3, false); Tox *tox3 = tox_new_log(opts3, &t_n_error, &index[2]); ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "Failed to create tox instance: %d", t_n_error); ck_assert_msg(tox1 && tox2 && tox3, "Failed to create 3 tox instances"); Time_Data time_data; ck_assert_msg(pthread_mutex_init(&time_data.lock, nullptr) == 0, "Failed to init time_data mutex"); time_data.clock = current_time_monotonic(tox1->mono_time); set_current_time_callback(tox1, &time_data); set_current_time_callback(tox2, &time_data); set_current_time_callback(tox3, &time_data); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(tox1, dht_key); const uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr); printf("using tox1 as tcp relay for tox2\n"); tox_add_tcp_relay(tox2, TOX_LOCALHOST, TCP_RELAY_PORT, dht_key, nullptr); printf("bootstrapping toxes off tox1\n"); tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr); tox_bootstrap(tox3, "localhost", dht_port, dht_key, nullptr); connected_t1 = 0; tox_callback_self_connection_status(tox1, tox_connection_status); tox_callback_friend_request(tox2, accept_friend_request); uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(tox2, address); 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); uint8_t off = 1; while (true) { tox_iterate(tox1, nullptr); tox_iterate(tox2, nullptr); tox_iterate(tox3, nullptr); if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2) && tox_self_get_connection_status(tox3)) { if (off) { printf("Toxes are online, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); con_time = time(nullptr); off = 0; } if (tox_friend_get_connection_status(tox2, 0, nullptr) == TOX_CONNECTION_TCP && tox_friend_get_connection_status(tox3, 0, nullptr) == TOX_CONNECTION_TCP) { break; } } increment_clock(&time_data, 200); c_sleep(5); } ck_assert_msg(connected_t1, "Tox1 isn't connected. %u", connected_t1); printf("tox clients connected took %lu seconds\n", (unsigned long)(time(nullptr) - con_time)); // We're done with this callback, so unset it to ensure we don't fail the // test if tox1 goes offline while tox2 and 3 are reloaded. tox_callback_self_connection_status(tox1, nullptr); reload_tox(&tox2, opts2, &index[1]); reload_tox(&tox3, opts3, &index[2]); cur_time = time(nullptr); off = 1; while (true) { tox_iterate(tox1, nullptr); tox_iterate(tox2, nullptr); tox_iterate(tox3, nullptr); if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2) && tox_self_get_connection_status(tox3)) { if (off) { printf("Toxes are online again after reloading, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); con_time = time(nullptr); off = 0; } if (tox_friend_get_connection_status(tox2, 0, nullptr) == TOX_CONNECTION_TCP && tox_friend_get_connection_status(tox3, 0, nullptr) == TOX_CONNECTION_TCP) { break; } } increment_clock(&time_data, 100); c_sleep(5); } printf("tox clients connected took %lu seconds\n", (unsigned long)(time(nullptr) - con_time)); printf("test_few_clients succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); tox_kill(tox1); tox_kill(tox2); tox_kill(tox3); tox_options_free(opts2); tox_options_free(opts3); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_few_clients(); return 0; } c-toxcore-0.2.18/auto_tests/send_message_test.c0000777000175000017500000000455414227324767020600 0ustar robinrobin/* Tests that we can send messages to friends. */ #include #include #include typedef struct State { bool message_received; } State; #include "auto_test_support.h" #define MESSAGE_FILLER 'G' static void message_callback( Tox *m, uint32_t friendnumber, Tox_Message_Type type, const uint8_t *string, size_t length, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; if (type != TOX_MESSAGE_TYPE_NORMAL) { ck_abort_msg("Bad type"); } const size_t cmp_msg_len = tox_max_message_length(); uint8_t *cmp_msg = (uint8_t *)malloc(cmp_msg_len); ck_assert(cmp_msg != nullptr); memset(cmp_msg, MESSAGE_FILLER, cmp_msg_len); if (length == tox_max_message_length() && memcmp(string, cmp_msg, cmp_msg_len) == 0) { state->message_received = true; } free(cmp_msg); } static void send_message_test(AutoTox *autotoxes) { tox_callback_friend_message(autotoxes[1].tox, &message_callback); const size_t msgs_len = tox_max_message_length() + 1; uint8_t *msgs = (uint8_t *)malloc(msgs_len); memset(msgs, MESSAGE_FILLER, msgs_len); Tox_Err_Friend_Send_Message errm; tox_friend_send_message(autotoxes[0].tox, 0, TOX_MESSAGE_TYPE_NORMAL, msgs, msgs_len, &errm); ck_assert_msg(errm == TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG, "tox_max_message_length() is too small? error=%d", errm); tox_friend_send_message(autotoxes[0].tox, 0, TOX_MESSAGE_TYPE_NORMAL, msgs, tox_max_message_length(), &errm); ck_assert_msg(errm == TOX_ERR_FRIEND_SEND_MESSAGE_OK, "tox_max_message_length() is too big? error=%d", errm); free(msgs); do { iterate_all_wait(autotoxes, 2, ITERATION_INTERVAL); } while (!((State *)autotoxes[1].state)->message_received); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); struct Tox_Options *tox_options = tox_options_new(nullptr); ck_assert(tox_options != nullptr); Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; tox_options_set_ipv6_enabled(tox_options, true); run_auto_test(tox_options, 2, send_message_test, sizeof(State), &options); tox_options_set_ipv6_enabled(tox_options, false); run_auto_test(tox_options, 2, send_message_test, sizeof(State), &options); tox_options_free(tox_options); return 0; } c-toxcore-0.2.18/auto_tests/set_name_test.c0000777000175000017500000000672114227324767017734 0ustar robinrobin/* Tests that we can set our name. */ #include #include #include #include #include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" #define NICKNAME "Gentoo" static void nickchange_callback(Tox *tox, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata) { ck_assert_msg(length == sizeof(NICKNAME), "Name length not correct: %d != %d", (uint16_t)length, (uint16_t)sizeof(NICKNAME)); ck_assert_msg(memcmp(string, NICKNAME, sizeof(NICKNAME)) == 0, "Name not correct: %s", (const char *)string); bool *nickname_updated = (bool *)userdata; *nickname_updated = true; } static void test_set_name(void) { printf("initialising 2 toxes\n"); uint32_t index[] = { 1, 2 }; const time_t cur_time = time(nullptr); Tox *const tox1 = tox_new_log(nullptr, nullptr, &index[0]); Tox *const tox2 = tox_new_log(nullptr, nullptr, &index[1]); ck_assert_msg(tox1 && tox2, "failed to create 2 tox instances"); printf("tox1 adds tox2 as friend, tox2 adds tox1\n"); uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(tox2, public_key); tox_friend_add_norequest(tox1, public_key, nullptr); tox_self_get_public_key(tox1, public_key); tox_friend_add_norequest(tox2, public_key, nullptr); printf("bootstrapping tox2 off tox1\n"); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(tox1, dht_key); const uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr); tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr); do { tox_iterate(tox1, nullptr); tox_iterate(tox2, nullptr); c_sleep(ITERATION_INTERVAL); } while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE || tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE); printf("toxes are online, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); const time_t con_time = time(nullptr); do { tox_iterate(tox1, nullptr); tox_iterate(tox2, nullptr); c_sleep(ITERATION_INTERVAL); } while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP || tox_friend_get_connection_status(tox2, 0, nullptr) != TOX_CONNECTION_UDP); printf("tox clients connected took %lu seconds\n", (unsigned long)(time(nullptr) - con_time)); tox_callback_friend_name(tox2, nickchange_callback); Tox_Err_Set_Info err_n; bool ret = tox_self_set_name(tox1, (const uint8_t *)NICKNAME, sizeof(NICKNAME), &err_n); ck_assert_msg(ret && err_n == TOX_ERR_SET_INFO_OK, "tox_self_set_name failed because %d\n", err_n); bool nickname_updated = false; do { tox_iterate(tox1, nullptr); tox_iterate(tox2, &nickname_updated); c_sleep(ITERATION_INTERVAL); } while (!nickname_updated); ck_assert_msg(tox_friend_get_name_size(tox2, 0, nullptr) == sizeof(NICKNAME), "Name length not correct"); uint8_t temp_name[sizeof(NICKNAME)]; tox_friend_get_name(tox2, 0, temp_name, nullptr); ck_assert_msg(memcmp(temp_name, NICKNAME, sizeof(NICKNAME)) == 0, "Name not correct"); printf("test_set_name succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); tox_kill(tox1); tox_kill(tox2); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_set_name(); return 0; } c-toxcore-0.2.18/auto_tests/set_status_message_test.c0000777000175000017500000000716114227324767022042 0ustar robinrobin/* Tests that we can set our status message */ #include #include #include #include #include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" #define STATUS_MESSAGE "Installing Gentoo" static void status_callback(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length, void *user_data) { ck_assert_msg(length == sizeof(STATUS_MESSAGE) && memcmp(message, STATUS_MESSAGE, sizeof(STATUS_MESSAGE)) == 0, "incorrect data in status callback"); bool *status_updated = (bool *)user_data; *status_updated = true; } static void test_set_status_message(void) { printf("initialising 2 toxes\n"); uint32_t index[] = { 1, 2 }; const time_t cur_time = time(nullptr); Tox *const tox1 = tox_new_log(nullptr, nullptr, &index[0]); Tox *const tox2 = tox_new_log(nullptr, nullptr, &index[1]); ck_assert_msg(tox1 && tox2, "failed to create 2 tox instances"); printf("tox1 adds tox2 as friend, tox2 adds tox1\n"); uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(tox2, public_key); tox_friend_add_norequest(tox1, public_key, nullptr); tox_self_get_public_key(tox1, public_key); tox_friend_add_norequest(tox2, public_key, nullptr); printf("bootstrapping tox2 off tox1\n"); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(tox1, dht_key); const uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr); tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr); do { tox_iterate(tox1, nullptr); tox_iterate(tox2, nullptr); c_sleep(ITERATION_INTERVAL); } while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE || tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE); printf("toxes are online, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); const time_t con_time = time(nullptr); do { tox_iterate(tox1, nullptr); tox_iterate(tox2, nullptr); c_sleep(ITERATION_INTERVAL); } while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP || tox_friend_get_connection_status(tox2, 0, nullptr) != TOX_CONNECTION_UDP); printf("tox clients connected took %lu seconds\n", (unsigned long)(time(nullptr) - con_time)); Tox_Err_Set_Info err_n; tox_callback_friend_status_message(tox2, status_callback); bool ret = tox_self_set_status_message(tox1, (const uint8_t *)STATUS_MESSAGE, sizeof(STATUS_MESSAGE), &err_n); ck_assert_msg(ret && err_n == TOX_ERR_SET_INFO_OK, "tox_self_set_status_message failed because %d\n", err_n); bool status_updated = false; do { tox_iterate(tox1, nullptr); tox_iterate(tox2, &status_updated); c_sleep(ITERATION_INTERVAL); } while (!status_updated); ck_assert_msg(tox_friend_get_status_message_size(tox2, 0, nullptr) == sizeof(STATUS_MESSAGE), "status message length not correct"); uint8_t cmp_status[sizeof(STATUS_MESSAGE)]; tox_friend_get_status_message(tox2, 0, cmp_status, nullptr); ck_assert_msg(memcmp(cmp_status, STATUS_MESSAGE, sizeof(STATUS_MESSAGE)) == 0, "status message not correct"); printf("test_set_status_message succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); tox_kill(tox1); tox_kill(tox2); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_set_status_message(); return 0; } c-toxcore-0.2.18/auto_tests/tcp_relay_test.c0000777000175000017500000000164614227324767020124 0ustar robinrobin#include #include "../testing/misc_tools.h" #include "check_compat.h" #include "auto_test_support.h" int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); struct Tox_Options *opts = tox_options_new(nullptr); tox_options_set_udp_enabled(opts, false); Tox *tox_tcp = tox_new_log(opts, nullptr, nullptr); tox_options_free(opts); bootstrap_tox_live_network(tox_tcp, true); printf("Waiting for connection"); do { printf("."); fflush(stdout); tox_iterate(tox_tcp, nullptr); c_sleep(ITERATION_INTERVAL); } while (tox_self_get_connection_status(tox_tcp) == TOX_CONNECTION_NONE); const Tox_Connection status = tox_self_get_connection_status(tox_tcp); ck_assert_msg(status == TOX_CONNECTION_TCP, "expected TCP connection, but got %d", status); printf("Connection (TCP): %d\n", status); tox_kill(tox_tcp); return 0; } c-toxcore-0.2.18/auto_tests/TCP_test.c0000777000175000017500000011171514227324767016567 0ustar robinrobin#include #include #include #include "../testing/misc_tools.h" #include "../toxcore/TCP_client.h" #include "../toxcore/TCP_common.h" #include "../toxcore/TCP_server.h" #include "../toxcore/crypto_core.h" #include "../toxcore/mono_time.h" #include "../toxcore/util.h" #include "auto_test_support.h" #define NUM_PORTS 3 #ifndef USE_IPV6 #define USE_IPV6 1 #endif #if !USE_IPV6 #define net_family_ipv6 net_family_ipv4 #endif static IP get_loopback(void) { IP ip; #if USE_IPV6 ip.family = net_family_ipv6(); ip.ip.v6 = get_ip6_loopback(); #else ip.family = net_family_ipv4(); ip.ip.v4 = get_ip4_loopback(); #endif return ip; } static void do_TCP_server_delay(TCP_Server *tcp_s, Mono_Time *mono_time, int delay) { c_sleep(delay); mono_time_update(mono_time); do_TCP_server(tcp_s, mono_time); c_sleep(delay); } static uint16_t ports[NUM_PORTS] = {13215, 33445, 25643}; static void test_basic(void) { Mono_Time *mono_time = mono_time_new(nullptr, nullptr); const Random *rng = system_random(); ck_assert(rng != nullptr); Logger *logger = logger_new(); logger_callback_log(logger, (logger_cb *)print_debug_log, nullptr, nullptr); // Attempt to create a new TCP_Server instance. uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; crypto_new_keypair(rng, self_public_key, self_secret_key); const Network *ns = system_network(); 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_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind a TCP relay server to all %d attempted ports.", NUM_PORTS); Socket sock = {0}; IP_Port localhost; localhost.ip = get_loopback(); localhost.port = 0; // Check all opened ports for connectivity. for (uint8_t i = 0; i < NUM_PORTS; i++) { sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP); localhost.port = net_htons(ports[i]); bool ret = net_connect(logger, sock, &localhost); 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. if (i + 1 < NUM_PORTS) { kill_sock(ns, sock); } } // Key creation. uint8_t f_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t f_nonce[CRYPTO_NONCE_SIZE]; crypto_new_keypair(rng, f_public_key, f_secret_key); random_nonce(rng, f_nonce); // Generation of the initial handshake. uint8_t t_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t *handshake_plain = (uint8_t *)malloc(TCP_HANDSHAKE_PLAIN_SIZE); ck_assert(handshake_plain != nullptr); crypto_new_keypair(rng, handshake_plain, t_secret_key); memcpy(handshake_plain + CRYPTO_PUBLIC_KEY_SIZE, f_nonce, CRYPTO_NONCE_SIZE); uint8_t *handshake = (uint8_t *)malloc(TCP_CLIENT_HANDSHAKE_SIZE); ck_assert(handshake != nullptr); memcpy(handshake, f_public_key, CRYPTO_PUBLIC_KEY_SIZE); random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE); // Encrypting handshake int ret = encrypt_data(self_public_key, f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain, TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); ck_assert_msg(ret == TCP_CLIENT_HANDSHAKE_SIZE - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), "encrypt_data() call failed."); free(handshake_plain); // Sending the handshake ck_assert_msg(net_send(ns, logger, sock, handshake, TCP_CLIENT_HANDSHAKE_SIZE - 1, &localhost) == TCP_CLIENT_HANDSHAKE_SIZE - 1, "An attempt to send the initial handshake minus last byte failed."); do_TCP_server_delay(tcp_s, mono_time, 50); ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost) == 1, "The attempt to send the last byte of handshake failed."); free(handshake); do_TCP_server_delay(tcp_s, mono_time, 50); // Receiving server response and decrypting it uint8_t response[TCP_SERVER_HANDSHAKE_SIZE]; uint8_t response_plain[TCP_HANDSHAKE_PLAIN_SIZE]; ck_assert_msg(net_recv(ns, logger, sock, response, TCP_SERVER_HANDSHAKE_SIZE, &localhost) == TCP_SERVER_HANDSHAKE_SIZE, "Could/did not receive a server response to the initial handshake."); ret = decrypt_data(self_public_key, f_secret_key, response, response + CRYPTO_NONCE_SIZE, TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, response_plain); ck_assert_msg(ret == TCP_HANDSHAKE_PLAIN_SIZE, "Failed to decrypt handshake response."); uint8_t f_nonce_r[CRYPTO_NONCE_SIZE]; uint8_t f_shared_key[CRYPTO_SHARED_KEY_SIZE]; encrypt_precompute(response_plain, t_secret_key, f_shared_key); memcpy(f_nonce_r, response_plain + CRYPTO_SHARED_KEY_SIZE, CRYPTO_NONCE_SIZE); // Building a request uint8_t r_req_p[1 + CRYPTO_PUBLIC_KEY_SIZE]; r_req_p[0] = TCP_PACKET_ROUTING_REQUEST; memcpy(r_req_p + 1, f_public_key, CRYPTO_PUBLIC_KEY_SIZE); uint8_t r_req[2 + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE]; uint16_t size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE; size = net_htons(size); encrypt_data_symmetric(f_shared_key, f_nonce, r_req_p, 1 + CRYPTO_PUBLIC_KEY_SIZE, r_req + 2); increment_nonce(f_nonce); memcpy(r_req, &size, 2); // Sending the request at random intervals in random pieces. for (uint32_t i = 0; i < sizeof(r_req);) { uint8_t msg_length = rand() % 5 + 1; // msg_length = 1 to 5 if (i + msg_length >= sizeof(r_req)) { msg_length = sizeof(r_req) - i; } ck_assert_msg(net_send(ns, logger, sock, r_req + i, msg_length, &localhost) == msg_length, "Failed to send request after completing the handshake."); i += msg_length; c_sleep(50); mono_time_update(mono_time); do_TCP_server(tcp_s, mono_time); } // Receiving the second response and verifying its validity uint8_t packet_resp[4096]; int recv_data_len = net_recv(ns, logger, sock, packet_resp, 2 + 2 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, &localhost); ck_assert_msg(recv_data_len == 2 + 2 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, "Failed to receive server response to request. %d", recv_data_len); memcpy(&size, packet_resp, 2); ck_assert_msg(net_ntohs(size) == 2 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, "Wrong packet size for request response."); uint8_t packet_resp_plain[4096]; ret = decrypt_data_symmetric(f_shared_key, f_nonce_r, packet_resp + 2, recv_data_len - 2, packet_resp_plain); ck_assert_msg(ret != -1, "Failed to decrypt the TCP server's response."); increment_nonce(f_nonce_r); ck_assert_msg(packet_resp_plain[0] == TCP_PACKET_ROUTING_RESPONSE, "Server sent the wrong packet id: %u", packet_resp_plain[0]); ck_assert_msg(packet_resp_plain[1] == 0, "Server did not refuse the connection."); ck_assert_msg(pk_equal(packet_resp_plain + 2, f_public_key), "Server sent the wrong public key."); // Closing connections. kill_sock(ns, sock); kill_TCP_server(tcp_s); logger_kill(logger); mono_time_free(mono_time); } struct sec_TCP_con { Socket sock; const Network *ns; uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; uint8_t sent_nonce[CRYPTO_NONCE_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) { struct sec_TCP_con *sec_c = (struct sec_TCP_con *)malloc(sizeof(struct sec_TCP_con)); ck_assert(sec_c != nullptr); sec_c->ns = ns; Socket sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP); IP_Port localhost; localhost.ip = get_loopback(); localhost.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); bool ok = net_connect(logger, sock, &localhost); ck_assert_msg(ok, "Failed to connect to the test TCP relay server."); uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; crypto_new_keypair(rng, sec_c->public_key, f_secret_key); random_nonce(rng, sec_c->sent_nonce); uint8_t t_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t handshake_plain[TCP_HANDSHAKE_PLAIN_SIZE]; crypto_new_keypair(rng, handshake_plain, t_secret_key); memcpy(handshake_plain + CRYPTO_PUBLIC_KEY_SIZE, sec_c->sent_nonce, CRYPTO_NONCE_SIZE); uint8_t handshake[TCP_CLIENT_HANDSHAKE_SIZE]; memcpy(handshake, sec_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE); int ret = encrypt_data(tcp_server_public_key(tcp_s), f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain, TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); ck_assert_msg(ret == TCP_CLIENT_HANDSHAKE_SIZE - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), "Failed to encrypt the outgoing handshake."); ck_assert_msg(net_send(ns, logger, sock, handshake, TCP_CLIENT_HANDSHAKE_SIZE - 1, &localhost) == TCP_CLIENT_HANDSHAKE_SIZE - 1, "Failed to send the first portion of the handshake to the TCP relay server."); do_TCP_server_delay(tcp_s, mono_time, 50); ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost) == 1, "Failed to send last byte of handshake."); do_TCP_server_delay(tcp_s, mono_time, 50); uint8_t response[TCP_SERVER_HANDSHAKE_SIZE]; uint8_t response_plain[TCP_HANDSHAKE_PLAIN_SIZE]; ck_assert_msg(net_recv(sec_c->ns, logger, sock, response, TCP_SERVER_HANDSHAKE_SIZE, &localhost) == TCP_SERVER_HANDSHAKE_SIZE, "Failed to receive server handshake response."); ret = decrypt_data(tcp_server_public_key(tcp_s), f_secret_key, response, response + CRYPTO_NONCE_SIZE, TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, response_plain); ck_assert_msg(ret == TCP_HANDSHAKE_PLAIN_SIZE, "Failed to decrypt server handshake response."); encrypt_precompute(response_plain, t_secret_key, sec_c->shared_key); memcpy(sec_c->recv_nonce, response_plain + CRYPTO_SHARED_KEY_SIZE, CRYPTO_NONCE_SIZE); sec_c->sock = sock; return sec_c; } static void kill_TCP_con(struct sec_TCP_con *con) { kill_sock(con->ns, con->sock); free(con); } static int write_packet_TCP_test_connection(const Logger *logger, struct sec_TCP_con *con, const uint8_t *data, uint16_t length) { VLA(uint8_t, packet, sizeof(uint16_t) + length + CRYPTO_MAC_SIZE); uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE); memcpy(packet, &c_length, sizeof(uint16_t)); int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); if ((unsigned int)len != (SIZEOF_VLA(packet) - sizeof(uint16_t))) { return -1; } increment_nonce(con->sent_nonce); IP_Port localhost; localhost.ip = get_loopback(); localhost.port = 0; ck_assert_msg(net_send(con->ns, logger, con->sock, packet, SIZEOF_VLA(packet), &localhost) == SIZEOF_VLA(packet), "Failed to send a packet."); return 0; } static int read_packet_sec_TCP(const Logger *logger, struct sec_TCP_con *con, uint8_t *data, uint16_t length) { IP_Port localhost; localhost.ip = get_loopback(); localhost.port = 0; int rlen = net_recv(con->ns, logger, con->sock, data, length, &localhost); ck_assert_msg(rlen == length, "Did not receive packet of correct length. Wanted %i, instead got %i", length, rlen); rlen = decrypt_data_symmetric(con->shared_key, con->recv_nonce, data + 2, length - 2, data); ck_assert_msg(rlen != -1, "Failed to decrypt a received packet from the Relay server."); increment_nonce(con->recv_nonce); return rlen; } static void test_some(void) { Mono_Time *mono_time = mono_time_new(nullptr, nullptr); const Random *rng = system_random(); ck_assert(rng != nullptr); Logger *logger = logger_new(); const Network *ns = system_network(); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; 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); 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."); struct sec_TCP_con *con1 = new_TCP_con(logger, 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 *con3 = new_TCP_con(logger, rng, ns, tcp_s, mono_time); uint8_t requ_p[1 + CRYPTO_PUBLIC_KEY_SIZE]; requ_p[0] = TCP_PACKET_ROUTING_REQUEST; // Sending wrong public keys to test server response. memcpy(requ_p + 1, con3->public_key, CRYPTO_PUBLIC_KEY_SIZE); write_packet_TCP_test_connection(logger, con1, requ_p, sizeof(requ_p)); memcpy(requ_p + 1, con1->public_key, CRYPTO_PUBLIC_KEY_SIZE); write_packet_TCP_test_connection(logger, con3, requ_p, sizeof(requ_p)); do_TCP_server_delay(tcp_s, mono_time, 50); // Testing response from connection 1 uint8_t data[2048]; 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(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(pk_equal(data + 2, con3->public_key), "Key in response packet wrong."); // Connection 3 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(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(pk_equal(data + 2, con1->public_key), "Key in response packet wrong."); 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)); do_TCP_server_delay(tcp_s, mono_time, 50); 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(data[0] == TCP_PACKET_CONNECTION_NOTIFICATION, "wrong packet id %u", data[0]); 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); 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[1] == 16, "wrong peer id %u", data[1]); 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(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]); 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(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]); 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(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]); 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); 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(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]); 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(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]); 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(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]); 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)); do_TCP_server_delay(tcp_s, mono_time, 50); 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(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"); // Kill off the connections kill_TCP_server(tcp_s); kill_TCP_con(con1); kill_TCP_con(con2); kill_TCP_con(con3); logger_kill(logger); mono_time_free(mono_time); } static int response_callback_good; static uint8_t response_callback_connection_id; static uint8_t response_callback_public_key[CRYPTO_PUBLIC_KEY_SIZE]; static int response_callback(void *object, uint8_t connection_id, const uint8_t *public_key) { if (set_tcp_connection_number((TCP_Client_Connection *)(void *)((char *)object - 2), connection_id, 7) != 0) { return 1; } response_callback_connection_id = connection_id; memcpy(response_callback_public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); response_callback_good++; return 0; } static int status_callback_good; static uint8_t status_callback_connection_id; static uint8_t status_callback_status; static int status_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t status) { if (object != (void *)2) { return 1; } if (number != 7) { return 1; } status_callback_connection_id = connection_id; status_callback_status = status; status_callback_good++; return 0; } static int data_callback_good; static int data_callback(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, uint16_t length, void *userdata) { if (object != (void *)3) { return 1; } if (number != 7) { return 1; } if (length != 5) { return 1; } if (data[0] == 1 && data[1] == 2 && data[2] == 3 && data[3] == 4 && data[4] == 5) { data_callback_good++; return 0; } return 1; } static int oob_data_callback_good; static uint8_t oob_pubkey[CRYPTO_PUBLIC_KEY_SIZE]; static int oob_data_callback(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata) { if (object != (void *)4) { return 1; } if (length != 5) { return 1; } if (!pk_equal(public_key, oob_pubkey)) { return 1; } if (data[0] == 1 && data[1] == 2 && data[2] == 3 && data[3] == 4 && data[4] == 5) { oob_data_callback_good++; return 0; } return 1; } static void test_client(void) { Mono_Time *mono_time = mono_time_new(nullptr, nullptr); const Random *rng = system_random(); ck_assert(rng != nullptr); Logger *logger = logger_new(); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; crypto_new_keypair(rng, self_public_key, self_secret_key); const Network *ns = system_network(); 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_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind the relay server to all ports."); uint8_t f_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; crypto_new_keypair(rng, f_public_key, f_secret_key); IP_Port ip_port_tcp_s; ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.ip = get_loopback(); TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr); do_TCP_connection(logger, mono_time, conn, nullptr); c_sleep(50); // The connection status should be unconfirmed here because we have finished // sending our data and are awaiting a response. ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_UNCONFIRMED, "Wrong connection status. Expected: %d, is: %d.", TCP_CLIENT_UNCONFIRMED, tcp_con_status(conn)); do_TCP_server_delay(tcp_s, mono_time, 50); // Now let the server handle requests... const uint8_t LOOP_SIZE = 3; for (uint8_t i = 0; i < LOOP_SIZE; i++) { mono_time_update(mono_time); 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. ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_CONFIRMED, "Wrong connection status. Expected: %d, is: %d", TCP_CLIENT_CONFIRMED, tcp_con_status(conn)); 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); // 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, tcp_con_status(conn)); uint8_t f2_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t f2_secret_key[CRYPTO_SECRET_KEY_SIZE]; crypto_new_keypair(rng, f2_public_key, f2_secret_key); ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); TCP_Client_Connection *conn2 = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key, f2_secret_key, nullptr); // The client should call this function (defined earlier) during the routing process. routing_response_handler(conn, response_callback, (char *)conn + 2); // The client should call this function when it receives a connection notification. routing_status_handler(conn, status_callback, (void *)2); // The client should call this function when routing_data_handler(conn, data_callback, (void *)3); // The client should call this function when sending out of band packets. oob_data_handler(conn, oob_data_callback, (void *)4); // These integers will increment per successful callback. 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, conn2, nullptr); do_TCP_server_delay(tcp_s, mono_time, 50); do_TCP_connection(logger, mono_time, conn, nullptr); do_TCP_connection(logger, mono_time, conn2, nullptr); c_sleep(50); uint8_t data[5] = {1, 2, 3, 4, 5}; memcpy(oob_pubkey, f2_public_key, CRYPTO_PUBLIC_KEY_SIZE); send_oob_packet(logger, conn2, f_public_key, data, 5); send_routing_request(logger, conn, f2_public_key); send_routing_request(logger, conn2, f_public_key); do_TCP_server_delay(tcp_s, mono_time, 50); do_TCP_connection(logger, mono_time, conn, nullptr); do_TCP_connection(logger, mono_time, conn2, nullptr); // 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(response_callback_good == 1, "Response callback not called."); ck_assert_msg(pk_equal(response_callback_public_key, f2_public_key), "Wrong public key."); ck_assert_msg(status_callback_good == 1, "Status callback not called."); ck_assert_msg(status_callback_status == 2, "Wrong status callback status."); ck_assert_msg(status_callback_connection_id == response_callback_connection_id, "Status and response callback connection IDs are not equal."); 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."); do_TCP_server_delay(tcp_s, mono_time, 50); do_TCP_connection(logger, mono_time, conn, nullptr); do_TCP_connection(logger, mono_time, conn2, nullptr); ck_assert_msg(data_callback_good == 1, "Data callback was not called."); status_callback_good = 0; send_disconnect_request(logger, conn2, 0); do_TCP_server_delay(tcp_s, mono_time, 50); do_TCP_connection(logger, mono_time, conn, 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_status == 1, "Wrong status callback status."); // Kill off all connections and servers. kill_TCP_server(tcp_s); kill_TCP_connection(conn); kill_TCP_connection(conn2); logger_kill(logger); mono_time_free(mono_time); } // Test how the client handles servers that don't respond. static void test_client_invalid(void) { Mono_Time *mono_time = mono_time_new(nullptr, nullptr); const Random *rng = system_random(); ck_assert(rng != nullptr); Logger *logger = logger_new(); const Network *ns = system_network(); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; crypto_new_keypair(rng, self_public_key, self_secret_key); uint8_t f_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; crypto_new_keypair(rng, f_public_key, f_secret_key); IP_Port ip_port_tcp_s; ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.ip = get_loopback(); TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr); // Run the client's main loop but not the server. mono_time_update(mono_time); do_TCP_connection(logger, mono_time, conn, nullptr); c_sleep(50); // After 50ms of no response... ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_CONNECTING, "Wrong status. Expected: %d, is: %d.", TCP_CLIENT_CONNECTING, tcp_con_status(conn)); // After 5s... c_sleep(5000); mono_time_update(mono_time); do_TCP_connection(logger, mono_time, conn, nullptr); ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_CONNECTING, "Wrong status. Expected: %d, is: %d.", TCP_CLIENT_CONNECTING, tcp_con_status(conn)); // 11s... (Should wait for 10 before giving up.) c_sleep(6000); mono_time_update(mono_time); do_TCP_connection(logger, mono_time, conn, nullptr); ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_DISCONNECTED, "Wrong status. Expected: %d, is: %d.", TCP_CLIENT_DISCONNECTED, tcp_con_status(conn)); kill_TCP_connection(conn); logger_kill(logger); mono_time_free(mono_time); } #include "../toxcore/TCP_connection.h" static bool tcp_data_callback_called; static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t length, void *userdata) { if (object != (void *)120397) { return -1; } if (id != 123) { return -1; } if (length != 6) { return -1; } if (memcmp(data, "Gentoo", length) != 0) { return -1; } tcp_data_callback_called = 1; return 0; } static void test_tcp_connection(void) { Mono_Time *mono_time = mono_time_new(nullptr, nullptr); Logger *logger = logger_new(); const Random *rng = system_random(); ck_assert(rng != nullptr); const Network *ns = system_network(); tcp_data_callback_called = 0; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; 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); ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key"); TCP_Proxy_Info proxy_info; proxy_info.proxy_type = TCP_PROXY_NONE; 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); 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); TCP_Connections *tc_2 = new_tcp_connections(logger, 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"); IP_Port ip_port_tcp_s; ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.ip = get_loopback(); int connection = new_tcp_connection_to(tc_1, tcp_connections_public_key(tc_2), 123); ck_assert_msg(connection == 0, "Connection id wrong"); ck_assert_msg(add_tcp_relay_connection(tc_1, connection, &ip_port_tcp_s, tcp_server_public_key(tcp_s)) == 0, "Could not add tcp relay to connection\n"); ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); connection = new_tcp_connection_to(tc_2, tcp_connections_public_key(tc_1), 123); ck_assert_msg(connection == 0, "Connection id wrong"); ck_assert_msg(add_tcp_relay_connection(tc_2, connection, &ip_port_tcp_s, tcp_server_public_key(tcp_s)) == 0, "Could not add tcp relay to connection\n"); ck_assert_msg(new_tcp_connection_to(tc_2, tcp_connections_public_key(tc_1), 123) == -1, "Managed to read same connection\n"); do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_2, nullptr); do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_2, nullptr); do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_2, nullptr); int ret = send_packet_tcp_connection(tc_1, 0, (const uint8_t *)"Gentoo", 6); ck_assert_msg(ret == 0, "could not send packet."); set_packet_tcp_connection_callback(tc_2, &tcp_data_callback, (void *) 120397); do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_2, nullptr); ck_assert_msg(tcp_data_callback_called, "could not recv packet."); 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"); do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_2, nullptr); 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"); kill_TCP_server(tcp_s); kill_tcp_connections(tc_1); kill_tcp_connections(tc_2); logger_kill(logger); mono_time_free(mono_time); } static bool tcp_oobdata_callback_called; static int tcp_oobdata_callback(void *object, const uint8_t *public_key, unsigned int id, const uint8_t *data, uint16_t length, void *userdata) { const TCP_Connections *tcp_c = (const TCP_Connections *)object; if (length != 6) { return -1; } if (memcmp(data, "Gentoo", length) != 0) { return -1; } if (tcp_send_oob_packet(tcp_c, id, public_key, data, length) == 0) { tcp_oobdata_callback_called = 1; } return 0; } static void test_tcp_connection2(void) { Mono_Time *mono_time = mono_time_new(nullptr, nullptr); Logger *logger = logger_new(); const Random *rng = system_random(); ck_assert(rng != nullptr); const Network *ns = system_network(); tcp_oobdata_callback_called = 0; tcp_data_callback_called = 0; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; 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); ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key"); TCP_Proxy_Info proxy_info; proxy_info.proxy_type = TCP_PROXY_NONE; 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); 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); TCP_Connections *tc_2 = new_tcp_connections(logger, 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"); IP_Port ip_port_tcp_s; ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.ip = get_loopback(); int connection = new_tcp_connection_to(tc_1, tcp_connections_public_key(tc_2), 123); ck_assert_msg(connection == 0, "Connection id wrong"); ck_assert_msg(add_tcp_relay_connection(tc_1, connection, &ip_port_tcp_s, tcp_server_public_key(tcp_s)) == 0, "Could not add tcp relay to connection\n"); 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"); do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_2, nullptr); do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_2, nullptr); do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_2, nullptr); int ret = send_packet_tcp_connection(tc_1, 0, (const uint8_t *)"Gentoo", 6); ck_assert_msg(ret == 0, "could not send packet."); 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); do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_2, nullptr); ck_assert_msg(tcp_oobdata_callback_called, "could not recv packet."); do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_2, nullptr); 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"); kill_TCP_server(tcp_s); kill_tcp_connections(tc_1); kill_tcp_connections(tc_2); logger_kill(logger); mono_time_free(mono_time); } static void TCP_suite(void) { test_basic(); test_some(); test_client(); test_client_invalid(); test_tcp_connection(); test_tcp_connection2(); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); TCP_suite(); return 0; } c-toxcore-0.2.18/auto_tests/toxav_basic_test.c0000777000175000017500000004060514227324767020442 0ustar robinrobin#include #include #include #include #include #include "../testing/misc_tools.h" #include "../toxav/toxav.h" #include "../toxcore/crypto_core.h" #include "../toxcore/logger.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" #define TEST_REGULAR_AV 1 #define TEST_REGULAR_A 1 #define TEST_REGULAR_V 1 #define TEST_REJECT 1 #define TEST_CANCEL 1 #define TEST_MUTE_UNMUTE 1 #define TEST_STOP_RESUME_PAYLOAD 1 #define TEST_PAUSE_RESUME_SEND 1 #define ck_assert_call_control(a, b, c) do { \ Toxav_Err_Call_Control cc_err; \ bool ok = toxav_call_control(a, b, c, &cc_err); \ if (!ok) { \ printf("toxav_call_control returned error %d\n", cc_err); \ } \ ck_assert(ok); \ ck_assert(cc_err == TOXAV_ERR_CALL_CONTROL_OK); \ } while (0) typedef struct { bool incoming; uint32_t state; } CallControl; static void clear_call_control(CallControl *cc) { const CallControl empty = {0}; *cc = empty; } /** * Callbacks */ static void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data) { printf("Handling CALL callback\n"); ((CallControl *)user_data)->incoming = true; } static void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data) { printf("Handling CALL STATE callback: %u\n", state); ((CallControl *)user_data)->state = state; } static void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number, uint16_t width, uint16_t height, uint8_t const *y, uint8_t const *u, uint8_t const *v, int32_t ystride, int32_t ustride, int32_t vstride, void *user_data) { printf("Received video payload\n"); } static void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number, int16_t const *pcm, size_t sample_count, uint8_t channels, uint32_t sampling_rate, void *user_data) { printf("Received audio payload\n"); } static void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) { if (length == 7 && memcmp("gentoo", data, 7) == 0) { ck_assert(tox_friend_add_norequest(m, public_key, nullptr) != (uint32_t) -1); } } /** * Iterate helper */ static void iterate_tox(Tox *bootstrap, Tox *Alice, Tox *Bob) { c_sleep(100); tox_iterate(bootstrap, nullptr); tox_iterate(Alice, nullptr); tox_iterate(Bob, nullptr); } 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}; return toxav_audio_send_frame(av, 0, PCM, 960, 1, 48000, nullptr); } static void regular_call_flow( Tox *Alice, Tox *Bob, Tox *bootstrap, ToxAV *AliceAV, ToxAV *BobAV, CallControl *AliceCC, CallControl *BobCC, int a_br, int v_br) { clear_call_control(AliceCC); clear_call_control(BobCC); Toxav_Err_Call call_err; toxav_call(AliceAV, 0, a_br, v_br, &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); do { if (BobCC->incoming) { Toxav_Err_Answer answer_err; toxav_answer(BobAV, 0, a_br, v_br, &answer_err); ck_assert_msg(answer_err == TOXAV_ERR_ANSWER_OK, "toxav_answer failed: %d\n", answer_err); BobCC->incoming = false; } else { /* TODO(mannol): rtp */ if (time(nullptr) - start_time >= 1) { Toxav_Err_Call_Control cc_err; toxav_call_control(AliceAV, 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); } } iterate_tox(bootstrap, Alice, Bob); } while (BobCC->state != TOXAV_FRIEND_CALL_STATE_FINISHED); printf("Success!\n"); } static void test_av_flows(void) { Tox *Alice, *Bob, *bootstrap; ToxAV *AliceAV, *BobAV; uint32_t index[] = { 1, 2, 3 }; CallControl AliceCC, BobCC; { Tox_Err_New error; bootstrap = tox_new_log(nullptr, &error, &index[0]); ck_assert(error == TOX_ERR_NEW_OK); Alice = tox_new_log(nullptr, &error, &index[1]); ck_assert(error == TOX_ERR_NEW_OK); Bob = tox_new_log(nullptr, &error, &index[2]); ck_assert(error == TOX_ERR_NEW_OK); } printf("Created 3 instances of Tox\n"); printf("Preparing network...\n"); long long unsigned int cur_time = time(nullptr); uint8_t address[TOX_ADDRESS_SIZE]; tox_callback_friend_request(Alice, t_accept_friend_request_cb); tox_self_get_address(Alice, address); printf("bootstrapping Alice and Bob off a third bootstrap node\n"); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(bootstrap, dht_key); const uint16_t dht_port = tox_self_get_udp_port(bootstrap, nullptr); tox_bootstrap(Alice, "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); uint8_t off = 1; while (true) { iterate_tox(bootstrap, Alice, Bob); if (tox_self_get_connection_status(bootstrap) && tox_self_get_connection_status(Alice) && tox_self_get_connection_status(Bob) && off) { printf("Toxes are online, took %llu seconds\n", time(nullptr) - cur_time); off = 0; } if (tox_friend_get_connection_status(Alice, 0, nullptr) == TOX_CONNECTION_UDP && tox_friend_get_connection_status(Bob, 0, nullptr) == TOX_CONNECTION_UDP) { break; } c_sleep(20); } { Toxav_Err_New error; AliceAV = toxav_new(Alice, &error); ck_assert(error == TOXAV_ERR_NEW_OK); BobAV = toxav_new(Bob, &error); ck_assert(error == TOXAV_ERR_NEW_OK); } toxav_callback_call(AliceAV, t_toxav_call_cb, &AliceCC); toxav_callback_call_state(AliceAV, t_toxav_call_state_cb, &AliceCC); toxav_callback_video_receive_frame(AliceAV, t_toxav_receive_video_frame_cb, &AliceCC); toxav_callback_audio_receive_frame(AliceAV, t_toxav_receive_audio_frame_cb, &AliceCC); toxav_callback_call(BobAV, t_toxav_call_cb, &BobCC); toxav_callback_call_state(BobAV, t_toxav_call_state_cb, &BobCC); toxav_callback_video_receive_frame(BobAV, t_toxav_receive_video_frame_cb, &BobCC); toxav_callback_audio_receive_frame(BobAV, t_toxav_receive_audio_frame_cb, &BobCC); printf("Created 2 instances of ToxAV\n"); printf("All set after %llu seconds!\n", time(nullptr) - cur_time); if (TEST_REGULAR_AV) { printf("\nTrying regular call (Audio and Video)...\n"); regular_call_flow(Alice, Bob, bootstrap, AliceAV, BobAV, &AliceCC, &BobCC, 48, 4000); } if (TEST_REGULAR_A) { printf("\nTrying regular call (Audio only)...\n"); regular_call_flow(Alice, Bob, bootstrap, AliceAV, BobAV, &AliceCC, &BobCC, 48, 0); } if (TEST_REGULAR_V) { printf("\nTrying regular call (Video only)...\n"); regular_call_flow(Alice, Bob, bootstrap, AliceAV, BobAV, &AliceCC, &BobCC, 0, 4000); } if (TEST_REJECT) { /* Alice calls; Bob rejects */ printf("\nTrying reject flow...\n"); clear_call_control(&AliceCC); clear_call_control(&BobCC); { Toxav_Err_Call rc; toxav_call(AliceAV, 0, 48, 0, &rc); ck_assert_msg(rc == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", rc); } do { iterate_tox(bootstrap, Alice, Bob); } while (!BobCC.incoming); /* Reject */ { Toxav_Err_Call_Control rc; toxav_call_control(BobAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); ck_assert_msg(rc == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", rc); } do { iterate_tox(bootstrap, Alice, Bob); } while (AliceCC.state != TOXAV_FRIEND_CALL_STATE_FINISHED); printf("Success!\n"); } if (TEST_CANCEL) { /* Alice calls; Alice cancels while ringing */ printf("\nTrying cancel (while ringing) flow...\n"); clear_call_control(&AliceCC); clear_call_control(&BobCC); { Toxav_Err_Call rc; toxav_call(AliceAV, 0, 48, 0, &rc); ck_assert_msg(rc == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", rc); } do { iterate_tox(bootstrap, Alice, Bob); } while (!BobCC.incoming); /* Cancel */ { Toxav_Err_Call_Control rc; toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); ck_assert_msg(rc == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", rc); } /* Alice will not receive end state */ do { iterate_tox(bootstrap, Alice, Bob); } while (BobCC.state != TOXAV_FRIEND_CALL_STATE_FINISHED); printf("Success!\n"); } if (TEST_MUTE_UNMUTE) { /* Check Mute-Unmute etc */ printf("\nTrying mute functionality...\n"); clear_call_control(&AliceCC); clear_call_control(&BobCC); /* Assume sending audio and video */ { Toxav_Err_Call rc; toxav_call(AliceAV, 0, 48, 1000, &rc); ck_assert_msg(rc == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", rc); } do { iterate_tox(bootstrap, Alice, Bob); } while (!BobCC.incoming); /* 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(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, nullptr)); ck_assert(!toxav_call_control(AliceAV, 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(AliceAV, 0, TOXAV_CALL_CONTROL_HIDE_VIDEO, nullptr)); ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_SHOW_VIDEO, nullptr)); { Toxav_Err_Answer rc; toxav_answer(BobAV, 0, 48, 4000, &rc); ck_assert_msg(rc == TOXAV_ERR_ANSWER_OK, "toxav_answer failed: %d\n", rc); } iterate_tox(bootstrap, Alice, Bob); /* Pause and Resume */ printf("Pause and Resume\n"); ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE); iterate_tox(bootstrap, Alice, Bob); ck_assert(BobCC.state == 0); ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME); iterate_tox(bootstrap, Alice, Bob); ck_assert(BobCC.state & (TOXAV_FRIEND_CALL_STATE_SENDING_A | TOXAV_FRIEND_CALL_STATE_SENDING_V)); /* Mute/Unmute single */ printf("Mute/Unmute single\n"); ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO); iterate_tox(bootstrap, Alice, Bob); ck_assert(BobCC.state ^ TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO); iterate_tox(bootstrap, Alice, Bob); ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); /* Mute/Unmute both */ printf("Mute/Unmute both\n"); ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO); iterate_tox(bootstrap, Alice, Bob); ck_assert(BobCC.state ^ TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_HIDE_VIDEO); iterate_tox(bootstrap, Alice, Bob); ck_assert(BobCC.state ^ TOXAV_FRIEND_CALL_STATE_ACCEPTING_V); ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO); iterate_tox(bootstrap, Alice, Bob); ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_SHOW_VIDEO); iterate_tox(bootstrap, Alice, Bob); ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V); { Toxav_Err_Call_Control rc; toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); ck_assert_msg(rc == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", rc); } iterate_tox(bootstrap, Alice, Bob); ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); printf("Success!\n"); } if (TEST_STOP_RESUME_PAYLOAD) { /* Stop and resume audio/video payload */ printf("\nTrying stop/resume functionality...\n"); clear_call_control(&AliceCC); clear_call_control(&BobCC); /* Assume sending audio and video */ { Toxav_Err_Call rc; toxav_call(AliceAV, 0, 48, 0, &rc); ck_assert_msg(rc == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", rc); } do { iterate_tox(bootstrap, Alice, Bob); } while (!BobCC.incoming); { Toxav_Err_Answer rc; toxav_answer(BobAV, 0, 48, 0, &rc); ck_assert_msg(rc == TOXAV_ERR_ANSWER_OK, "toxav_answer failed: %d\n", rc); } iterate_tox(bootstrap, Alice, Bob); printf("Call started as audio only\n"); printf("Turning on video for Alice...\n"); ck_assert(toxav_video_set_bit_rate(AliceAV, 0, 1000, nullptr)); iterate_tox(bootstrap, Alice, Bob); ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V); printf("Turning off video for Alice...\n"); ck_assert(toxav_video_set_bit_rate(AliceAV, 0, 0, nullptr)); iterate_tox(bootstrap, Alice, Bob); ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V)); printf("Turning off audio for Alice...\n"); ck_assert(toxav_audio_set_bit_rate(AliceAV, 0, 0, nullptr)); iterate_tox(bootstrap, Alice, Bob); ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_A)); { Toxav_Err_Call_Control rc; toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); ck_assert_msg(rc == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", rc); } iterate_tox(bootstrap, Alice, Bob); ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); printf("Success!\n"); } if (TEST_PAUSE_RESUME_SEND) { /* Stop and resume audio/video payload and test send options */ printf("\nTrying stop/resume functionality...\n"); clear_call_control(&AliceCC); clear_call_control(&BobCC); /* Assume sending audio and video */ { Toxav_Err_Call rc; toxav_call(AliceAV, 0, 48, 0, &rc); ck_assert_msg(rc == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", rc); } do { iterate_tox(bootstrap, Alice, Bob); } while (!BobCC.incoming); { Toxav_Err_Answer rc; toxav_answer(BobAV, 0, 48, 0, &rc); ck_assert_msg(rc == TOXAV_ERR_ANSWER_OK, "toxav_answer failed: %d\n", rc); } iterate_tox(bootstrap, Alice, Bob); ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE); iterate_tox(bootstrap, Alice, Bob); ck_assert(!toxav_audio_send_frame_helper(AliceAV, 0, nullptr)); ck_assert(!toxav_audio_send_frame_helper(BobAV, 0, nullptr)); ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME); iterate_tox(bootstrap, Alice, Bob); ck_assert(toxav_audio_send_frame_helper(AliceAV, 0, nullptr)); ck_assert(toxav_audio_send_frame_helper(BobAV, 0, nullptr)); iterate_tox(bootstrap, Alice, Bob); { Toxav_Err_Call_Control rc; toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); ck_assert_msg(rc == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", rc); } iterate_tox(bootstrap, Alice, Bob); ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); printf("Success!\n"); } toxav_kill(BobAV); toxav_kill(AliceAV); tox_kill(Bob); tox_kill(Alice); tox_kill(bootstrap); printf("\nTest successful!\n"); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_av_flows(); return 0; } c-toxcore-0.2.18/auto_tests/toxav_many_test.c0000777000175000017500000002666614227324767020340 0ustar robinrobin#include #include #include #include #include #include #if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) #include #endif #include #include "../testing/misc_tools.h" #include "../toxav/toxav.h" #include "../toxcore/crypto_core.h" #include "../toxcore/logger.h" #include "../toxcore/tox.h" #include "../toxcore/tox_struct.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" typedef struct { bool incoming; uint32_t state; } CallControl; typedef struct { ToxAV *AliceAV; ToxAV *BobAV; CallControl *AliceCC; CallControl *BobCC; uint32_t friend_number; } thread_data; /** * Callbacks */ static void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data) { printf("Handling CALL callback\n"); ((CallControl *)user_data)[friend_number].incoming = true; } static void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data) { printf("Handling CALL STATE callback: %u %p\n", state, (void *)av); ((CallControl *)user_data)[friend_number].state = state; } static void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number, uint16_t width, uint16_t height, uint8_t const *y, uint8_t const *u, uint8_t const *v, int32_t ystride, int32_t ustride, int32_t vstride, void *user_data) { } static void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number, int16_t const *pcm, size_t sample_count, uint8_t channels, uint32_t sampling_rate, void *user_data) { } static void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) { if (length == 7 && memcmp("gentoo", data, 7) == 0) { ck_assert(tox_friend_add_norequest(m, public_key, nullptr) != (uint32_t) -1); } } /** * Iterate helper */ static ToxAV *setup_av_instance(Tox *tox, CallControl *CC) { Toxav_Err_New error; ToxAV *av = toxav_new(tox, &error); ck_assert(error == TOXAV_ERR_NEW_OK); toxav_callback_call(av, t_toxav_call_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_audio_receive_frame(av, t_toxav_receive_audio_frame_cb, CC); return av; } static void *call_thread(void *pd) { ToxAV *AliceAV = ((thread_data *) pd)->AliceAV; ToxAV *BobAV = ((thread_data *) pd)->BobAV; uint32_t friend_number = ((thread_data *) pd)->friend_number; 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_u = (uint8_t *)calloc(800 * 600 / 4, sizeof(uint8_t)); uint8_t *video_v = (uint8_t *)calloc(800 * 600 / 4, sizeof(uint8_t)); time_t start_time = time(nullptr); do { toxav_iterate(AliceAV); toxav_iterate(BobAV); toxav_audio_send_frame(AliceAV, friend_number, PCM, 960, 1, 48000, nullptr); toxav_audio_send_frame(BobAV, 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(BobAV, 0, 800, 600, video_y, video_u, video_v, nullptr); c_sleep(10); } while (time(nullptr) - start_time < 4); free(PCM); free(video_y); free(video_u); free(video_v); printf("Closing thread\n"); pthread_exit(nullptr); return nullptr; } typedef struct Time_Data { pthread_mutex_t lock; uint64_t clock; } Time_Data; static uint64_t get_state_clock_callback(void *user_data) { Time_Data *time_data = (Time_Data *)user_data; pthread_mutex_lock(&time_data->lock); uint64_t clock = time_data->clock; pthread_mutex_unlock(&time_data->lock); return clock; } static void increment_clock(Time_Data *time_data, uint64_t count) { pthread_mutex_lock(&time_data->lock); time_data->clock += count; pthread_mutex_unlock(&time_data->lock); } static void set_current_time_callback(Tox *tox, Time_Data *time_data) { Mono_Time *mono_time = tox->mono_time; mono_time_set_current_time_callback(mono_time, get_state_clock_callback, time_data); } static void test_av_three_calls(void) { uint32_t index[] = { 1, 2, 3, 4, 5 }; Tox *Alice, *bootstrap, *Bobs[3]; ToxAV *AliceAV, *BobsAV[3]; void *retval; CallControl AliceCC[3], BobsCC[3]; Time_Data time_data; pthread_mutex_init(&time_data.lock, nullptr); { Tox_Err_New error; bootstrap = tox_new_log(nullptr, &error, &index[0]); ck_assert(error == TOX_ERR_NEW_OK); time_data.clock = current_time_monotonic(bootstrap->mono_time); set_current_time_callback(bootstrap, &time_data); Alice = tox_new_log(nullptr, &error, &index[1]); ck_assert(error == TOX_ERR_NEW_OK); set_current_time_callback(Alice, &time_data); Bobs[0] = tox_new_log(nullptr, &error, &index[2]); ck_assert(error == TOX_ERR_NEW_OK); set_current_time_callback(Bobs[0], &time_data); Bobs[1] = tox_new_log(nullptr, &error, &index[3]); ck_assert(error == TOX_ERR_NEW_OK); set_current_time_callback(Bobs[1], &time_data); Bobs[2] = tox_new_log(nullptr, &error, &index[4]); ck_assert(error == TOX_ERR_NEW_OK); set_current_time_callback(Bobs[2], &time_data); } printf("Created 5 instances of Tox\n"); printf("Preparing network...\n"); time_t cur_time = time(nullptr); uint8_t address[TOX_ADDRESS_SIZE]; tox_callback_friend_request(Alice, t_accept_friend_request_cb); tox_self_get_address(Alice, address); printf("bootstrapping Alice and the %u Bobs off a third bootstrap node\n", (unsigned)(sizeof(Bobs) / sizeof(Bobs[0]))); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(bootstrap, dht_key); const uint16_t dht_port = tox_self_get_udp_port(bootstrap, nullptr); tox_bootstrap(Alice, "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[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[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); uint8_t off = 1; while (true) { tox_iterate(bootstrap, nullptr); tox_iterate(Alice, nullptr); tox_iterate(Bobs[0], nullptr); tox_iterate(Bobs[1], nullptr); tox_iterate(Bobs[2], nullptr); if (tox_self_get_connection_status(bootstrap) && tox_self_get_connection_status(Alice) && tox_self_get_connection_status(Bobs[0]) && tox_self_get_connection_status(Bobs[1]) && tox_self_get_connection_status(Bobs[2]) && off) { printf("Toxes are online, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); off = 0; } 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, 2, 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[2], 0, nullptr) == TOX_CONNECTION_UDP) { break; } increment_clock(&time_data, 200); c_sleep(5); } AliceAV = setup_av_instance(Alice, AliceCC); BobsAV[0] = setup_av_instance(Bobs[0], &BobsCC[0]); BobsAV[1] = setup_av_instance(Bobs[1], &BobsCC[1]); BobsAV[2] = setup_av_instance(Bobs[2], &BobsCC[2]); printf("Created 4 instances of ToxAV\n"); printf("All set after %lu seconds!\n", (unsigned long)(time(nullptr) - cur_time)); thread_data tds[3]; for (size_t i = 0; i < 3; i++) { tds[i].AliceAV = AliceAV; tds[i].BobAV = BobsAV[i]; tds[i].AliceCC = &AliceCC[i]; tds[i].BobCC = &BobsCC[i]; tds[i].friend_number = i; memset(tds[i].AliceCC, 0, sizeof(CallControl)); memset(tds[i].BobCC, 0, sizeof(CallControl)); } pthread_t tids[3]; for (size_t i = 0; i < 3; i++) { (void) pthread_create(&tids[i], nullptr, call_thread, &tds[i]); } time_t start_time = time(nullptr); do { tox_iterate(bootstrap, nullptr); tox_iterate(Alice, nullptr); tox_iterate(Bobs[0], nullptr); tox_iterate(Bobs[1], nullptr); tox_iterate(Bobs[2], nullptr); increment_clock(&time_data, 100); c_sleep(5); } while (time(nullptr) - start_time < 1); /* Call */ for (size_t i = 0; i < 3; i++) { Toxav_Err_Call rc; toxav_call(AliceAV, tds[i].friend_number, 48, 3000, &rc); if (rc != TOXAV_ERR_CALL_OK) { printf("toxav_call failed: %d\n", rc); ck_assert(0); } } do { tox_iterate(bootstrap, nullptr); tox_iterate(Alice, nullptr); tox_iterate(Bobs[0], nullptr); tox_iterate(Bobs[1], nullptr); tox_iterate(Bobs[2], nullptr); for (size_t i = 0; i < 3; i++) { if (BobsCC[i].incoming) { /* Answer */ Toxav_Err_Answer rc; toxav_answer(BobsAV[i], 0, 8, 500, &rc); if (rc != TOXAV_ERR_ANSWER_OK) { printf("toxav_answer failed: %d\n", rc); ck_assert(0); } BobsCC[i].incoming = false; } } increment_clock(&time_data, 100); c_sleep(5); } while (time(nullptr) - start_time < 3); /* Hangup */ for (size_t i = 0; i < 3; i++) { Toxav_Err_Call_Control rc; toxav_call_control(AliceAV, i, TOXAV_CALL_CONTROL_CANCEL, &rc); if (rc != TOXAV_ERR_CALL_CONTROL_OK) { printf("toxav_call_control failed: %d %p %p\n", rc, (void *)AliceAV, (void *)&BobsAV[i]); } } do { tox_iterate(bootstrap, nullptr); tox_iterate(Alice, nullptr); tox_iterate(Bobs[0], nullptr); tox_iterate(Bobs[1], nullptr); tox_iterate(Bobs[2], nullptr); increment_clock(&time_data, 100); c_sleep(5); } while (time(nullptr) - start_time < 5); ck_assert(pthread_join(tids[0], &retval) == 0); ck_assert(retval == nullptr); ck_assert(pthread_join(tids[1], &retval) == 0); ck_assert(retval == nullptr); ck_assert(pthread_join(tids[2], &retval) == 0); ck_assert(retval == nullptr); printf("Killing all instances\n"); toxav_kill(BobsAV[2]); toxav_kill(BobsAV[1]); toxav_kill(BobsAV[0]); toxav_kill(AliceAV); tox_kill(Bobs[2]); tox_kill(Bobs[1]); tox_kill(Bobs[0]); tox_kill(Alice); tox_kill(bootstrap); pthread_mutex_destroy(&time_data.lock); printf("\nTest successful!\n"); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_av_three_calls(); return 0; } c-toxcore-0.2.18/auto_tests/tox_dispatch_test.c0000777000175000017500000001173514227324767020633 0ustar robinrobin/* Auto Tests: Many clients. */ #include #include #include #include #include "../testing/misc_tools.h" #include "../toxcore/tox.h" #include "../toxcore/tox_dispatch.h" #include "../toxcore/tox_events.h" #include "auto_test_support.h" #include "check_compat.h" // Set to true to produce an msgpack file at /tmp/test.mp. static const bool want_dump_events = false; static void handle_events_friend_message(Tox *tox, const Tox_Event_Friend_Message *event, void *user_data) { bool *success = (bool *)user_data; ck_assert(tox_event_friend_message_get_message_length(event) == sizeof("hello")); const uint8_t *msg = tox_event_friend_message_get_message(event); ck_assert_msg(memcmp(msg, "hello", sizeof("hello")) == 0, "message was not expected 'hello' but '%s'", (const char *)msg); *success = true; } static void dump_events(const char *path, const Tox_Events *events) { if (want_dump_events) { FILE *fh = fopen(path, "w"); ck_assert(fh != nullptr); const uint32_t len = tox_events_bytes_size(events); uint8_t *buf = (uint8_t *)malloc(len); ck_assert(buf != nullptr); tox_events_get_bytes(events, buf); fwrite(buf, 1, len, fh); free(buf); fclose(fh); } } static void print_events(Tox_Events *events) { const uint32_t size = tox_events_bytes_size(events); uint8_t *bytes = (uint8_t *)malloc(size); ck_assert(bytes != nullptr); tox_events_get_bytes(events, bytes); Tox_Events *events_copy = tox_events_load(bytes, size); ck_assert(events_copy != nullptr); free(bytes); ck_assert(tox_events_equal(events, events_copy)); tox_events_free(events_copy); tox_events_free(events); } static bool await_message(Tox **toxes, const Tox_Dispatch *dispatch) { for (uint32_t i = 0; i < 100; ++i) { // Ignore events on tox 1. print_events(tox_events_iterate(toxes[0], false, nullptr)); // Check if tox 2 got the message from tox 1. Tox_Events *events = tox_events_iterate(toxes[1], false, nullptr); dump_events("/tmp/test.mp", events); bool success = false; tox_dispatch_invoke(dispatch, events, toxes[1], &success); print_events(events); if (success) { return true; } c_sleep(tox_iteration_interval(toxes[0])); } return false; } static void test_tox_events(void) { uint8_t message[sizeof("hello")]; memcpy(message, "hello", sizeof(message)); Tox *toxes[2]; uint32_t index[2]; for (uint32_t i = 0; i < 2; ++i) { index[i] = i + 1; toxes[i] = tox_new_log(nullptr, nullptr, &index[i]); tox_events_init(toxes[i]); ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i); } Tox_Err_Dispatch_New err_new; Tox_Dispatch *dispatch = tox_dispatch_new(&err_new); ck_assert_msg(dispatch != nullptr, "failed to create event dispatcher"); ck_assert(err_new == TOX_ERR_DISPATCH_NEW_OK); tox_events_callback_friend_message(dispatch, handle_events_friend_message); uint8_t pk[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(toxes[0], pk); tox_bootstrap(toxes[1], "localhost", tox_self_get_udp_port(toxes[0], nullptr), pk, nullptr); tox_self_get_public_key(toxes[0], pk); tox_friend_add_norequest(toxes[1], pk, nullptr); tox_self_get_public_key(toxes[1], pk); tox_friend_add_norequest(toxes[0], pk, nullptr); printf("bootstrapping and connecting 2 toxes\n"); while (tox_self_get_connection_status(toxes[0]) == TOX_CONNECTION_NONE || tox_self_get_connection_status(toxes[1]) == TOX_CONNECTION_NONE) { // Ignore connection events for now. print_events(tox_events_iterate(toxes[0], false, nullptr)); print_events(tox_events_iterate(toxes[1], false, nullptr)); c_sleep(tox_iteration_interval(toxes[0])); } printf("toxes online, waiting for friend connection\n"); 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) { // Ignore connection events for now. print_events(tox_events_iterate(toxes[0], false, nullptr)); print_events(tox_events_iterate(toxes[1], false, nullptr)); c_sleep(tox_iteration_interval(toxes[0])); } printf("friends are connected via %s, now sending message\n", tox_friend_get_connection_status(toxes[0], 0, nullptr) == TOX_CONNECTION_TCP ? "TCP" : "UDP"); Tox_Err_Friend_Send_Message err; tox_friend_send_message(toxes[0], 0, TOX_MESSAGE_TYPE_NORMAL, message, sizeof(message), &err); ck_assert(err == TOX_ERR_FRIEND_SEND_MESSAGE_OK); ck_assert(await_message(toxes, dispatch)); tox_dispatch_free(dispatch); for (uint32_t i = 0; i < 2; ++i) { tox_kill(toxes[i]); } } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_tox_events(); return 0; } c-toxcore-0.2.18/auto_tests/tox_events_test.c0000777000175000017500000000777114227324767020345 0ustar robinrobin/* Auto Tests: Many clients. */ #include #include #include #include #include "../testing/misc_tools.h" #include "../toxcore/tox.h" #include "../toxcore/tox_events.h" #include "../toxcore/tox_struct.h" #include "auto_test_support.h" #include "check_compat.h" static bool await_message(Tox **toxes) { for (uint32_t i = 0; i < 100; ++i) { // Ignore events on tox 1. tox_events_free(tox_events_iterate(toxes[0], false, nullptr)); // Check if tox 2 got the message from tox 1. Tox_Events *events = tox_events_iterate(toxes[1], false, nullptr); if (events != nullptr) { ck_assert(tox_events_get_friend_message_size(events) == 1); const Tox_Event_Friend_Message *msg_event = tox_events_get_friend_message(events, 0); ck_assert(tox_event_friend_message_get_message_length(msg_event) == sizeof("hello")); const uint8_t *msg = tox_event_friend_message_get_message(msg_event); ck_assert_msg(memcmp(msg, "hello", sizeof("hello")) == 0, "message was not expected 'hello' but '%s'", (const char *)msg); tox_events_free(events); return true; } c_sleep(tox_iteration_interval(toxes[0])); } return false; } static uint64_t get_state_clock_callback(void *user_data) { const uint64_t *clock = (const uint64_t *)user_data; return *clock; } static void test_tox_events(void) { uint8_t message[sizeof("hello")]; memcpy(message, "hello", sizeof(message)); Tox *toxes[2]; uint32_t index[2]; for (uint32_t i = 0; i < 2; ++i) { index[i] = i + 1; toxes[i] = tox_new_log(nullptr, nullptr, &index[i]); tox_events_init(toxes[i]); ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i); } uint64_t clock = current_time_monotonic(toxes[0]->mono_time); Mono_Time *mono_time; mono_time = toxes[0]->mono_time; mono_time_set_current_time_callback(mono_time, get_state_clock_callback, &clock); mono_time = toxes[1]->mono_time; mono_time_set_current_time_callback(mono_time, get_state_clock_callback, &clock); uint8_t pk[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(toxes[0], pk); tox_bootstrap(toxes[1], "localhost", tox_self_get_udp_port(toxes[0], nullptr), pk, nullptr); tox_self_get_public_key(toxes[0], pk); tox_friend_add_norequest(toxes[1], pk, nullptr); tox_self_get_public_key(toxes[1], pk); tox_friend_add_norequest(toxes[0], pk, nullptr); printf("bootstrapping and connecting 2 toxes\n"); while (tox_self_get_connection_status(toxes[0]) == TOX_CONNECTION_NONE || tox_self_get_connection_status(toxes[1]) == TOX_CONNECTION_NONE) { // Ignore connection events for now. tox_events_free(tox_events_iterate(toxes[0], false, nullptr)); tox_events_free(tox_events_iterate(toxes[1], false, nullptr)); clock += 100; c_sleep(5); } printf("toxes online, waiting for friend connection\n"); 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) { // Ignore connection events for now. tox_events_free(tox_events_iterate(toxes[0], false, nullptr)); tox_events_free(tox_events_iterate(toxes[1], false, nullptr)); clock += 100; c_sleep(5); } printf("friends are connected via %s, now sending message\n", tox_friend_get_connection_status(toxes[0], 0, nullptr) == TOX_CONNECTION_TCP ? "TCP" : "UDP"); Tox_Err_Friend_Send_Message err; tox_friend_send_message(toxes[0], 0, TOX_MESSAGE_TYPE_NORMAL, message, sizeof(message), &err); ck_assert(err == TOX_ERR_FRIEND_SEND_MESSAGE_OK); ck_assert(await_message(toxes)); for (uint32_t i = 0; i < 2; ++i) { tox_kill(toxes[i]); } } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_tox_events(); return 0; } c-toxcore-0.2.18/auto_tests/tox_many_tcp_test.c0000777000175000017500000001717414227324767020651 0ustar robinrobin/* Auto Tests: Many TCP. */ #include #include #include #include #include "../testing/misc_tools.h" #include "../toxcore/crypto_core.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" /* The Travis-CI container responds poorly to ::1 as a localhost address * You're encouraged to -D FORCE_TESTS_IPV6 on a local test */ #ifdef FORCE_TESTS_IPV6 #define TOX_LOCALHOST "::1" #else #define TOX_LOCALHOST "127.0.0.1" #endif static bool enable_broken_tests = false; static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) { if (*((uint32_t *)userdata) != 974536) { return; } if (length == 7 && memcmp("Gentoo", data, 7) == 0) { tox_friend_add_norequest(m, public_key, nullptr); } } #define NUM_FRIENDS 50 #define NUM_TOXES_TCP 40 static uint16_t tcp_relay_port = 33448; static void test_many_clients_tcp(void) { const Random *rng = system_random(); ck_assert(rng != nullptr); long long unsigned int cur_time = time(nullptr); Tox *toxes[NUM_TOXES_TCP]; uint32_t index[NUM_TOXES_TCP]; uint32_t i, j; uint32_t to_comp = 974536; for (i = 0; i < NUM_TOXES_TCP; ++i) { struct Tox_Options *opts = tox_options_new(nullptr); if (i == 0) { tox_options_set_tcp_port(opts, tcp_relay_port); } else { tox_options_set_udp_enabled(opts, false); } index[i] = i + 1; Tox_Err_New err; toxes[i] = tox_new_log(opts, &err, &index[i]); if (i == 0 && err == TOX_ERR_NEW_PORT_ALLOC) { ck_assert(toxes[i] == nullptr); --i; ++tcp_relay_port; tox_options_free(opts); continue; } ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i); tox_callback_friend_request(toxes[i], accept_friend_request); uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(toxes[0], dpk); Tox_Err_Bootstrap error = TOX_ERR_BOOTSTRAP_OK; ck_assert_msg(tox_add_tcp_relay(toxes[i], TOX_LOCALHOST, tcp_relay_port, dpk, &error), "add relay error, %u, %d", i, error); uint16_t first_port = tox_self_get_udp_port(toxes[0], nullptr); ck_assert_msg(tox_bootstrap(toxes[i], TOX_LOCALHOST, first_port, dpk, nullptr), "Bootstrap error"); tox_options_free(opts); } struct { uint16_t tox1; uint16_t tox2; } pairs[NUM_FRIENDS]; uint8_t address[TOX_ADDRESS_SIZE]; for (i = 0; i < NUM_FRIENDS; ++i) { loop_top: 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; for (j = 0; j < i; ++j) { if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) { goto loop_top; } } tox_self_get_address(toxes[pairs[i].tox1], address); Tox_Err_Friend_Add test; uint32_t num = tox_friend_add(toxes[pairs[i].tox2], address, (const uint8_t *)"Gentoo", 7, &test); if (test == TOX_ERR_FRIEND_ADD_ALREADY_SENT) { goto loop_top; } ck_assert_msg(num != UINT32_MAX && test == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend error code: %i", test); } while (true) { uint16_t counter = 0; for (i = 0; i < NUM_TOXES_TCP; ++i) { for (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) { ++counter; } } } if (counter == NUM_FRIENDS * 2) { break; } for (i = 0; i < NUM_TOXES_TCP; ++i) { tox_iterate(toxes[i], &to_comp); } c_sleep(50); } for (i = 0; i < NUM_TOXES_TCP; ++i) { tox_kill(toxes[i]); } printf("test_many_clients_tcp succeeded, took %llu seconds\n", time(nullptr) - cur_time); } #define NUM_TCP_RELAYS 3 static void test_many_clients_tcp_b(void) { const Random *rng = system_random(); ck_assert(rng != nullptr); long long unsigned int cur_time = time(nullptr); Tox *toxes[NUM_TOXES_TCP]; uint32_t index[NUM_TOXES_TCP]; uint32_t i, j; uint32_t to_comp = 974536; for (i = 0; i < NUM_TOXES_TCP; ++i) { struct Tox_Options *opts = tox_options_new(nullptr); if (i < NUM_TCP_RELAYS) { tox_options_set_tcp_port(opts, tcp_relay_port + i); } else { tox_options_set_udp_enabled(opts, 0); } index[i] = i + 1; toxes[i] = tox_new_log(opts, nullptr, &index[i]); ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i); tox_callback_friend_request(toxes[i], accept_friend_request); uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(toxes[(i % NUM_TCP_RELAYS)], dpk); ck_assert_msg(tox_add_tcp_relay(toxes[i], TOX_LOCALHOST, tcp_relay_port + (i % NUM_TCP_RELAYS), dpk, nullptr), "add relay error"); tox_self_get_dht_id(toxes[0], dpk); uint16_t first_port = tox_self_get_udp_port(toxes[0], nullptr); ck_assert_msg(tox_bootstrap(toxes[i], TOX_LOCALHOST, first_port, dpk, nullptr), "Bootstrap error"); tox_options_free(opts); } struct { uint16_t tox1; uint16_t tox2; } pairs[NUM_FRIENDS]; uint8_t address[TOX_ADDRESS_SIZE]; for (i = 0; i < NUM_FRIENDS; ++i) { loop_top: 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; for (j = 0; j < i; ++j) { if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) { goto loop_top; } } tox_self_get_address(toxes[pairs[i].tox1], address); Tox_Err_Friend_Add test; uint32_t num = tox_friend_add(toxes[pairs[i].tox2], address, (const uint8_t *)"Gentoo", 7, &test); if (test == TOX_ERR_FRIEND_ADD_ALREADY_SENT) { goto loop_top; } ck_assert_msg(num != UINT32_MAX && test == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend error code: %i", test); } uint16_t last_count = 0; while (true) { uint16_t counter = 0; for (i = 0; i < NUM_TOXES_TCP; ++i) { for (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) { ++counter; } } } if (counter != last_count) { printf("many_clients_tcp_b got to %u\n", counter); last_count = counter; } if (counter == NUM_FRIENDS * 2) { break; } for (i = 0; i < NUM_TOXES_TCP; ++i) { tox_iterate(toxes[i], &to_comp); } c_sleep(30); } for (i = 0; i < NUM_TOXES_TCP; ++i) { tox_kill(toxes[i]); } printf("test_many_clients_tcp_b succeeded, took %llu seconds\n", time(nullptr) - cur_time); } static void tox_suite(void) { /* Each tox connects to a single tox TCP */ test_many_clients_tcp(); if (enable_broken_tests) { /* Try to make a connection to each "older sibling" tox instance via TCP */ /* Currently this test intermittently fails for unknown reasons. */ test_many_clients_tcp_b(); } } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); tox_suite(); return 0; } c-toxcore-0.2.18/auto_tests/tox_many_test.c0000777000175000017500000000744214227324767020000 0ustar robinrobin/* Auto Tests: Many clients. */ #include #include #include #include #include "../testing/misc_tools.h" #include "../toxcore/crypto_core.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) { if (length == 7 && memcmp("Gentoo", data, 7) == 0) { tox_friend_add_norequest(m, public_key, nullptr); } } #define TCP_TEST_NUM_TOXES 90 #define TCP_TEST_NUM_FRIENDS 50 static void test_many_clients(void) { const Random *rng = system_random(); ck_assert(rng != nullptr); time_t cur_time = time(nullptr); Tox *toxes[TCP_TEST_NUM_TOXES]; uint32_t index[TCP_TEST_NUM_TOXES]; for (uint32_t i = 0; i < TCP_TEST_NUM_TOXES; ++i) { index[i] = i + 1; toxes[i] = tox_new_log(nullptr, nullptr, &index[i]); ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i); tox_callback_friend_request(toxes[i], accept_friend_request); } struct { uint16_t tox1; uint16_t tox2; } pairs[TCP_TEST_NUM_FRIENDS]; uint8_t address[TOX_ADDRESS_SIZE]; uint32_t num_f = 0; for (uint32_t i = 0; i < TCP_TEST_NUM_TOXES; ++i) { num_f += tox_self_get_friend_list_size(toxes[i]); } ck_assert_msg(num_f == 0, "bad num friends: %u", num_f); for (uint32_t i = 0; i < TCP_TEST_NUM_FRIENDS; ++i) { loop_top: pairs[i].tox1 = random_u32(rng) % TCP_TEST_NUM_TOXES; pairs[i].tox2 = (pairs[i].tox1 + random_u32(rng) % (TCP_TEST_NUM_TOXES - 1) + 1) % TCP_TEST_NUM_TOXES; for (uint32_t j = 0; j < i; ++j) { if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) { goto loop_top; } } tox_self_get_address(toxes[pairs[i].tox1], address); Tox_Err_Friend_Add test; uint32_t num = tox_friend_add(toxes[pairs[i].tox2], address, (const uint8_t *)"Gentoo", 7, &test); if (test == TOX_ERR_FRIEND_ADD_ALREADY_SENT) { goto loop_top; } uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(toxes[pairs[i].tox1], dht_key); const uint16_t dht_port = tox_self_get_udp_port(toxes[pairs[i].tox1], nullptr); tox_bootstrap(toxes[pairs[i].tox2], "localhost", dht_port, dht_key, nullptr); ck_assert_msg(num != UINT32_MAX && test == TOX_ERR_FRIEND_ADD_OK, "failed to add friend error code: %i", test); } for (uint32_t i = 0; i < TCP_TEST_NUM_TOXES; ++i) { num_f += tox_self_get_friend_list_size(toxes[i]); } ck_assert_msg(num_f == TCP_TEST_NUM_FRIENDS, "bad num friends: %u", num_f); uint16_t last_count = 0; while (true) { uint16_t counter = 0; for (uint32_t i = 0; i < TCP_TEST_NUM_TOXES; ++i) { 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_UDP) { ++counter; } } } if (counter != last_count) { printf("many_clients got to %u\n", counter); last_count = counter; } if (counter == TCP_TEST_NUM_FRIENDS * 2) { break; } for (uint32_t i = 0; i < TCP_TEST_NUM_TOXES; ++i) { tox_iterate(toxes[i], nullptr); } c_sleep(50); } for (uint32_t i = 0; i < TCP_TEST_NUM_TOXES; ++i) { tox_kill(toxes[i]); } printf("test_many_clients succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_many_clients(); return 0; } c-toxcore-0.2.18/auto_tests/tox_strncasecmp_test.c0000777000175000017500000001233214227324767021350 0ustar robinrobin#include #include #include "../testing/misc_tools.h" #include "check_compat.h" typedef enum { NEGATIVE, ZERO, POSITIVE } Comparison; static const char *Comparison_Str[] = { "NEGATIVE", "ZERO", "POSITIVE" }; static void verify(const char *s1, const char *s2, size_t n, Comparison expected) { int r = tox_strncasecmp(s1, s2, n); Comparison actual = r < 0 ? NEGATIVE : r == 0 ? ZERO : POSITIVE; ck_assert_msg(actual == expected, "tox_strncasecmp(\"%s\", \"%s\", %u) == %s, but expected %s.", s1, s2, (unsigned)n, Comparison_Str[actual], Comparison_Str[expected]); } static void test_general(void) { // empty strings are equal verify("", "", 100, ZERO); verify("", "", -1, ZERO); // ====== Same Case Test Cases ====== // equal strings with n=0 are equal verify("", "", 0, ZERO); verify("AAA", "AAA", 0, ZERO); // unequal strings with n=0 are equal verify("A", "B", 0, ZERO); verify("AAA", "BBB", 0, ZERO); verify("AAA", "BBBBBB", 0, ZERO); verify("AAAAAA", "BBB", 0, ZERO); // equal strings are equal verify("AAA", "AAA", 0, ZERO); verify("AAA", "AAA", 1, ZERO); verify("AAA", "AAA", 2, ZERO); verify("AAA", "AAA", 3, ZERO); verify("AAA", "AAA", 4, ZERO); verify("AAA", "AAA", 5, ZERO); verify("AAA", "AAA", -1, ZERO); verify("AAA", "AAAAAA", 0, ZERO); verify("AAA", "AAAAAA", 1, ZERO); verify("AAA", "AAAAAA", 2, ZERO); verify("AAA", "AAAAAA", 3, ZERO); verify("AAA", "AAAAAA", 4, NEGATIVE); verify("AAA", "AAAAAA", 5, NEGATIVE); verify("AAA", "AAAAAA", -1, NEGATIVE); verify("AAAAAA", "AAA", 0, ZERO); verify("AAAAAA", "AAA", 1, ZERO); verify("AAAAAA", "AAA", 2, ZERO); verify("AAAAAA", "AAA", 3, ZERO); verify("AAAAAA", "AAA", 4, POSITIVE); verify("AAAAAA", "AAA", 5, POSITIVE); verify("AAAAAA", "AAA", -1, POSITIVE); verify("I'm eating wafers and drinking tea.", "I'm eating wafers and drinking tea.", -1, ZERO); // unequal strings are equal only up to n verify("AAAB", "AAAA", 0, ZERO); verify("AAAB", "AAAA", 1, ZERO); verify("AAAB", "AAAA", 2, ZERO); verify("AAAB", "AAAA", 3, ZERO); verify("AAAB", "AAAA", 4, POSITIVE); verify("AAAB", "AAAA", 5, POSITIVE); verify("AAAB", "AAAA", -1, POSITIVE); verify("AAAA", "AAAB", 0, ZERO); verify("AAAA", "AAAB", 1, ZERO); verify("AAAA", "AAAB", 2, ZERO); verify("AAAA", "AAAB", 3, ZERO); verify("AAAA", "AAAB", 4, NEGATIVE); verify("AAAA", "AAAB", 5, NEGATIVE); verify("AAAA", "AAAB", -1, NEGATIVE); verify("The wafers are salty.", "The wafers are sweet.", 16, ZERO); verify("The wafers are salty.", "The wafers are sweet.", 17, NEGATIVE); verify("The wafers are salty.", "The wafers are sweet.", -1, NEGATIVE); // the comparison should stop at first mismatch verify("AAABA", "AAAAB", -1, POSITIVE); verify("AAAAB", "AAABA", -1, NEGATIVE); // ====== Different Case Test Cases ====== // equal strings with n=0 are equal verify("", "", 0, ZERO); verify("aaa", "AAA", 0, ZERO); // unequal strings with n=0 are equal verify("a", "B", 0, ZERO); verify("aaa", "BBB", 0, ZERO); verify("aaa", "BBBBBB", 0, ZERO); verify("aaaaaa", "BBB", 0, ZERO); // equal strings are equal verify("aaa", "AAA", 0, ZERO); verify("AAA", "aaa", 1, ZERO); verify("aaa", "AAA", 2, ZERO); verify("aaa", "AAA", 3, ZERO); verify("AAA", "aaa", 4, ZERO); verify("AAA", "aaa", 5, ZERO); verify("AAA", "aaa", -1, ZERO); verify("aaa", "AAAAAA", 0, ZERO); verify("AAA", "AAAaaa", 1, ZERO); verify("aaA", "aaaAAA", 2, ZERO); verify("AaA", "aAAAAA", 3, ZERO); verify("AAA", "AAAAAA", 4, NEGATIVE); verify("Aaa", "AAaaAA", 5, NEGATIVE); verify("AAA", "AAAAAa", -1, NEGATIVE); verify("AAAAAA", "aaa", 0, ZERO); verify("AAAaaa", "AAA", 1, ZERO); verify("aaaAAA", "aaA", 2, ZERO); verify("aAAAAA", "AaA", 3, ZERO); verify("AAAAAA", "AAA", 4, POSITIVE); verify("AAaaAA", "Aaa", 5, POSITIVE); verify("AAAAAa", "AAA", -1, POSITIVE); verify("I'm Eating Wafers And Drinking Tea.", "I'm eating wafers and drinking tea.", -1, ZERO); // unequal strings are equal only up to n verify("aaaB", "AAAA", 0, ZERO); verify("AaAB", "aAAA", 1, ZERO); verify("aAAB", "AaAA", 2, ZERO); verify("AAAB", "AAaA", 3, ZERO); verify("AAAB", "AAAA", 4, POSITIVE); verify("AAAb", "AAAA", 5, POSITIVE); verify("AAAB", "AAAa", -1, POSITIVE); verify("AAAA", "aaaB", 0, ZERO); verify("aAAA", "AaAB", 1, ZERO); verify("AaAA", "aAAB", 2, ZERO); verify("AAaA", "AAAB", 3, ZERO); verify("AAAA", "AAAB", 4, NEGATIVE); verify("AAAA", "AAAb", 5, NEGATIVE); verify("AAAa", "AAAB", -1, NEGATIVE); verify("The Wafers Are Salty.", "The wafers are sweet.", 16, ZERO); verify("The Wafers Are Salty.", "The wafers are sweet.", 17, NEGATIVE); verify("The Wafers Are Salty.", "The wafers are sweet.", -1, NEGATIVE); // the comparison should stop at first mismatch verify("aAaBA", "AAAAb", -1, POSITIVE); verify("AAAAb", "aAaBA", -1, NEGATIVE); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_general(); return 0; } c-toxcore-0.2.18/auto_tests/typing_test.c0000777000175000017500000000355414227324767017454 0ustar robinrobin/* Tests that our typing notifications work. */ #include #include #include #include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" #include "check_compat.h" typedef struct State { bool friend_is_typing; } State; #include "auto_test_support.h" static void typing_callback(Tox *m, uint32_t friendnumber, bool typing, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; state->friend_is_typing = typing; } static void test_typing(AutoTox *autotoxes) { time_t cur_time = time(nullptr); tox_callback_friend_typing(autotoxes[1].tox, &typing_callback); tox_self_set_typing(autotoxes[0].tox, 0, true, nullptr); do { iterate_all_wait(autotoxes, 2, 200); } while (!((State *)autotoxes[1].state)->friend_is_typing); ck_assert_msg(tox_friend_get_typing(autotoxes[1].tox, 0, nullptr) == 1, "tox_friend_get_typing should have returned true, but it didn't"); tox_self_set_typing(autotoxes[0].tox, 0, false, nullptr); do { iterate_all_wait(autotoxes, 2, 200); } while (((State *)autotoxes[1].state)->friend_is_typing); Tox_Err_Friend_Query err_t; ck_assert_msg(tox_friend_get_typing(autotoxes[1].tox, 0, &err_t) == 0, "tox_friend_get_typing should have returned false, but it didn't"); ck_assert_msg(err_t == TOX_ERR_FRIEND_QUERY_OK, "tox_friend_get_typing call did not return correct error"); printf("test_typing succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); } int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; run_auto_test(nullptr, 2, test_typing, sizeof(State), &options); return 0; } c-toxcore-0.2.18/auto_tests/version_test.c0000777000175000017500000000544514227324767017630 0ustar robinrobin#include "../toxcore/tox.h" #include "check_compat.h" #define check(major, minor, patch, expected) \ do_check(TOX_VERSION_MAJOR, TOX_VERSION_MINOR, TOX_VERSION_PATCH, \ major, minor, patch, \ TOX_VERSION_IS_API_COMPATIBLE(major, minor, patch), expected) static void do_check(int lib_major, int lib_minor, int lib_patch, int cli_major, int cli_minor, int cli_patch, bool actual, bool expected) { ck_assert_msg(actual == expected, "Client version %d.%d.%d is%s compatible with library version %d.%d.%d, but it should%s be\n", cli_major, cli_minor, cli_patch, actual ? "" : " not", lib_major, lib_minor, lib_patch, expected ? "" : " not"); } #undef TOX_VERSION_MAJOR #undef TOX_VERSION_MINOR #undef TOX_VERSION_PATCH int main(void) { #define TOX_VERSION_MAJOR 0 #define TOX_VERSION_MINOR 0 #define TOX_VERSION_PATCH 4 // Tox versions from 0.0.* are only compatible with themselves. check(0, 0, 0, false); check(0, 0, 3, false); check(0, 0, 4, true); check(0, 0, 5, false); check(1, 0, 4, false); #undef TOX_VERSION_MAJOR #undef TOX_VERSION_MINOR #undef TOX_VERSION_PATCH #define TOX_VERSION_MAJOR 0 #define TOX_VERSION_MINOR 1 #define TOX_VERSION_PATCH 4 // Tox versions from 0.1.* are only compatible with themselves or 0.1.<* check(0, 0, 0, false); check(0, 0, 4, false); check(0, 0, 5, false); check(0, 1, 0, true); check(0, 1, 4, true); check(0, 1, 5, false); check(0, 2, 0, false); check(0, 2, 4, false); check(0, 2, 5, false); check(1, 0, 0, false); check(1, 0, 4, false); check(1, 0, 5, false); check(1, 1, 4, false); #undef TOX_VERSION_MAJOR #undef TOX_VERSION_MINOR #undef TOX_VERSION_PATCH #define TOX_VERSION_MAJOR 1 #define TOX_VERSION_MINOR 0 #define TOX_VERSION_PATCH 4 // Beyond 0.*.* Tox is comfortable with any lower version within their major check(0, 0, 4, false); check(1, 0, 0, true); check(1, 0, 1, true); check(1, 0, 4, true); check(1, 0, 5, false); check(1, 1, 0, false); check(2, 0, 0, false); check(2, 0, 4, false); #undef TOX_VERSION_MAJOR #undef TOX_VERSION_MINOR #undef TOX_VERSION_PATCH #define TOX_VERSION_MAJOR 1 #define TOX_VERSION_MINOR 1 #define TOX_VERSION_PATCH 4 check(0, 0, 4, false); check(1, 0, 0, true); check(1, 0, 4, true); check(1, 0, 5, true); check(1, 1, 0, true); check(1, 1, 1, true); check(1, 1, 4, true); check(1, 1, 5, false); check(1, 2, 0, false); check(1, 2, 4, false); check(1, 2, 5, false); check(2, 0, 0, false); check(2, 1, 4, false); #undef TOX_VERSION_MAJOR #undef TOX_VERSION_MINOR #undef TOX_VERSION_PATCH return 0; } c-toxcore-0.2.18/build/0000777000175000017500000000000014227324767013632 5ustar robinrobinc-toxcore-0.2.18/build/Makefile.am0000777000175000017500000000103614227324767015671 0ustar robinrobinbin_PROGRAMS = noinst_PROGRAMS = noinst_LTLIBRARIES = lib_LTLIBRARIES = noinst_bindir = $(top_builddir)/build EXTRA_DIST= if SET_SO_VERSION include ../so.version LT_LDFLAGS=-version-info $(CURRENT):$(REVISION):$(AGE) else LT_LDFLAGS=-avoid-version endif include ../toxcore/Makefile.inc include ../toxencryptsave/Makefile.inc include ../toxav/Makefile.inc include ../other/Makefile.inc include ../testing/Makefile.inc include ../other/bootstrap_daemon/src/Makefile.inc include ../auto_tests/Makefile.inc build-tests: $(check_PROGRAMS) c-toxcore-0.2.18/BUILD.bazel0000777000175000017500000000177214227324767014423 0ustar robinrobinload("@rules_cc//cc:defs.bzl", "cc_library") load("//tools/project:build_defs.bzl", "project") package(features = ["layering_check"]) project() genrule( name = "public_headers", srcs = [ "//c-toxcore/toxav:toxav.h", "//c-toxcore/toxcore:tox.h", "//c-toxcore/toxencryptsave:toxencryptsave.h", ], outs = [ "tox/toxav.h", "tox/tox.h", "tox/toxencryptsave.h", ], cmd = """ cp $(location //c-toxcore/toxav:toxav.h) $(GENDIR)/c-toxcore/tox/toxav.h cp $(location //c-toxcore/toxcore:tox.h) $(GENDIR)/c-toxcore/tox/tox.h cp $(location //c-toxcore/toxencryptsave:toxencryptsave.h) $(GENDIR)/c-toxcore/tox/toxencryptsave.h """, visibility = ["//visibility:public"], ) cc_library( name = "c-toxcore", hdrs = [":public_headers"], includes = ["."], visibility = ["//visibility:public"], deps = [ "//c-toxcore/toxav", "//c-toxcore/toxcore", "//c-toxcore/toxencryptsave", ], ) c-toxcore-0.2.18/CHANGELOG.md0000777000175000017500000043137214227324767014361 0ustar robinrobin ## v0.2.18 ### Merged PRs: - [#2299](https://github.com/TokTok/c-toxcore/pull/2299) fix: remove the assert because buffer can be larger than UINT16_MAX. - [#2297](https://github.com/TokTok/c-toxcore/pull/2297) cleanup: remove unused field last_seen from Onion_Friend - [#2289](https://github.com/TokTok/c-toxcore/pull/2289) test: Add a Null_System used in toxsave_harness. - [#2288](https://github.com/TokTok/c-toxcore/pull/2288) test: enable additional sanitizers for fuzzing - [#2287](https://github.com/TokTok/c-toxcore/pull/2287) fix: Don't allow onion paths to be built from real friends. - [#2285](https://github.com/TokTok/c-toxcore/pull/2285) test: Don't abort fuzz test when tox_new fails. - [#2284](https://github.com/TokTok/c-toxcore/pull/2284) refactor: Move crypto utilities from util to crypto_core. - [#2283](https://github.com/TokTok/c-toxcore/pull/2283) fix: Allow onion paths to be built from more random nodes. - [#2282](https://github.com/TokTok/c-toxcore/pull/2282) fix: Fix potential array out-of-bounds in DHT onion path building. - [#2281](https://github.com/TokTok/c-toxcore/pull/2281) cleanup: Avoid goto in msi.c. - [#2280](https://github.com/TokTok/c-toxcore/pull/2280) test: Improve test hermeticity by using local TCP relay. - [#2279](https://github.com/TokTok/c-toxcore/pull/2279) test: Enable fuzzing for TCP. - [#2277](https://github.com/TokTok/c-toxcore/pull/2277) refactor: Avoid `static_cast` in `Fuzz_System` functions. - [#2275](https://github.com/TokTok/c-toxcore/pull/2275) chore: Downgrade C++ version to 17 - [#2273](https://github.com/TokTok/c-toxcore/pull/2273) fix: Really fix overrun added in e49a477a - [#2272](https://github.com/TokTok/c-toxcore/pull/2272) fix: Add missing return on error - [#2270](https://github.com/TokTok/c-toxcore/pull/2270) test: Improve error messages in toxav_basic_test. - [#2266](https://github.com/TokTok/c-toxcore/pull/2266) fix: Fixed leak and overrun added in e49a477a - [#2263](https://github.com/TokTok/c-toxcore/pull/2263) chore: Upgrade to C++20 in CMake build. - [#2261](https://github.com/TokTok/c-toxcore/pull/2261) refactor: Protect array unpacking against invalid lengths. - [#2258](https://github.com/TokTok/c-toxcore/pull/2258) refactor: Rename announce functions into their own namespace. - [#2257](https://github.com/TokTok/c-toxcore/pull/2257) fix: Format IP as string again in error log. - [#2255](https://github.com/TokTok/c-toxcore/pull/2255) fix: Fix a stack overflow triggered by small DHT packets. - [#2251](https://github.com/TokTok/c-toxcore/pull/2251) chore: Add MISRA-2012 check using cppcheck's misra addon. - [#2250](https://github.com/TokTok/c-toxcore/pull/2250) cleanup: remove populate_path_nodes_tcp - [#2249](https://github.com/TokTok/c-toxcore/pull/2249) test: Improve stability of forwarding_test. - [#2248](https://github.com/TokTok/c-toxcore/pull/2248) refactor: Use a struct for the `ip_ntoa` buffer. - [#2246](https://github.com/TokTok/c-toxcore/pull/2246) fix: Don't crash if RNG init failed. - [#2244](https://github.com/TokTok/c-toxcore/pull/2244) refactor: Allow NULL logger; make it no-op in NDEBUG. - [#2243](https://github.com/TokTok/c-toxcore/pull/2243) chore: Add initial ESP32 docker build. - [#2242](https://github.com/TokTok/c-toxcore/pull/2242) cleanup: Use `static_assert` instead of `assert` where possible. - [#2240](https://github.com/TokTok/c-toxcore/pull/2240) chore(deps): Use upstream cmp directly instead of our fork. - [#2238](https://github.com/TokTok/c-toxcore/pull/2238) cleanup: Make `*_free` and `kill_*` functions nullable. - [#2236](https://github.com/TokTok/c-toxcore/pull/2236) chore: Add dependabot config. - [#2234](https://github.com/TokTok/c-toxcore/pull/2234) test: Add more functionality to the bootstrap fuzz harness. - [#2233](https://github.com/TokTok/c-toxcore/pull/2233) cleanup: Replace a series of `if` statements with a `switch`. - [#2232](https://github.com/TokTok/c-toxcore/pull/2232) test: Add fuzzer support functions for internal toxcore objects. - [#2230](https://github.com/TokTok/c-toxcore/pull/2230) feat: Merge group announce portion of new groupchats implementation - [#2229](https://github.com/TokTok/c-toxcore/pull/2229) cleanup: Remove layers in the cmake build. - [#2228](https://github.com/TokTok/c-toxcore/pull/2228) chore: Fix path to fuzzer binaries in clusterfuzz build. - [#2227](https://github.com/TokTok/c-toxcore/pull/2227) cleanup: Disallow stack frames of over 9000 bytes. - [#2225](https://github.com/TokTok/c-toxcore/pull/2225) fix: fix typo in git command in INSTALL.md - [#2224](https://github.com/TokTok/c-toxcore/pull/2224) cleanup: Add include for assert.h for the fuzzing build. - [#2223](https://github.com/TokTok/c-toxcore/pull/2223) chore: Add `uint8_t` version of `bin_pack` for numbers. - [#2219](https://github.com/TokTok/c-toxcore/pull/2219) refactor: Rename bin_pack/unpack functions the same as cmp funcs. - [#2217](https://github.com/TokTok/c-toxcore/pull/2217) cleanup: Add Network object parameter for addr_resolve. - [#2214](https://github.com/TokTok/c-toxcore/pull/2214) cleanup: Remove all uses of `TOX_*_MAX_SIZE` macros. - [#2213](https://github.com/TokTok/c-toxcore/pull/2213) cleanup: Remove unused random_testing program. - [#2212](https://github.com/TokTok/c-toxcore/pull/2212) cleanup: Expand `CONST_FUNCTION` and remove the macro. - [#2211](https://github.com/TokTok/c-toxcore/pull/2211) cleanup: Move definitions of tox_private.h functions to tox_private.c. - [#2210](https://github.com/TokTok/c-toxcore/pull/2210) chore: Clone submodules in clusterfuzzlite Dockerfile. - [#2208](https://github.com/TokTok/c-toxcore/pull/2208) chore: Remove valgrind build. - [#2206](https://github.com/TokTok/c-toxcore/pull/2206) feat: Allow overriding mono_time in tox_new. - [#2204](https://github.com/TokTok/c-toxcore/pull/2204) chore: Support producing shared libraries on Windows - [#2202](https://github.com/TokTok/c-toxcore/pull/2202) cleanup: Avoid name clash between struct field and function. - [#2201](https://github.com/TokTok/c-toxcore/pull/2201) docs: Add information regarding git submodules, cmp to INSTALL.md - [#2200](https://github.com/TokTok/c-toxcore/pull/2200) cleanup: Add more null checks in `tox_new`. - [#2199](https://github.com/TokTok/c-toxcore/pull/2199) cleanup: Mark Mono_Time const where possible. - [#2196](https://github.com/TokTok/c-toxcore/pull/2196) test: Remove save_load_test from autotools build. - [#2195](https://github.com/TokTok/c-toxcore/pull/2195) fix: Correct calculation of packet sent time - [#2193](https://github.com/TokTok/c-toxcore/pull/2193) perf: Make time move a lot faster in fuzzing runs. - [#2190](https://github.com/TokTok/c-toxcore/pull/2190) feat: Add support for custom random number generator. - [#2189](https://github.com/TokTok/c-toxcore/pull/2189) chore: Add third_party to toxcore-sources docker image. - [#2188](https://github.com/TokTok/c-toxcore/pull/2188) cleanup: Make addr_resolve a private function. - [#2187](https://github.com/TokTok/c-toxcore/pull/2187) test: Add DHT and tox_events fuzz tests to the cmake build. - [#2186](https://github.com/TokTok/c-toxcore/pull/2186) cleanup: Use `_Static_assert` in gcc/clang. - [#2184](https://github.com/TokTok/c-toxcore/pull/2184) test: Add some support functions to make writing fuzzers easier. - [#2183](https://github.com/TokTok/c-toxcore/pull/2183) test: Enable more tests for msan. - [#2182](https://github.com/TokTok/c-toxcore/pull/2182) test: Improve stability of tox_many_tcp_test. - [#2177](https://github.com/TokTok/c-toxcore/pull/2177) feat: Add support for overriding network functions. - [#2176](https://github.com/TokTok/c-toxcore/pull/2176) test: try to save the fuzzed save file again - [#2175](https://github.com/TokTok/c-toxcore/pull/2175) refactor: Use cmp instead of msgpack-c for events packing. - [#2173](https://github.com/TokTok/c-toxcore/pull/2173) chore: Use "master" as the branch in toktok-fuzzer. - [#2170](https://github.com/TokTok/c-toxcore/pull/2170) test: Add fuzzer tests to the bazel build. - [#2169](https://github.com/TokTok/c-toxcore/pull/2169) feat: Merge moderation portion of new groupchats codebase - [#2167](https://github.com/TokTok/c-toxcore/pull/2167) cleanup: Reduce scope of array-typed variables where possible. - [#2166](https://github.com/TokTok/c-toxcore/pull/2166) cleanup: Reduce scope of variables as requested by cimple. - [#2164](https://github.com/TokTok/c-toxcore/pull/2164) feat: Merge onion_announce changes from new groupchats fork - [#2163](https://github.com/TokTok/c-toxcore/pull/2163) chore: Enable memory sanitizer build. - [#2160](https://github.com/TokTok/c-toxcore/pull/2160) test: Improve the stability of the save_load test - [#2159](https://github.com/TokTok/c-toxcore/pull/2159) chore: Update the Appveyor build to VS2019 to work around conan issues - [#2158](https://github.com/TokTok/c-toxcore/pull/2158) cleanup: Expose `struct Tox` to internal code. - [#2157](https://github.com/TokTok/c-toxcore/pull/2157) cleanup: Split the huge TCP client packet handler. - [#2156](https://github.com/TokTok/c-toxcore/pull/2156) cleanup: Sync doc comments between .h and .c files. - [#2155](https://github.com/TokTok/c-toxcore/pull/2155) fix: Eliminate memory leak in toxav. - [#2154](https://github.com/TokTok/c-toxcore/pull/2154) test: Speed up toxav_many_test by using fake mono_time. - [#2153](https://github.com/TokTok/c-toxcore/pull/2153) docs: Put all the tox public api into a fake "tox" namespace. - [#2150](https://github.com/TokTok/c-toxcore/pull/2150) cleanup: Move all the group.h structs into group.c. - [#2149](https://github.com/TokTok/c-toxcore/pull/2149) cleanup: Avoid `memset` on structs. - [#2147](https://github.com/TokTok/c-toxcore/pull/2147) feat: Store announcements - [#2146](https://github.com/TokTok/c-toxcore/pull/2146) chore: Add testing/Dockerfile to the CI build. - [#2145](https://github.com/TokTok/c-toxcore/pull/2145) chore: Be even more explicit about integer range bounds. - [#2144](https://github.com/TokTok/c-toxcore/pull/2144) cleanup: Minor cleanups in TCP_connection.c. - [#2143](https://github.com/TokTok/c-toxcore/pull/2143) fix: Allow port range in DHT_bootstrap.c. - [#2142](https://github.com/TokTok/c-toxcore/pull/2142) cleanup: Count re-adding an existing bootstrap node as success. - [#2141](https://github.com/TokTok/c-toxcore/pull/2141) cleanup: Disable LAN discovery in TCP-only mode. - [#2140](https://github.com/TokTok/c-toxcore/pull/2140) cleanup: Add assertion for decrypted data length. - [#2101](https://github.com/TokTok/c-toxcore/pull/2101) cleanup: improve CMakeLists.txt structure - [#2100](https://github.com/TokTok/c-toxcore/pull/2100) chore: remove cpufeatures.c - [#2098](https://github.com/TokTok/c-toxcore/pull/2098) chore: remove DHT_test.c since it's unused ### Closed issues: - [#2256](https://github.com/TokTok/c-toxcore/issues/2256) New Defects reported by Coverity Scan for TokTok/c-toxcore - [#2109](https://github.com/TokTok/c-toxcore/issues/2109) Assimilate `messenger_test.c`: replace with public API test - [#2012](https://github.com/TokTok/c-toxcore/issues/2012) Support building a DLL on Windows - [#907](https://github.com/TokTok/c-toxcore/issues/907) use dll abnormal System.AccessViolationException win7 x32 but x64 no problem ## v0.2.17 ### Merged PRs: - [#2138](https://github.com/TokTok/c-toxcore/pull/2138) chore: Release 0.2.17 - [#2136](https://github.com/TokTok/c-toxcore/pull/2136) docs: Clean up doxygen comments to be more doxygen-like. - [#2135](https://github.com/TokTok/c-toxcore/pull/2135) cleanup: Move test-only functions into tests. - [#2134](https://github.com/TokTok/c-toxcore/pull/2134) cleanup: Add explicit callback setters for MSI callbacks. - [#2133](https://github.com/TokTok/c-toxcore/pull/2133) cleanup: Remove redundant Messenger and DHT tests. - [#2132](https://github.com/TokTok/c-toxcore/pull/2132) cleanup: Remove dependency from LAN_discovery onto DHT. - [#2131](https://github.com/TokTok/c-toxcore/pull/2131) cleanup: Split util.c out of the network library. - [#2130](https://github.com/TokTok/c-toxcore/pull/2130) cleanup: Remove redundant `()` around `return` expression. - [#2128](https://github.com/TokTok/c-toxcore/pull/2128) test: Add unit test for create/handle request packets. - [#2127](https://github.com/TokTok/c-toxcore/pull/2127) cleanup: Remove `EAGAIN` from the list of ignored errors. - [#2126](https://github.com/TokTok/c-toxcore/pull/2126) cleanup: Remove port from `Broadcast_Info`. - [#2125](https://github.com/TokTok/c-toxcore/pull/2125) cleanup: Don't reference local variables in macro bodies. - [#2123](https://github.com/TokTok/c-toxcore/pull/2123) cleanup: Remove some more implicit bool conversions. - [#2122](https://github.com/TokTok/c-toxcore/pull/2122) chore: Enable a bunch more warnings in GCC builds. - [#2120](https://github.com/TokTok/c-toxcore/pull/2120) cleanup: Remove all boolean-int conversions. - [#2117](https://github.com/TokTok/c-toxcore/pull/2117) cleanup: Comply with strict include ordering. - [#2116](https://github.com/TokTok/c-toxcore/pull/2116) cleanup: Remove more boolean conversions (and a bugfix). - [#2115](https://github.com/TokTok/c-toxcore/pull/2115) cleanup: Log at ERROR level when `connect()` fails. - [#2114](https://github.com/TokTok/c-toxcore/pull/2114) cleanup: Avoid creating invalid enum values. - [#2113](https://github.com/TokTok/c-toxcore/pull/2113) cleanup: Remove superfluous parentheses on the rhs of assignments. - [#2108](https://github.com/TokTok/c-toxcore/pull/2108) test: Add mallocfail and proxy test to our coverage runs. - [#2106](https://github.com/TokTok/c-toxcore/pull/2106) test: Add test coverage docker build for local tests. - [#2105](https://github.com/TokTok/c-toxcore/pull/2105) cleanup: Change valid status of onion friend to bool. - [#2104](https://github.com/TokTok/c-toxcore/pull/2104) fix: Report failure to DHT bootstrap back to the client. - [#2103](https://github.com/TokTok/c-toxcore/pull/2103) cleanup: Remove more implicit bool conversions. - [#2102](https://github.com/TokTok/c-toxcore/pull/2102) cleanup: Mark all local non-pointers as const where possible. - [#2099](https://github.com/TokTok/c-toxcore/pull/2099) cleanup: Reduce name shadowing; remove ptr-to-bool conversions. - [#2097](https://github.com/TokTok/c-toxcore/pull/2097) cleanup: Remove implicit conversions from `uint32_t` to `bool`. - [#2096](https://github.com/TokTok/c-toxcore/pull/2096) cleanup: Return boolean constants, not ints from bool functions. - [#2094](https://github.com/TokTok/c-toxcore/pull/2094) fix: Null function pointer dereference. - [#2093](https://github.com/TokTok/c-toxcore/pull/2093) cleanup: Remove any disallowed casts. - [#2092](https://github.com/TokTok/c-toxcore/pull/2092) perf: fix issue with friend finding taking too long after disconnects. - [#2091](https://github.com/TokTok/c-toxcore/pull/2091) cleanup: Avoid casting function pointers. - [#2090](https://github.com/TokTok/c-toxcore/pull/2090) refactor: Move `tox_new_log` to `auto_test_support`. - [#2088](https://github.com/TokTok/c-toxcore/pull/2088) cleanup: Remove all implicit bool conversions in if-conditions. - [#2086](https://github.com/TokTok/c-toxcore/pull/2086) cleanup: Enable most cppcheck warnings as errors. - [#2084](https://github.com/TokTok/c-toxcore/pull/2084) fix: out-of-memory condition by corrupted save file - [#2079](https://github.com/TokTok/c-toxcore/pull/2079) cleanup: Remove unused execution trace library. - [#2078](https://github.com/TokTok/c-toxcore/pull/2078) perf: Refactor onion_client.c do_friends() to reduce network traffic - [#2075](https://github.com/TokTok/c-toxcore/pull/2075) chore: Add a .clang-format that mostly agrees with astyle. - [#2074](https://github.com/TokTok/c-toxcore/pull/2074) chore: Make coverity scan a nightly job. - [#2073](https://github.com/TokTok/c-toxcore/pull/2073) chore: Fix build-args in win32/win64 docker build. - [#2072](https://github.com/TokTok/c-toxcore/pull/2072) chore: Simplify and speed up windows builds using docker image. - [#2070](https://github.com/TokTok/c-toxcore/pull/2070) chore: Add docker image builds for windows cross compiler. - [#2064](https://github.com/TokTok/c-toxcore/pull/2064) fix: toxsave memory leak while loading groups ### Closed issues: - [#2121](https://github.com/TokTok/c-toxcore/issues/2121) Improve speed and stability of LAN discovery test - [#2083](https://github.com/TokTok/c-toxcore/issues/2083) Tox save file format/loader doesn't limit or check the number of frozen peers - [#2080](https://github.com/TokTok/c-toxcore/issues/2080) speedup getting online after tox process has been suspended - [#2050](https://github.com/TokTok/c-toxcore/issues/2050) Excessive onion friend lookups - [#2034](https://github.com/TokTok/c-toxcore/issues/2034) Make coverity-scan workflow a nightly build instead of on master push - [#2000](https://github.com/TokTok/c-toxcore/issues/2000) Move win32 docker image build out to dockerfiles - [#1990](https://github.com/TokTok/c-toxcore/issues/1990) Add a .clang-format config that matches the astyle config as closely as possible. - [#1115](https://github.com/TokTok/c-toxcore/issues/1115) Add empty handler for LAN discovery packets when LAN discovery is disabled - [#647](https://github.com/TokTok/c-toxcore/issues/647) `tox_bootstrap` should return an error on unrecoverable `getnodes` failure - [#169](https://github.com/TokTok/c-toxcore/issues/169) Get rid of TOX_USER_STATUS_BUSY + 1 ## v0.2.16 ### Merged PRs: - [#2071](https://github.com/TokTok/c-toxcore/pull/2071) chore: Release 0.2.16 - [#2069](https://github.com/TokTok/c-toxcore/pull/2069) chore: Simplify and speed up nacl build using toxchat/nacl. - [#2066](https://github.com/TokTok/c-toxcore/pull/2066) test: Add a profiling script and Dockerfile. - [#2058](https://github.com/TokTok/c-toxcore/pull/2058) fix: properly deallocate frozen peers - [#2056](https://github.com/TokTok/c-toxcore/pull/2056) cleanup: Avoid implicit boolean and floating point conversions in decls. - [#2055](https://github.com/TokTok/c-toxcore/pull/2055) cleanup: Avoid implicit bool conversions in logical operators. - [#2053](https://github.com/TokTok/c-toxcore/pull/2053) cleanup: Enable tokstyle's `-Wlarge-struct-params`. - [#2052](https://github.com/TokTok/c-toxcore/pull/2052) fix: Fix return type of functions returning uint64_t. - [#2049](https://github.com/TokTok/c-toxcore/pull/2049) cleanup: Apply stronger type checks and fix errors. - [#2047](https://github.com/TokTok/c-toxcore/pull/2047) feat: Improve how we share TCP relays with friends - [#2046](https://github.com/TokTok/c-toxcore/pull/2046) cleanup: Avoid implicit pointer-to-bool conversion in `if` in toxav. - [#2043](https://github.com/TokTok/c-toxcore/pull/2043) refactor: Compare pointers in if conditions to nullptr. - [#2041](https://github.com/TokTok/c-toxcore/pull/2041) fix: file transfer bug introduced in commit 2073d02 - [#2039](https://github.com/TokTok/c-toxcore/pull/2039) refactor: Add a bit more logging; change WARNING to ERROR. - [#2036](https://github.com/TokTok/c-toxcore/pull/2036) chore: Add BUILD file for websockify. - [#2035](https://github.com/TokTok/c-toxcore/pull/2035) chore: fine tune fuzzing settings - [#2033](https://github.com/TokTok/c-toxcore/pull/2033) cleanup: Add some more error path logging to TCP server code. - [#2032](https://github.com/TokTok/c-toxcore/pull/2032) chore: update the list of CMake options & Windows Docker build deps - [#2031](https://github.com/TokTok/c-toxcore/pull/2031) fix: remove bogus asserts in fuzzer harness - [#2030](https://github.com/TokTok/c-toxcore/pull/2030) chore: expand fuzzing to toxsave - [#2028](https://github.com/TokTok/c-toxcore/pull/2028) fix: syntax error introduced in 8bf37994fd12acec9e3010437502f478399b99b4 - [#2027](https://github.com/TokTok/c-toxcore/pull/2027) fix: add continous fuzzing - [#2026](https://github.com/TokTok/c-toxcore/pull/2026) chore: Fix implicit declaration warning in fuzz build - [#2025](https://github.com/TokTok/c-toxcore/pull/2025) chore: add continous fuzzing to our CI - [#2024](https://github.com/TokTok/c-toxcore/pull/2024) perf: Reduce minimal encoding size of packed events. - [#2023](https://github.com/TokTok/c-toxcore/pull/2023) cleanup: Add wrapper library for msgpack pack functions - [#2022](https://github.com/TokTok/c-toxcore/pull/2022) cleanup: Split tox_unpack into two smaller libs - [#2021](https://github.com/TokTok/c-toxcore/pull/2021) chore: Disable non-null attributes by default. - [#2019](https://github.com/TokTok/c-toxcore/pull/2019) chore: Silence clang compile warnings causing circle-ci/asan to fail - [#2018](https://github.com/TokTok/c-toxcore/pull/2018) fix: Coverty scan - [#2016](https://github.com/TokTok/c-toxcore/pull/2016) docs: Add libmsgpack dependency in INSTALL.md - [#2015](https://github.com/TokTok/c-toxcore/pull/2015) fix: shared toxcore autotools build failing - [#2013](https://github.com/TokTok/c-toxcore/pull/2013) cleanup: Don't use VLAs for huge allocations. - [#2011](https://github.com/TokTok/c-toxcore/pull/2011) fix: Conan build link failures - [#2010](https://github.com/TokTok/c-toxcore/pull/2010) chore: Remove duplicate source file in autotools build. - [#2008](https://github.com/TokTok/c-toxcore/pull/2008) chore: get skeletons out of the closet - [#2007](https://github.com/TokTok/c-toxcore/pull/2007) feat: add bash-completion for tox-bootstrapd - [#2006](https://github.com/TokTok/c-toxcore/pull/2006) cleanup: Add more nonnull and nullable annotations. - [#2002](https://github.com/TokTok/c-toxcore/pull/2002) cleanup: Add nonnull annotations to function definitions. - [#2001](https://github.com/TokTok/c-toxcore/pull/2001) chore: Add an undefined behaviour/integer sanitizer build. - [#1999](https://github.com/TokTok/c-toxcore/pull/1999) chore: Speed up cmake builds with `UNITY_BUILD`. - [#1996](https://github.com/TokTok/c-toxcore/pull/1996) feat: Add unpacker functions for events structures. - [#1993](https://github.com/TokTok/c-toxcore/pull/1993) feat: Add binary packing functions for tox events. - [#1992](https://github.com/TokTok/c-toxcore/pull/1992) chore: Set up an Android CI job - [#1988](https://github.com/TokTok/c-toxcore/pull/1988) cleanup: Make LAN discovery thread-safe without data races. - [#1987](https://github.com/TokTok/c-toxcore/pull/1987) cleanup: Comply with new cimple callback rules. - [#1985](https://github.com/TokTok/c-toxcore/pull/1985) cleanup: Split msi callback array into 1 member per callback - [#1982](https://github.com/TokTok/c-toxcore/pull/1982) chore: Add an easy way to run autotools and circleci builds locally. - [#1979](https://github.com/TokTok/c-toxcore/pull/1979) chore: Update readme header - [#1952](https://github.com/TokTok/c-toxcore/pull/1952) feat: Add async event handling (callbacks) code. - [#1935](https://github.com/TokTok/c-toxcore/pull/1935) feat: add DHT queries to private API - [#1668](https://github.com/TokTok/c-toxcore/pull/1668) perf: Take advantage of fast networks for file transfers ### Closed issues: - [#2009](https://github.com/TokTok/c-toxcore/issues/2009) Autotools build fails - [#2004](https://github.com/TokTok/c-toxcore/issues/2004) Add `nullable` and `nonnull` annotations to all functions. - [#1998](https://github.com/TokTok/c-toxcore/issues/1998) Large stack allocations - [#1977](https://github.com/TokTok/c-toxcore/issues/1977) Turn array of callbacks in msi.h into separate callbacks. - [#1670](https://github.com/TokTok/c-toxcore/issues/1670) Broken link in readme - [#405](https://github.com/TokTok/c-toxcore/issues/405) Remove all¹ uses of global state in toxcore - [#340](https://github.com/TokTok/c-toxcore/issues/340) Set up a continuous integration build for Android - [#236](https://github.com/TokTok/c-toxcore/issues/236) Tox file transfers do not use available bandwidth - [#128](https://github.com/TokTok/c-toxcore/issues/128) Toxcore should provide an easy, local method for making sure Travis checks will pass ## v0.2.15 ### Merged PRs: - [#1984](https://github.com/TokTok/c-toxcore/pull/1984) fix: Reduce logging verbosity even more. - [#1983](https://github.com/TokTok/c-toxcore/pull/1983) chore: Release 0.2.15 - [#1980](https://github.com/TokTok/c-toxcore/pull/1980) fix: Reduce logging verbosity in TCP server. ## v0.2.14 ### Merged PRs: - [#1978](https://github.com/TokTok/c-toxcore/pull/1978) chore: Release 0.2.14 - [#1976](https://github.com/TokTok/c-toxcore/pull/1976) docs: Make crypto_core.h appear on doxygen. - [#1975](https://github.com/TokTok/c-toxcore/pull/1975) refactor: use proper method for generating random numbers in a range - [#1974](https://github.com/TokTok/c-toxcore/pull/1974) docs: Add doxygen configuration and netlify publishing. - [#1972](https://github.com/TokTok/c-toxcore/pull/1972) chore: Make the last few remaining top level comments doxygen style. - [#1971](https://github.com/TokTok/c-toxcore/pull/1971) chore: Sync all comments between header and source files. - [#1968](https://github.com/TokTok/c-toxcore/pull/1968) cleanup: Ensure we limit the system headers included in .h files. - [#1964](https://github.com/TokTok/c-toxcore/pull/1964) cleanup: Don't pass the whole DHT object to lan discovery. - [#1958](https://github.com/TokTok/c-toxcore/pull/1958) chore: Make run-infer script use docker. - [#1956](https://github.com/TokTok/c-toxcore/pull/1956) chore: Disable some cimple warnings for now. - [#1955](https://github.com/TokTok/c-toxcore/pull/1955) cleanup: Properly copy Node_format using serialized format - [#1954](https://github.com/TokTok/c-toxcore/pull/1954) cleanup: make functions take const pointer to IP_Port wherever possible - [#1950](https://github.com/TokTok/c-toxcore/pull/1950) feat: Add WASM build for toxcore and websocket bootstrap node. - [#1948](https://github.com/TokTok/c-toxcore/pull/1948) fix: potential freeing of an immutable static buffer - [#1945](https://github.com/TokTok/c-toxcore/pull/1945) fix: Fix bootstrap on emscripten/wasm. - [#1943](https://github.com/TokTok/c-toxcore/pull/1943) chore: use latest toktok-stack msan version - [#1942](https://github.com/TokTok/c-toxcore/pull/1942) cleanup: Add some toxav bounds/sanity checks - [#1940](https://github.com/TokTok/c-toxcore/pull/1940) chore: Use latest instead of versioned toktok-stack image. - [#1939](https://github.com/TokTok/c-toxcore/pull/1939) chore: Rename bazel-release to -opt and -debug to -dbg. - [#1938](https://github.com/TokTok/c-toxcore/pull/1938) cleanup: small refactor of DHT getnodes function - [#1937](https://github.com/TokTok/c-toxcore/pull/1937) cleanup: remove brackets from ip_ntoa ipv6 formatting - [#1933](https://github.com/TokTok/c-toxcore/pull/1933) chore: Add a Bazel Buildifier CI job - [#1932](https://github.com/TokTok/c-toxcore/pull/1932) test: separate run_auto_tests into a library (revival of #1505) - [#1929](https://github.com/TokTok/c-toxcore/pull/1929) cleanup: make some non-const pointers const - [#1928](https://github.com/TokTok/c-toxcore/pull/1928) fix: unintentional integer down-casts - [#1926](https://github.com/TokTok/c-toxcore/pull/1926) fix: group av memory leak - [#1924](https://github.com/TokTok/c-toxcore/pull/1924) test: refactor autotest live network bootstrapping - [#1923](https://github.com/TokTok/c-toxcore/pull/1923) fix: corruption in key files, making it unable to load when node starts. - [#1922](https://github.com/TokTok/c-toxcore/pull/1922) chore: Don't run sonar scan on pull requests. - [#1920](https://github.com/TokTok/c-toxcore/pull/1920) cleanup: refactor group audio packet data handling - [#1918](https://github.com/TokTok/c-toxcore/pull/1918) chore: Run sonar scan on pull requests. - [#1917](https://github.com/TokTok/c-toxcore/pull/1917) fix: buffer overwrite in bootstrap config - [#1916](https://github.com/TokTok/c-toxcore/pull/1916) chore: Add a make_single_file script, used for CI. - [#1915](https://github.com/TokTok/c-toxcore/pull/1915) cleanup: replace magic numbers with appropriately named constants - [#1914](https://github.com/TokTok/c-toxcore/pull/1914) chore: Add cpplint to the CI. - [#1912](https://github.com/TokTok/c-toxcore/pull/1912) cleanup: Remove uses of `strcpy` and `sprintf`. - [#1910](https://github.com/TokTok/c-toxcore/pull/1910) cleanup: Remove our only use of flexible array members in toxcore. - [#1909](https://github.com/TokTok/c-toxcore/pull/1909) chore: Expose public API headers as files in bazel. - [#1906](https://github.com/TokTok/c-toxcore/pull/1906) cleanup: Split large switch statement into functions. - [#1905](https://github.com/TokTok/c-toxcore/pull/1905) chore: Mark unsafe code as testonly. - [#1903](https://github.com/TokTok/c-toxcore/pull/1903) cleanup: Even more pointer-to-const parameters. - [#1901](https://github.com/TokTok/c-toxcore/pull/1901) cleanup: Make parameters pointers-to-const where possible. - [#1900](https://github.com/TokTok/c-toxcore/pull/1900) cleanup: Remove old check Suite compat layer. - [#1899](https://github.com/TokTok/c-toxcore/pull/1899) cleanup: Make `Networking_Core` pointer-to-const where possible. - [#1898](https://github.com/TokTok/c-toxcore/pull/1898) cleanup: Use pointer cast instead of memcpy in qsort callback. - [#1897](https://github.com/TokTok/c-toxcore/pull/1897) refactor: Deduplicate a bunch of code in TCP client/server. - [#1894](https://github.com/TokTok/c-toxcore/pull/1894) cleanup: Deduplicate a somewhat complex loop in DHT.c. - [#1891](https://github.com/TokTok/c-toxcore/pull/1891) cleanup: Remove our only use of sprintf. - [#1889](https://github.com/TokTok/c-toxcore/pull/1889) cleanup: Stop using `strerror` directly. - [#1887](https://github.com/TokTok/c-toxcore/pull/1887) test: Add two more bootstrap/TCP nodes to autotests - [#1884](https://github.com/TokTok/c-toxcore/pull/1884) chore: Add mypy Python type check. - [#1883](https://github.com/TokTok/c-toxcore/pull/1883) chore: Add sonar-scan analysis on pushes. - [#1881](https://github.com/TokTok/c-toxcore/pull/1881) cleanup: Merge crypto_core and crypto_core_mem. - [#1880](https://github.com/TokTok/c-toxcore/pull/1880) chore: Run static analysers in multiple variants. - [#1879](https://github.com/TokTok/c-toxcore/pull/1879) fix: Fix `toxav_basic_test` buffer overflow. - [#1878](https://github.com/TokTok/c-toxcore/pull/1878) fix: don't count filetransfer as sending until accepted - [#1877](https://github.com/TokTok/c-toxcore/pull/1877) fix: Fix some uninitialised memory errors found by valgrind. - [#1876](https://github.com/TokTok/c-toxcore/pull/1876) chore: Ignore some failures in bazel-tsan. - [#1875](https://github.com/TokTok/c-toxcore/pull/1875) chore: Add asan/tsan bazel builds. - [#1874](https://github.com/TokTok/c-toxcore/pull/1874) cleanup: replace all instances of atoi with strtol - [#1873](https://github.com/TokTok/c-toxcore/pull/1873) chore: Enable layering check in all c-toxcore build files. - [#1871](https://github.com/TokTok/c-toxcore/pull/1871) chore: Enable compiler layering check. - [#1870](https://github.com/TokTok/c-toxcore/pull/1870) chore: Disable the OpenMP cracker in bazel for now. - [#1867](https://github.com/TokTok/c-toxcore/pull/1867) chore: Retry asan/tsan tests a few more times. - [#1866](https://github.com/TokTok/c-toxcore/pull/1866) chore: Run tokstyle with 3 cores. - [#1865](https://github.com/TokTok/c-toxcore/pull/1865) cleanup: Remove extra parens around function arguments. - [#1864](https://github.com/TokTok/c-toxcore/pull/1864) cleanup: Don't use memcpy where assignment can be used. - [#1862](https://github.com/TokTok/c-toxcore/pull/1862) chore: Remove all references to Travis CI. - [#1861](https://github.com/TokTok/c-toxcore/pull/1861) cleanup: Use `calloc` instead of `malloc` for struct allocations. - [#1860](https://github.com/TokTok/c-toxcore/pull/1860) cleanup: Fix `calloc` argument order. - [#1857](https://github.com/TokTok/c-toxcore/pull/1857) chore: Get all* autotests working with MSVC - [#1853](https://github.com/TokTok/c-toxcore/pull/1853) cleanup: Remove useless parentheses. - [#1850](https://github.com/TokTok/c-toxcore/pull/1850) chore: Add a GH Actions code coverage job - [#1845](https://github.com/TokTok/c-toxcore/pull/1845) fix: use correct sample size in toxav_basic_test - [#1844](https://github.com/TokTok/c-toxcore/pull/1844) cleanup: make struct typedefs have the same name as their struct - [#1841](https://github.com/TokTok/c-toxcore/pull/1841) cleanup: refactor toxav_call_control - [#1840](https://github.com/TokTok/c-toxcore/pull/1840) chore: Remove old travis docker scripts. - [#1837](https://github.com/TokTok/c-toxcore/pull/1837) chore: Add bazel-debug build. - [#1836](https://github.com/TokTok/c-toxcore/pull/1836) fix: possible unintended negative loop bound - [#1835](https://github.com/TokTok/c-toxcore/pull/1835) cleanup: remove dead code - [#1834](https://github.com/TokTok/c-toxcore/pull/1834) cleanup: Reduce the scope of for-loop iterator variables. - [#1832](https://github.com/TokTok/c-toxcore/pull/1832) fix: a double-unlocking mutex in toxav - [#1830](https://github.com/TokTok/c-toxcore/pull/1830) chore: Add "tcc" and "compcert" compiler targets. - [#1820](https://github.com/TokTok/c-toxcore/pull/1820) chore: Add macOS build. - [#1819](https://github.com/TokTok/c-toxcore/pull/1819) refactor: Extract some functions from the big run_auto_test function. - [#1818](https://github.com/TokTok/c-toxcore/pull/1818) feat: Add programs for creating savedata & bootstrap keys - [#1816](https://github.com/TokTok/c-toxcore/pull/1816) cleanup: put breaks inside case braces - [#1815](https://github.com/TokTok/c-toxcore/pull/1815) test: add ability for autotests to use TCP connections - [#1813](https://github.com/TokTok/c-toxcore/pull/1813) chore: Login to dockerhub before trying to push to dockerhub. - [#1812](https://github.com/TokTok/c-toxcore/pull/1812) chore: Only push versioned docker image on tag builds. - [#1811](https://github.com/TokTok/c-toxcore/pull/1811) chore: Add bootstrap daemon docker image build. - [#1810](https://github.com/TokTok/c-toxcore/pull/1810) chore: Remove apidsl comment from tox.h. - [#1807](https://github.com/TokTok/c-toxcore/pull/1807) chore: Don't run CI on master branch pushes. - [#1802](https://github.com/TokTok/c-toxcore/pull/1802) cleanup: Sync doc comments in a few more .c/.h files. - [#1801](https://github.com/TokTok/c-toxcore/pull/1801) chore: Fix up a few source code comment and style issues. - [#1798](https://github.com/TokTok/c-toxcore/pull/1798) chore: merge friend_connections from NGC fork - [#1797](https://github.com/TokTok/c-toxcore/pull/1797) cleanup: Move `sodium.h` include to front of network.c. - [#1794](https://github.com/TokTok/c-toxcore/pull/1794) chore: Move cmake-freebsd-stage2 back into the toxcore repo. - [#1793](https://github.com/TokTok/c-toxcore/pull/1793) chore: Add FreeBSD build to CI. - [#1792](https://github.com/TokTok/c-toxcore/pull/1792) chore: Add cross compilation CI targets. - [#1790](https://github.com/TokTok/c-toxcore/pull/1790) cleanup: remove redundant (and incorrect) comments - [#1789](https://github.com/TokTok/c-toxcore/pull/1789) refactor: rename variable to clarify purpose - [#1786](https://github.com/TokTok/c-toxcore/pull/1786) cleanup: Remove apidsl; remove `crypto_memcmp`. - [#1783](https://github.com/TokTok/c-toxcore/pull/1783) cleanup: fix format-source - [#1779](https://github.com/TokTok/c-toxcore/pull/1779) chore: Update toktok-stack version. - [#1778](https://github.com/TokTok/c-toxcore/pull/1778) chore: Tie down the use of doxygen comments. - [#1777](https://github.com/TokTok/c-toxcore/pull/1777) cleanup: Remove crypto_pwhash import. - [#1776](https://github.com/TokTok/c-toxcore/pull/1776) cleanup: remove unused function argument from set_tcp_connection_status() - [#1775](https://github.com/TokTok/c-toxcore/pull/1775) cleanup: Remove apidsl for everything except the public API. - [#1774](https://github.com/TokTok/c-toxcore/pull/1774) chore: Remove config.h. - [#1773](https://github.com/TokTok/c-toxcore/pull/1773) chore: Fix gen-file.sh: it wasn't globbing properly. - [#1772](https://github.com/TokTok/c-toxcore/pull/1772) chore: Add .cc files to the static analysis. - [#1770](https://github.com/TokTok/c-toxcore/pull/1770) cleanup: merge onion.c changes from new groupchats fork - [#1769](https://github.com/TokTok/c-toxcore/pull/1769) chore: merge tcp_connection changes from new groupchats fork - [#1768](https://github.com/TokTok/c-toxcore/pull/1768) chore: merge DHT changes from new groupchats fork - [#1766](https://github.com/TokTok/c-toxcore/pull/1766) chore: Use docker for the autotools ci build. - [#1765](https://github.com/TokTok/c-toxcore/pull/1765) fix: Fix file permission issue with toxchat/bootstrap-node Docker container - [#1762](https://github.com/TokTok/c-toxcore/pull/1762) chore: Add autotools build; exempt crypto_pwhash from tokstyle. - [#1761](https://github.com/TokTok/c-toxcore/pull/1761) cleanup: Don't include `"config.h"` unless needed. - [#1759](https://github.com/TokTok/c-toxcore/pull/1759) cleanup: address some unused return values - [#1758](https://github.com/TokTok/c-toxcore/pull/1758) test: Make ERROR logging fatal in tests. - [#1754](https://github.com/TokTok/c-toxcore/pull/1754) fix: off-by-one error caused by integer division without proper cast - [#1753](https://github.com/TokTok/c-toxcore/pull/1753) cleanup: use crypto_memzero to wipe secret keys when no longer in use - [#1752](https://github.com/TokTok/c-toxcore/pull/1752) chore: Use an incrementing version number for coverity scans. - [#1751](https://github.com/TokTok/c-toxcore/pull/1751) fix: Fixed uninitialised value copy. - [#1747](https://github.com/TokTok/c-toxcore/pull/1747) cleanup: Fix some clang-tidy warnings and make them errors. - [#1746](https://github.com/TokTok/c-toxcore/pull/1746) chore: Add clang-tidy review github workflow. - [#1744](https://github.com/TokTok/c-toxcore/pull/1744) cleanup: Enforce for loop consistency. - [#1743](https://github.com/TokTok/c-toxcore/pull/1743) chore: Minor cleanups of warnings given by cppcheck. - [#1742](https://github.com/TokTok/c-toxcore/pull/1742) test: Add a simple test for `ip_ntoa`. - [#1740](https://github.com/TokTok/c-toxcore/pull/1740) cleanup: Put fatal errors where API return values should be impossible - [#1738](https://github.com/TokTok/c-toxcore/pull/1738) chore: Add missing `sudo` to coverity apt-get calls. - [#1737](https://github.com/TokTok/c-toxcore/pull/1737) refactor: Fix previous refactor - [#1736](https://github.com/TokTok/c-toxcore/pull/1736) chore: Add workflow for running coverity scan. - [#1735](https://github.com/TokTok/c-toxcore/pull/1735) cleanup: Use `static_assert` instead of preprocessor `#error`. - [#1734](https://github.com/TokTok/c-toxcore/pull/1734) chore: Add logger to onion and onion announce objects - [#1733](https://github.com/TokTok/c-toxcore/pull/1733) cleanup: Minor fixes in test code. - [#1732](https://github.com/TokTok/c-toxcore/pull/1732) cleanup: Refactor kill_nonused_tcp() - [#1730](https://github.com/TokTok/c-toxcore/pull/1730) cleanup: Fix last instance of `-Wcast-align` and enable the warning. - [#1729](https://github.com/TokTok/c-toxcore/pull/1729) cleanup: Ensure that error codes are always initialised. - [#1727](https://github.com/TokTok/c-toxcore/pull/1727) cleanup: Avoid endian-specific code in `crypto_core`. - [#1720](https://github.com/TokTok/c-toxcore/pull/1720) feat: Add automatic fuzz testing for c-toxcore - [#1673](https://github.com/TokTok/c-toxcore/pull/1673) cleanup: Remove hardening code from DHT - [#1622](https://github.com/TokTok/c-toxcore/pull/1622) perf: Make the key cracker a bit faster - [#1333](https://github.com/TokTok/c-toxcore/pull/1333) refactor: Clean up friend loading. - [#1307](https://github.com/TokTok/c-toxcore/pull/1307) refactor: Split toxav_iterate into audio and video part ### Closed issues: - [#1967](https://github.com/TokTok/c-toxcore/issues/1967) Potential freeing of an immutable static buffer - [#1788](https://github.com/TokTok/c-toxcore/issues/1788) Rename dht->last_run - [#1719](https://github.com/TokTok/c-toxcore/issues/1719) Enforce braces around macros that compute a value - [#1694](https://github.com/TokTok/c-toxcore/issues/1694) Double unlocking in the ac_iterate - [#1332](https://github.com/TokTok/c-toxcore/issues/1332) Padding bytes in Tox save format are not specified - [#1217](https://github.com/TokTok/c-toxcore/issues/1217) valgrind reports "Conditional jump or move depends on uninitialised value(s)" - [#1118](https://github.com/TokTok/c-toxcore/issues/1118) Fix threading issues in tests caught by tsan (data race etc) - [#1087](https://github.com/TokTok/c-toxcore/issues/1087) Remove all uses of `%zu` in printf formats. - [#1040](https://github.com/TokTok/c-toxcore/issues/1040) Random numbers should not be produced using `rng() % max`. - [#540](https://github.com/TokTok/c-toxcore/issues/540) Stop deleting source files - [#501](https://github.com/TokTok/c-toxcore/issues/501) Testsuite fails and hangs on FreeBSD - [#451](https://github.com/TokTok/c-toxcore/issues/451) Don't fail when building toxcore on windows with `cmake .` - [#350](https://github.com/TokTok/c-toxcore/issues/350) Configure coverity runs for nightly builds - [#349](https://github.com/TokTok/c-toxcore/issues/349) Run clang-tidy on Travis with specific warnings as errors. - [#348](https://github.com/TokTok/c-toxcore/issues/348) Run cppcheck on Travis and push the results to toktok.github.io. - [#323](https://github.com/TokTok/c-toxcore/issues/323) Set library version on future releases - [#235](https://github.com/TokTok/c-toxcore/issues/235) Video corruption: Don't drop video keyframes - [#203](https://github.com/TokTok/c-toxcore/issues/203) ToxAV is still on the old API style - [#198](https://github.com/TokTok/c-toxcore/issues/198) Crash on call while peer calling you - [#167](https://github.com/TokTok/c-toxcore/issues/167) Const-ify pointers - [#124](https://github.com/TokTok/c-toxcore/issues/124) Don't include OS specific headers in .h files - [#106](https://github.com/TokTok/c-toxcore/issues/106) Sometimes Toxcore reports the wrong connection status for both the DHT, and friends. - [#85](https://github.com/TokTok/c-toxcore/issues/85) Reproducible Builds // OBS a bad Idea ## v0.2.13 ### Merged PRs: - [#1725](https://github.com/TokTok/c-toxcore/pull/1725) cleanup: add some missing null checks - [#1723](https://github.com/TokTok/c-toxcore/pull/1723) chore: Run infer static analyser on circle ci builds. - [#1722](https://github.com/TokTok/c-toxcore/pull/1722) chore: Release 0.2.13 - [#1718](https://github.com/TokTok/c-toxcore/pull/1718) fix: Sec/fix crypto size compute - [#1716](https://github.com/TokTok/c-toxcore/pull/1716) chore: Use toktok-stack docker image with built third_party. - [#1713](https://github.com/TokTok/c-toxcore/pull/1713) test: Add some unit tests for important internal DHT functions. - [#1708](https://github.com/TokTok/c-toxcore/pull/1708) perf: reduce calling into Mono_Time in DHT - [#1706](https://github.com/TokTok/c-toxcore/pull/1706) chore: Enable cimple tests on cirrus build. - [#1705](https://github.com/TokTok/c-toxcore/pull/1705) fix: issue with save_load autotest - [#1703](https://github.com/TokTok/c-toxcore/pull/1703) chore: Upgrade to toktok-stack:0.0.11. - [#1699](https://github.com/TokTok/c-toxcore/pull/1699) fix: some friend connection issues - [#1698](https://github.com/TokTok/c-toxcore/pull/1698) fix: bug causing API to report wrong self connection status - [#1693](https://github.com/TokTok/c-toxcore/pull/1693) chore: Update IRC info - [#1691](https://github.com/TokTok/c-toxcore/pull/1691) chore: Fix Appveyor and add workarounds for Cirrus CI - [#1686](https://github.com/TokTok/c-toxcore/pull/1686) chore: Enable c-toxcore conan packaging - [#1684](https://github.com/TokTok/c-toxcore/pull/1684) cleanup: Update INSTALL.md instructions - [#1679](https://github.com/TokTok/c-toxcore/pull/1679) cleanup: Trivial cleanup - [#1674](https://github.com/TokTok/c-toxcore/pull/1674) cleanup: filetransfer code - [#1672](https://github.com/TokTok/c-toxcore/pull/1672) docs: Add instructions for building unit tests to INSTALL.md - [#1667](https://github.com/TokTok/c-toxcore/pull/1667) chore: Update tox-bootstrapd checksum due to newer packages in Alpine - [#1664](https://github.com/TokTok/c-toxcore/pull/1664) cleanup: use heap memory instead of stack for large variables - [#1663](https://github.com/TokTok/c-toxcore/pull/1663) fix: Fix file tests on windows - [#1633](https://github.com/TokTok/c-toxcore/pull/1633) fix: AppVeyor failing due to conan remote being added twice - [#1602](https://github.com/TokTok/c-toxcore/pull/1602) fix: Fix buffer over-read when a peer leaves a conference - [#1586](https://github.com/TokTok/c-toxcore/pull/1586) test: Fix tcp_relay_test by adding a second bootstrap node. - [#1580](https://github.com/TokTok/c-toxcore/pull/1580) style: Format comments according to tokstyle's requirements. - [#1557](https://github.com/TokTok/c-toxcore/pull/1557) chore: Add conan support - [#1537](https://github.com/TokTok/c-toxcore/pull/1537) chore: Cygwin build - [#1516](https://github.com/TokTok/c-toxcore/pull/1516) cleanup: Make pylint and mypy happy with bootstrap_node_info.py. - [#1515](https://github.com/TokTok/c-toxcore/pull/1515) style: Run restyled on Travis and Circle CI scripts. - [#1514](https://github.com/TokTok/c-toxcore/pull/1514) refactor: Remove multi-declarators entirely. - [#1513](https://github.com/TokTok/c-toxcore/pull/1513) refactor: Disallow multiple initialised declarators per decl. - [#1510](https://github.com/TokTok/c-toxcore/pull/1510) chore: Don't build pushes to branches, only to tags. - [#1504](https://github.com/TokTok/c-toxcore/pull/1504) chore: Remove release-drafter configuration in favour of global one. - [#1498](https://github.com/TokTok/c-toxcore/pull/1498) refactor: Limit scope of loop iterators. - [#1497](https://github.com/TokTok/c-toxcore/pull/1497) refactor: Use bash arrays instead of strings for static analysis scripts. - [#1496](https://github.com/TokTok/c-toxcore/pull/1496) cleanup: Stop hard-coding packet IDs in tests. - [#1495](https://github.com/TokTok/c-toxcore/pull/1495) chore: Exclude imported libsodium sources from restyled. - [#1493](https://github.com/TokTok/c-toxcore/pull/1493) feat: Add logging to TCP and onion client. - [#1489](https://github.com/TokTok/c-toxcore/pull/1489) cleanup: `NAC_LIBS` -> `NACL_LIBS`. - [#1487](https://github.com/TokTok/c-toxcore/pull/1487) chore: Add autotools build to localbuild docker images. - [#1473](https://github.com/TokTok/c-toxcore/pull/1473) chore: Add a script to run Travis CI locally. - [#1467](https://github.com/TokTok/c-toxcore/pull/1467) fix: Fix a bug in savedata loading when malloc fails. - [#1464](https://github.com/TokTok/c-toxcore/pull/1464) fix: Fix errors on error paths found by oomer. - [#1463](https://github.com/TokTok/c-toxcore/pull/1463) cleanup: Add a check that we don't have any unused functions. - [#1462](https://github.com/TokTok/c-toxcore/pull/1462) cleanup: Include `` for `explicit_bzero`. - [#1436](https://github.com/TokTok/c-toxcore/pull/1436) chore: Enable cimple tests by default but allow disabling them. ### Closed issues: - [#1598](https://github.com/TokTok/c-toxcore/issues/1598) ERROR: heap-buffer-overflow in group.c found with AddressSanitizer - [#1326](https://github.com/TokTok/c-toxcore/issues/1326) the cause is great, but this thing is completely unusable - [#1319](https://github.com/TokTok/c-toxcore/issues/1319) Is this new application is safe & trusted ?? - [#1236](https://github.com/TokTok/c-toxcore/issues/1236) Ruby Extension? - [#1149](https://github.com/TokTok/c-toxcore/issues/1149) uTox aborts on toxcore restart - [#886](https://github.com/TokTok/c-toxcore/issues/886) Maybe need to set the stacksize for musl-libc ## v0.2.12 ### Merged PRs: - [#1458](https://github.com/TokTok/c-toxcore/pull/1458) Release 0.2.12 - [#1457](https://github.com/TokTok/c-toxcore/pull/1457) Disable non-hermetic tests by default. - [#1456](https://github.com/TokTok/c-toxcore/pull/1456) Limit the number of friends you can have to ~4 billion. - [#1452](https://github.com/TokTok/c-toxcore/pull/1452) Add execution trace option for debugging. - [#1444](https://github.com/TokTok/c-toxcore/pull/1444) Set up release-drafter to automatically draft the next release. - [#1443](https://github.com/TokTok/c-toxcore/pull/1443) Allow test coverage to fluctuate 2% up and down, but not below 80%. - [#1442](https://github.com/TokTok/c-toxcore/pull/1442) Add CODEOWNERS and settings.yml files. - [#1441](https://github.com/TokTok/c-toxcore/pull/1441) [ImgBot] Optimize images - [#1439](https://github.com/TokTok/c-toxcore/pull/1439) Fix continuous integration builds. - [#1437](https://github.com/TokTok/c-toxcore/pull/1437) Rework the toxchat/bootstrap-node Docker image. - [#1435](https://github.com/TokTok/c-toxcore/pull/1435) Enable TCP relay test in Bazel and autotools build. - [#1434](https://github.com/TokTok/c-toxcore/pull/1434) Skip invalid TCP relays and DHT nodes when loading save data. - [#1433](https://github.com/TokTok/c-toxcore/pull/1433) Fix saving of combination of loaded and connected TCP relays - [#1430](https://github.com/TokTok/c-toxcore/pull/1430) Invert `not_valid` functions and name them `is_valid`. - [#1429](https://github.com/TokTok/c-toxcore/pull/1429) Fix things not being initialized if creating a TCP-only network - [#1426](https://github.com/TokTok/c-toxcore/pull/1426) Remove tokstyle exemptions from build files. - [#1425](https://github.com/TokTok/c-toxcore/pull/1425) Stop using the "inline namespace" feature of apidsl. - [#1424](https://github.com/TokTok/c-toxcore/pull/1424) Add new semi-private API functions to set per-packet-id custom handlers. - [#1423](https://github.com/TokTok/c-toxcore/pull/1423) Give CI workflow a better name: clang-sanitizers - [#1422](https://github.com/TokTok/c-toxcore/pull/1422) Use public API for sending in RTP - [#1421](https://github.com/TokTok/c-toxcore/pull/1421) Install ci-tools and get tokstyle via the script it provides. - [#1420](https://github.com/TokTok/c-toxcore/pull/1420) Use tox public API for sending packets in toxav BWController - [#1419](https://github.com/TokTok/c-toxcore/pull/1419) Remove newlines from the end of LOGGER format strings. - [#1418](https://github.com/TokTok/c-toxcore/pull/1418) Change ToxAVCall struct mutex to a more distinct name - [#1417](https://github.com/TokTok/c-toxcore/pull/1417) Create own instance of Mono_Time for ToxAV - [#1416](https://github.com/TokTok/c-toxcore/pull/1416) Stop using Messenger's mono_time in bandwidth controller. - [#1415](https://github.com/TokTok/c-toxcore/pull/1415) Fix 2 memory leaks in ToxAV. - [#1414](https://github.com/TokTok/c-toxcore/pull/1414) Show function names in asan/tsan stack traces on CircleCI. - [#1413](https://github.com/TokTok/c-toxcore/pull/1413) Make afl_toxsave.c a bit more portable; fix memory leak. - [#1411](https://github.com/TokTok/c-toxcore/pull/1411) Fixes towards building on MSVC. - [#1409](https://github.com/TokTok/c-toxcore/pull/1409) Mark conference test as small. - [#1407](https://github.com/TokTok/c-toxcore/pull/1407) Add minimal save generator - [#1406](https://github.com/TokTok/c-toxcore/pull/1406) Migrate format-source script to new apidsl web app. - [#1404](https://github.com/TokTok/c-toxcore/pull/1404) Smarter setup of bazel remote cache on Cirrus CI. - [#1331](https://github.com/TokTok/c-toxcore/pull/1331) Add basic test adapter for AFL ### Closed issues: - [#1365](https://github.com/TokTok/c-toxcore/issues/1365) Add the option to use LAN discovery even when using a proxy for remote connections - [#1353](https://github.com/TokTok/c-toxcore/issues/1353) libtoxdns.a and libtoxav.a - [#86](https://github.com/TokTok/c-toxcore/issues/86) Freenet as Offline Messaging Backend ## v0.2.11 ### Merged PRs: - [#1405](https://github.com/TokTok/c-toxcore/pull/1405) Release 0.2.11 - [#1403](https://github.com/TokTok/c-toxcore/pull/1403) Install libsodium from apt instead of from source. - [#1402](https://github.com/TokTok/c-toxcore/pull/1402) Remove bazel build from Travis. - [#1400](https://github.com/TokTok/c-toxcore/pull/1400) Disable bazel remote cache on CI. - [#1399](https://github.com/TokTok/c-toxcore/pull/1399) Periodically try to send direct packets when connected by TCP. - [#1398](https://github.com/TokTok/c-toxcore/pull/1398) Minor cleanup: use `assoc_timeout` function where possible. - [#1397](https://github.com/TokTok/c-toxcore/pull/1397) Check that LOGGER macros are only called with string literals. - [#1396](https://github.com/TokTok/c-toxcore/pull/1396) Make function defns match their decls regarding storage class. - [#1395](https://github.com/TokTok/c-toxcore/pull/1395) Mark file-local function definitions as `static`. - [#1394](https://github.com/TokTok/c-toxcore/pull/1394) Enable remote cache for bazel builds. - [#1393](https://github.com/TokTok/c-toxcore/pull/1393) Add another bootstrap node to the bootstrap test. - [#1392](https://github.com/TokTok/c-toxcore/pull/1392) Clear out old conference connections. - [#1391](https://github.com/TokTok/c-toxcore/pull/1391) Minor cleanups in network code. - [#1390](https://github.com/TokTok/c-toxcore/pull/1390) Avoid casting back and forth between void-ptr. - [#1389](https://github.com/TokTok/c-toxcore/pull/1389) Standardise on having a comma at the end of enums. - [#1388](https://github.com/TokTok/c-toxcore/pull/1388) Fix up comments a bit to start being more uniform. - [#1387](https://github.com/TokTok/c-toxcore/pull/1387) Use rules_cc instead of native cc_library rules. - [#1386](https://github.com/TokTok/c-toxcore/pull/1386) Use spdx license identifier instead of GPL blurb. - [#1383](https://github.com/TokTok/c-toxcore/pull/1383) Pass packet ID to custom packet handlers. - [#1382](https://github.com/TokTok/c-toxcore/pull/1382) Add a mutex lock/unlock inside every public API function. - [#1381](https://github.com/TokTok/c-toxcore/pull/1381) Use `net_pack` instead of casting bytes to ints. - [#1380](https://github.com/TokTok/c-toxcore/pull/1380) Disable FreeBSD travis build until it is fixed. - [#1379](https://github.com/TokTok/c-toxcore/pull/1379) Update and fix FreeBSD setup on Travis-CI - [#1378](https://github.com/TokTok/c-toxcore/pull/1378) Use ninja build system for the cmake-linux build. - [#1376](https://github.com/TokTok/c-toxcore/pull/1376) Remove testing/av_test.c. - [#1375](https://github.com/TokTok/c-toxcore/pull/1375) Add "cimple_test" to the bazel build. - [#1374](https://github.com/TokTok/c-toxcore/pull/1374) Handle invite to existing conference - [#1372](https://github.com/TokTok/c-toxcore/pull/1372) Upgrade bazel to 2.1.1. - [#1371](https://github.com/TokTok/c-toxcore/pull/1371) Bump to astyle-3.1 in travis build. - [#1370](https://github.com/TokTok/c-toxcore/pull/1370) use -1 rather than ~0 in unsigned integer types - [#1362](https://github.com/TokTok/c-toxcore/pull/1362) Workaround for message number saving - [#1358](https://github.com/TokTok/c-toxcore/pull/1358) Allow Bazel to rerun tests marked as flaky - [#1352](https://github.com/TokTok/c-toxcore/pull/1352) Update tests to use a working bootstrap node - [#1349](https://github.com/TokTok/c-toxcore/pull/1349) Fix tox-bootstrapd's README and update Dockerfile - [#1347](https://github.com/TokTok/c-toxcore/pull/1347) Fix pthread_mutex_destroy getting too many arguments - [#1346](https://github.com/TokTok/c-toxcore/pull/1346) Fix most TSAN failures - [#1345](https://github.com/TokTok/c-toxcore/pull/1345) fix concurrency issues in mono_time - [#1343](https://github.com/TokTok/c-toxcore/pull/1343) Fix TSAN failures in tests - [#1334](https://github.com/TokTok/c-toxcore/pull/1334) fix missing group title length check - [#1330](https://github.com/TokTok/c-toxcore/pull/1330) Force IPv4 for cirrus-ci tests - [#1329](https://github.com/TokTok/c-toxcore/pull/1329) bump libsodium version in appveyor.yml - [#1322](https://github.com/TokTok/c-toxcore/pull/1322) Clean-up of group.c code - [#1321](https://github.com/TokTok/c-toxcore/pull/1321) Some small fixes to groups. - [#1299](https://github.com/TokTok/c-toxcore/pull/1299) Add VScode folder to .gitignore - [#1297](https://github.com/TokTok/c-toxcore/pull/1297) Use net_pack/unpack instead of host_to_net. ### Closed issues: - [#1373](https://github.com/TokTok/c-toxcore/issues/1373) handle crashes after group invites - [#1368](https://github.com/TokTok/c-toxcore/issues/1368) Are tox clients also open source - [#1366](https://github.com/TokTok/c-toxcore/issues/1366) Generate a link for websites (Friendship and proxy) - [#1354](https://github.com/TokTok/c-toxcore/issues/1354) Unstable Tests - [#1316](https://github.com/TokTok/c-toxcore/issues/1316) Documentation claims toxav_iteration_interval is threadsafe but it's not - [#1274](https://github.com/TokTok/c-toxcore/issues/1274) build error - [#850](https://github.com/TokTok/c-toxcore/issues/850) GPG App Usage ## v0.2.10 ### Merged PRs: - [#1324](https://github.com/TokTok/c-toxcore/pull/1324) Release 0.2.10 - [#1320](https://github.com/TokTok/c-toxcore/pull/1320) add undef guard in tox_many_tcp_test - [#1314](https://github.com/TokTok/c-toxcore/pull/1314) Fix bazel build version at 0.22.0 for CI. - [#1311](https://github.com/TokTok/c-toxcore/pull/1311) Disable failing TCP server test - [#1310](https://github.com/TokTok/c-toxcore/pull/1310) Do not send the same packet to the same node twice - [#1309](https://github.com/TokTok/c-toxcore/pull/1309) add configurable limit on number of stored frozen peers - [#1305](https://github.com/TokTok/c-toxcore/pull/1305) Expose api functions for enabling and disabling AV in AV groups - [#1302](https://github.com/TokTok/c-toxcore/pull/1302) Specify that buffer size for tox_conference_peer_get_name is given by $size ### Closed issues: - [#1325](https://github.com/TokTok/c-toxcore/issues/1325) Question: ETA of v0.2.10? - [#1313](https://github.com/TokTok/c-toxcore/issues/1313) CirrusCI is failing and blocking PRs - [#1312](https://github.com/TokTok/c-toxcore/issues/1312) Onion client review - [#1306](https://github.com/TokTok/c-toxcore/issues/1306) Persistent conference's offline peer list always grows and never decreases - [#1303](https://github.com/TokTok/c-toxcore/issues/1303) Loaded persistent groups fail to send audio - [#1298](https://github.com/TokTok/c-toxcore/issues/1298) How to make libtox4j-c.so for android? - [#1261](https://github.com/TokTok/c-toxcore/issues/1261) Bump so version - [#1116](https://github.com/TokTok/c-toxcore/issues/1116) Message length is too large log spam ## v0.2.9 ### Merged PRs: - [#1296](https://github.com/TokTok/c-toxcore/pull/1296) Add some const qualifiers - [#1295](https://github.com/TokTok/c-toxcore/pull/1295) Implement all min/max functions for (un)signed int types. - [#1293](https://github.com/TokTok/c-toxcore/pull/1293) Fix misaligned 4-byte access in trace logging. - [#1291](https://github.com/TokTok/c-toxcore/pull/1291) Use correct path to test log to cat on error. - [#1290](https://github.com/TokTok/c-toxcore/pull/1290) Display build log for autotools build on failure. - [#1289](https://github.com/TokTok/c-toxcore/pull/1289) Enable auto tests under STRICT_ABI if static libs are available. - [#1288](https://github.com/TokTok/c-toxcore/pull/1288) Add MIN_LOGGER_LEVEL to the Circle CI builds. - [#1287](https://github.com/TokTok/c-toxcore/pull/1287) Avoid sending group messages to a peer before we have its group number - [#1284](https://github.com/TokTok/c-toxcore/pull/1284) Use new WineHQ Debian package repository key - [#1283](https://github.com/TokTok/c-toxcore/pull/1283) Release 0.2.9 - [#1282](https://github.com/TokTok/c-toxcore/pull/1282) Merge irungentoo/master back into toktok/master. - [#1281](https://github.com/TokTok/c-toxcore/pull/1281) Allow unauthenticated wine packages in the Windows build. - [#1278](https://github.com/TokTok/c-toxcore/pull/1278) Add cmake option for building additional tests - [#1277](https://github.com/TokTok/c-toxcore/pull/1277) Define tox_conference_id_size and tox_conference_uid_size - [#1273](https://github.com/TokTok/c-toxcore/pull/1273) Avoid format truncation in save compatibility test - [#1272](https://github.com/TokTok/c-toxcore/pull/1272) Upgrade bazel to 0.19.0 to fix the bazel build. - [#1271](https://github.com/TokTok/c-toxcore/pull/1271) Return TOX_ERR_CONFERENCE_SEND_MESSAGE_NO_CONNECTION if we are not connected to any peers - [#1268](https://github.com/TokTok/c-toxcore/pull/1268) Fix indices calculation for congestion control. - [#1267](https://github.com/TokTok/c-toxcore/pull/1267) Improve handling of peers entering and leaving conferences - [#1266](https://github.com/TokTok/c-toxcore/pull/1266) Expose offline conference peers in API - [#1242](https://github.com/TokTok/c-toxcore/pull/1242) Fix critical stack overflow arising from VLA usage - [#1239](https://github.com/TokTok/c-toxcore/pull/1239) Add some hopefully helpful documentation to the functions in mono_time.h - [#1235](https://github.com/TokTok/c-toxcore/pull/1235) Change method of PK production for FAKE friend in DHT - [#1234](https://github.com/TokTok/c-toxcore/pull/1234) Increase NOFILE limit for tox-bootstrapd - [#1231](https://github.com/TokTok/c-toxcore/pull/1231) Use `bool` for IPv6 flag in test programs and `DHT_bootstrap`. - [#1230](https://github.com/TokTok/c-toxcore/pull/1230) Add `LOGGER_ASSERT` for checking fatal error conditions. - [#1229](https://github.com/TokTok/c-toxcore/pull/1229) Include `CTest` in CMakeLists.txt to get valgrind support. - [#1228](https://github.com/TokTok/c-toxcore/pull/1228) Consistently use camel case enum names. - [#1223](https://github.com/TokTok/c-toxcore/pull/1223) Add AUTOTEST option to CMakeLists.txt - [#1221](https://github.com/TokTok/c-toxcore/pull/1221) Make tox-bootstrapd free memory on SIGINT and SIGTERM - [#1218](https://github.com/TokTok/c-toxcore/pull/1218) Support DragonFlyBSD and prune unused variables. - [#1215](https://github.com/TokTok/c-toxcore/pull/1215) Ensure save data unchanged after save and load - [#1213](https://github.com/TokTok/c-toxcore/pull/1213) Make saving and loading the responsibility of Tox rather than Messenger - [#1211](https://github.com/TokTok/c-toxcore/pull/1211) Some improvements to tox-bootstrapd's Dockerfile - [#1210](https://github.com/TokTok/c-toxcore/pull/1210) Remove Alpine Linux bootstrap daemon dockerfile. - [#1209](https://github.com/TokTok/c-toxcore/pull/1209) Improve Windows compatibility of toxav code. - [#1206](https://github.com/TokTok/c-toxcore/pull/1206) Add LAN_discovery to the list of apidsl-generated files. - [#1156](https://github.com/TokTok/c-toxcore/pull/1156) conferences saving ### Closed issues: - [#1285](https://github.com/TokTok/c-toxcore/issues/1285) Persistent group titles get mixed up - [#1276](https://github.com/TokTok/c-toxcore/issues/1276) How to run test case? - [#1275](https://github.com/TokTok/c-toxcore/issues/1275) Save file corruption - [#1269](https://github.com/TokTok/c-toxcore/issues/1269) Tox conference connected callback isn't triggered - [#1264](https://github.com/TokTok/c-toxcore/issues/1264) tox_conference_id_size() symbol missing - [#1262](https://github.com/TokTok/c-toxcore/issues/1262) Fails to build with STRICT_ABI option - [#1169](https://github.com/TokTok/c-toxcore/issues/1169) PK should not be generated with random_bytes - [#1143](https://github.com/TokTok/c-toxcore/issues/1143) Test #1081 - [#956](https://github.com/TokTok/c-toxcore/issues/956) friendlist access (add, delete, ...) causes crashes sometimes - [#777](https://github.com/TokTok/c-toxcore/issues/777) Proposal: TFCL [Tox Friend Capabilities Level] - [#762](https://github.com/TokTok/c-toxcore/issues/762) packet ranges not very clearly explained - [#743](https://github.com/TokTok/c-toxcore/issues/743) Proposal: reduce Video corruption even more by negotating the reference frame between sender and receiver - [#735](https://github.com/TokTok/c-toxcore/issues/735) Proposal: Tox MessageV2 - [#663](https://github.com/TokTok/c-toxcore/issues/663) libvpx vulnerability - [#626](https://github.com/TokTok/c-toxcore/issues/626) please add documentation to: bwcontroller.c - [#625](https://github.com/TokTok/c-toxcore/issues/625) function names misleading in ToxAV - [#617](https://github.com/TokTok/c-toxcore/issues/617) WIP: ToxIdenticon - howto - [#610](https://github.com/TokTok/c-toxcore/issues/610) PACKET_LOSSY_AV_RESERVED 8 # why? - [#609](https://github.com/TokTok/c-toxcore/issues/609) payload_type hardcoded - [#589](https://github.com/TokTok/c-toxcore/issues/589) running a normal tox node as tcp relay is not possible - [#584](https://github.com/TokTok/c-toxcore/issues/584) [INFO]: network graphs 0.1.9 vs 0.1.10 - [#548](https://github.com/TokTok/c-toxcore/issues/548) toxcore removes message receipts and filetransfers from memory, when client has short network outage - [#375](https://github.com/TokTok/c-toxcore/issues/375) Invalid bit rate prevents call ## v0.2.8 ### Merged PRs: - [#1225](https://github.com/TokTok/c-toxcore/pull/1225) Release 0.2.8 - [#1224](https://github.com/TokTok/c-toxcore/pull/1224) Avoid use of IPv6 in tests if not supported (e.g. on Travis). - [#1216](https://github.com/TokTok/c-toxcore/pull/1216) Fix memory leak in tcp server by wiping priority queues on deletion. - [#1212](https://github.com/TokTok/c-toxcore/pull/1212) Fix logger level defaulting to TRACE in CMake - [#1208](https://github.com/TokTok/c-toxcore/pull/1208) Remove a function-like macro and replace it with a function. - [#1205](https://github.com/TokTok/c-toxcore/pull/1205) Use a working DHT node for bootstrap tests. - [#1203](https://github.com/TokTok/c-toxcore/pull/1203) Revert "Improve cmake build for MSVC." - [#1202](https://github.com/TokTok/c-toxcore/pull/1202) Reset onion search rate for a friend when we see evidence that they are online - [#1199](https://github.com/TokTok/c-toxcore/pull/1199) Run tests on Appveyor (Windows native build). - [#1198](https://github.com/TokTok/c-toxcore/pull/1198) Add Cirrus CI configuration. - [#1197](https://github.com/TokTok/c-toxcore/pull/1197) Use new `@pthread` library from toktok-stack for Windows compat. - [#1196](https://github.com/TokTok/c-toxcore/pull/1196) Run UBSAN (undefined behaviour sanitizer) on Circle CI. - [#1195](https://github.com/TokTok/c-toxcore/pull/1195) Fix using uninitialized mutex on call end - [#1192](https://github.com/TokTok/c-toxcore/pull/1192) Send rejoin packets on conference disconnection - [#1191](https://github.com/TokTok/c-toxcore/pull/1191) Improve cmake build for MSVC - [#1188](https://github.com/TokTok/c-toxcore/pull/1188) Fix yamllint test (it's gone from bazel, add a new one). - [#1187](https://github.com/TokTok/c-toxcore/pull/1187) Fix typos in comments and log and test assertion messages. - [#1165](https://github.com/TokTok/c-toxcore/pull/1165) Fixed a silly boolean practice using uint8_t - [#1164](https://github.com/TokTok/c-toxcore/pull/1164) Format yaml files according to yamllint's requirements and remove branch filter for appveyor. - [#1161](https://github.com/TokTok/c-toxcore/pull/1161) Use most recent version of Bazel (0.17.1). - [#1158](https://github.com/TokTok/c-toxcore/pull/1158) Use C++ style casts in C++ code. - [#1157](https://github.com/TokTok/c-toxcore/pull/1157) Use run_auto_test fixture in typing_test.c - [#1155](https://github.com/TokTok/c-toxcore/pull/1155) Standardise header guards. - [#1154](https://github.com/TokTok/c-toxcore/pull/1154) Assert that we don't kill tox before killing toxav. - [#1153](https://github.com/TokTok/c-toxcore/pull/1153) Always use the passed logger (from Messenger) in msi_kill. - [#1151](https://github.com/TokTok/c-toxcore/pull/1151) Fix typo: tcp_replays -> tcp_relays. - [#1150](https://github.com/TokTok/c-toxcore/pull/1150) Use `(void)` for empty parameter lists in C. - [#1147](https://github.com/TokTok/c-toxcore/pull/1147) Ignore "unused-result" warning in super_donators code. - [#1145](https://github.com/TokTok/c-toxcore/pull/1145) Fix login issue on Travis-CI FreeBSD build - [#1141](https://github.com/TokTok/c-toxcore/pull/1141) Include necessary opencv2 header on OSX. - [#1140](https://github.com/TokTok/c-toxcore/pull/1140) Clean up `add_to_list` function a bit. - [#1139](https://github.com/TokTok/c-toxcore/pull/1139) Avoid recursion in `ip_is_lan` and `ip_is_local`. - [#1138](https://github.com/TokTok/c-toxcore/pull/1138) Add tool to find directly recursive calls in toxcore. - [#1136](https://github.com/TokTok/c-toxcore/pull/1136) Remove the use of `CLOCK_MONOTONIC_RAW`. - [#1135](https://github.com/TokTok/c-toxcore/pull/1135) Avoid use of global mutable state in mono_time on win32. - [#1134](https://github.com/TokTok/c-toxcore/pull/1134) Use `code font` for tool names and flags in INSTALL.md. - [#1126](https://github.com/TokTok/c-toxcore/pull/1126) Simplify configure.ac for faster autotools build. - [#1095](https://github.com/TokTok/c-toxcore/pull/1095) Use test clock in run_auto_test tests and dht test - [#1069](https://github.com/TokTok/c-toxcore/pull/1069) Add mechanism for recovering from disconnections in conferences - [#1046](https://github.com/TokTok/c-toxcore/pull/1046) Finish the messenger state plugin system - [#895](https://github.com/TokTok/c-toxcore/pull/895) Feature bootstrap trace/debug log output ### Closed issues: - [#1214](https://github.com/TokTok/c-toxcore/issues/1214) Massive red shutdown of nodes - [#1201](https://github.com/TokTok/c-toxcore/issues/1201) Windows cross-compilation is broken - [#1194](https://github.com/TokTok/c-toxcore/issues/1194) Cancelling unanswered toxav call locks uninitialied mutex - [#961](https://github.com/TokTok/c-toxcore/issues/961) Can't send messages in persistent group chat - [#960](https://github.com/TokTok/c-toxcore/issues/960) Persistent groups don't work properly when using toxync bot - [#838](https://github.com/TokTok/c-toxcore/issues/838) How to get groupchat identifier? ## v0.2.7 ### Merged PRs: - [#1142](https://github.com/TokTok/c-toxcore/pull/1142) Release 0.2.7 - [#1137](https://github.com/TokTok/c-toxcore/pull/1137) Make `ip_is_lan` return bool instead of 0/-1. - [#1133](https://github.com/TokTok/c-toxcore/pull/1133) Make the tsan build fail instead of swallowing its errors. - [#1132](https://github.com/TokTok/c-toxcore/pull/1132) Use `bool` in place of 0/1 int values. - [#1131](https://github.com/TokTok/c-toxcore/pull/1131) Format crypto_core.c. - [#1130](https://github.com/TokTok/c-toxcore/pull/1130) Fix test class name for mono_time_test. - [#1129](https://github.com/TokTok/c-toxcore/pull/1129) Call `abort` instead of `exit` on test failure. - [#1128](https://github.com/TokTok/c-toxcore/pull/1128) Add some tests for `ping_array`. - [#1127](https://github.com/TokTok/c-toxcore/pull/1127) Update copyright to 2018. - [#1125](https://github.com/TokTok/c-toxcore/pull/1125) Run save_compatibility_test in the autotools build. - [#1124](https://github.com/TokTok/c-toxcore/pull/1124) Fix the `PORT_ALLOC` failure of `save_compatibility_test`. - [#1123](https://github.com/TokTok/c-toxcore/pull/1123) Add support for setting a custom monotonic time function in mono_time - [#1122](https://github.com/TokTok/c-toxcore/pull/1122) Run all tests (and compilation) in parallel with autotools. - [#1120](https://github.com/TokTok/c-toxcore/pull/1120) Stop using massive macros in `toxav_basic_test`. - [#1119](https://github.com/TokTok/c-toxcore/pull/1119) Use do-while instead of while in tests. - [#1117](https://github.com/TokTok/c-toxcore/pull/1117) Fix leave callback calling in del_groupchat - [#1112](https://github.com/TokTok/c-toxcore/pull/1112) Fix auto_tests Makefile - [#1110](https://github.com/TokTok/c-toxcore/pull/1110) Add check to make sure tox was created successfully - [#1109](https://github.com/TokTok/c-toxcore/pull/1109) Consistently use 'mono_time' rather than 'monotime' - [#1107](https://github.com/TokTok/c-toxcore/pull/1107) Always print output on failure in cmake tests on Travis. - [#1106](https://github.com/TokTok/c-toxcore/pull/1106) Fix libmisc_tools building - [#1104](https://github.com/TokTok/c-toxcore/pull/1104) Avoid redefining macros from different files. - [#1103](https://github.com/TokTok/c-toxcore/pull/1103) Upload coverage to codecov as well as coveralls. - [#1102](https://github.com/TokTok/c-toxcore/pull/1102) Enable color diagnostics on circleci. - [#1101](https://github.com/TokTok/c-toxcore/pull/1101) Make the save_compatibility_test work with bazel. - [#1100](https://github.com/TokTok/c-toxcore/pull/1100) Make Mono_Time an argument to current_time_monotonic - [#1099](https://github.com/TokTok/c-toxcore/pull/1099) Fix const cast in save-generator. - [#1098](https://github.com/TokTok/c-toxcore/pull/1098) Run both asan and tsan on Circle CI. - [#1097](https://github.com/TokTok/c-toxcore/pull/1097) Run project tests like yamllint_test. - [#1096](https://github.com/TokTok/c-toxcore/pull/1096) Enable .travis.yml check and use non-markdown license. - [#1094](https://github.com/TokTok/c-toxcore/pull/1094) Set `_POSIX_C_SOURCE` to 200112L. We need it for C99 compat. - [#1092](https://github.com/TokTok/c-toxcore/pull/1092) Install the `DHT_bootstrap` binary on `make install`. - [#1086](https://github.com/TokTok/c-toxcore/pull/1086) Try ipv6 connections even after udp timeout - [#1081](https://github.com/TokTok/c-toxcore/pull/1081) Change while-loop to for-loop to express for-each-frame. - [#1075](https://github.com/TokTok/c-toxcore/pull/1075) Fix FreeBSD VM on Travis not shutting down - [#1061](https://github.com/TokTok/c-toxcore/pull/1061) Force storing the result of crypto_memcmp in the test. - [#1057](https://github.com/TokTok/c-toxcore/pull/1057) Reduce the number of times `unix_time_update` is called. - [#1051](https://github.com/TokTok/c-toxcore/pull/1051) Add save file generator, compatibility test, and generate a savefile - [#1038](https://github.com/TokTok/c-toxcore/pull/1038) Use per-instance `Mono_Time` instead of a global `unix_time` ### Closed issues: - [#1114](https://github.com/TokTok/c-toxcore/issues/1114) Segfault on group quit, free of invalid audio_decoder - [#1105](https://github.com/TokTok/c-toxcore/issues/1105) Sodium.h missing? ## v0.2.6 ### Merged PRs: - [#1093](https://github.com/TokTok/c-toxcore/pull/1093) Release 0.2.6 - [#1090](https://github.com/TokTok/c-toxcore/pull/1090) Fix possible resource leaks in test - [#1089](https://github.com/TokTok/c-toxcore/pull/1089) Limit the size of a save file in file_saving_test. - [#1088](https://github.com/TokTok/c-toxcore/pull/1088) Use `--config` to tell bazel about the environment. - [#1085](https://github.com/TokTok/c-toxcore/pull/1085) Prune long long warnings. - [#1084](https://github.com/TokTok/c-toxcore/pull/1084) Fix style in toxav.c. - [#1083](https://github.com/TokTok/c-toxcore/pull/1083) Fix coding style in rtp module. - [#1082](https://github.com/TokTok/c-toxcore/pull/1082) Fix groupav.c style and avoid casts in toxav_old.c. - [#1080](https://github.com/TokTok/c-toxcore/pull/1080) Fix memory leak in error path in group A/V. - [#1079](https://github.com/TokTok/c-toxcore/pull/1079) Fix style in video.c. - [#1078](https://github.com/TokTok/c-toxcore/pull/1078) Fix style in msi.c. - [#1077](https://github.com/TokTok/c-toxcore/pull/1077) Make `conferences_object` properly typed. - [#1076](https://github.com/TokTok/c-toxcore/pull/1076) Fix style in bwcontroller module. - [#1074](https://github.com/TokTok/c-toxcore/pull/1074) Move OSX to stage 1 of Travis. - [#1073](https://github.com/TokTok/c-toxcore/pull/1073) Stop running tests in the bazel build. - [#1072](https://github.com/TokTok/c-toxcore/pull/1072) Avoid forward declaration of rtp structs. - [#1071](https://github.com/TokTok/c-toxcore/pull/1071) Temporarily disable FreeBSD build, since it times out. - [#1070](https://github.com/TokTok/c-toxcore/pull/1070) Fix enumerator names in toxav to comply with toxcore naming standards. - [#1068](https://github.com/TokTok/c-toxcore/pull/1068) Fix a few warnings from clang. - [#1067](https://github.com/TokTok/c-toxcore/pull/1067) Remove last use of the `MIN` macro. - [#1066](https://github.com/TokTok/c-toxcore/pull/1066) Remove all uses of the PAIR macro in toxav. - [#1064](https://github.com/TokTok/c-toxcore/pull/1064) Fix ToxAv's use of `struct Tox`. - [#1063](https://github.com/TokTok/c-toxcore/pull/1063) Avoid passing -1 as friend connection to new groups. - [#1062](https://github.com/TokTok/c-toxcore/pull/1062) Check that the save file size isn't larger than our address space. - [#1060](https://github.com/TokTok/c-toxcore/pull/1060) Avoid implicit conversion of negative value to uint32_t. - [#1059](https://github.com/TokTok/c-toxcore/pull/1059) Assert that we don't divide by 0 in random_testing.cc. - [#1056](https://github.com/TokTok/c-toxcore/pull/1056) Fix typo in loop over assocs. - [#1053](https://github.com/TokTok/c-toxcore/pull/1053) Use tokstyle in the cmake travis build. - [#1049](https://github.com/TokTok/c-toxcore/pull/1049) Fix some printf format specifiers. - [#1043](https://github.com/TokTok/c-toxcore/pull/1043) Add simple deterministic random number generator for tests - [#1042](https://github.com/TokTok/c-toxcore/pull/1042) Add callback for successful connection to a conference - [#1039](https://github.com/TokTok/c-toxcore/pull/1039) Use the crypto random functions instead of `rand()`. - [#1036](https://github.com/TokTok/c-toxcore/pull/1036) Add deprecation notice to some UPPER_CASE enums. - [#1016](https://github.com/TokTok/c-toxcore/pull/1016) Split out conference type (text/av) from identifier. ## v0.2.5 ### Merged PRs: - [#1054](https://github.com/TokTok/c-toxcore/pull/1054) Release 0.2.5 - [#1048](https://github.com/TokTok/c-toxcore/pull/1048) Fix error message in m_send_generic_message - [#1047](https://github.com/TokTok/c-toxcore/pull/1047) Remove unused `m_callback_log` function. - [#1041](https://github.com/TokTok/c-toxcore/pull/1041) Avoid multiple for-next expressions. - [#1037](https://github.com/TokTok/c-toxcore/pull/1037) Run all tests in the Autotools build - [#1035](https://github.com/TokTok/c-toxcore/pull/1035) Fix problems with initial connections and name-setting in conferences - [#1032](https://github.com/TokTok/c-toxcore/pull/1032) Use auto_test fixture in some tests and standardise filenames - [#1030](https://github.com/TokTok/c-toxcore/pull/1030) Make a separate `struct Tox` containing the Messenger. - [#1029](https://github.com/TokTok/c-toxcore/pull/1029) Add `by_id` and `get_id` functions, renaming from `*_uid`. - [#1025](https://github.com/TokTok/c-toxcore/pull/1025) More fixed_width ints and incorporating file_saving_test.c - [#1023](https://github.com/TokTok/c-toxcore/pull/1023) Run buildifier on c-toxcore BUILD files. - [#1022](https://github.com/TokTok/c-toxcore/pull/1022) Make `resize` in `list.c` return bool instead of 0/1. - [#1021](https://github.com/TokTok/c-toxcore/pull/1021) Remove redundant casts to the same type. - [#1020](https://github.com/TokTok/c-toxcore/pull/1020) Add github usernames to TODOs. - [#1019](https://github.com/TokTok/c-toxcore/pull/1019) Synchronise parameter names in headers with those in the implementation. - [#1018](https://github.com/TokTok/c-toxcore/pull/1018) Reduce nesting by doing more early returns on error. - [#1017](https://github.com/TokTok/c-toxcore/pull/1017) Add missing braces in dht_test.c. - [#1011](https://github.com/TokTok/c-toxcore/pull/1011) Run Clang global static analysis on Travis. - [#1010](https://github.com/TokTok/c-toxcore/pull/1010) Avoid implementations in .h files or #including .c files. ### Closed issues: - [#1028](https://github.com/TokTok/c-toxcore/issues/1028) qTox crashes 1-2 times a day after update to 0.2.4 - [#1002](https://github.com/TokTok/c-toxcore/issues/1002) Implement an abstraction over pthread and windows thread synchronisation primitives ## v0.2.4 ### Merged PRs: - [#1024](https://github.com/TokTok/c-toxcore/pull/1024) Release v0.2.4 - [#1014](https://github.com/TokTok/c-toxcore/pull/1014) Use string comparison operator in configure.ac. - [#1013](https://github.com/TokTok/c-toxcore/pull/1013) Link -lsocket and -lnsl for socket functions on Solaris. - [#1012](https://github.com/TokTok/c-toxcore/pull/1012) Correct the max hostname length constant. - [#1009](https://github.com/TokTok/c-toxcore/pull/1009) Using stdint instead of int/long - [#1008](https://github.com/TokTok/c-toxcore/pull/1008) Set `_XOPEN_SOURCE` to 700 for FreeBSD. - [#1007](https://github.com/TokTok/c-toxcore/pull/1007) Use enums for group packet types. - [#1006](https://github.com/TokTok/c-toxcore/pull/1006) Set C++11/C99 flag manually in older cmake on not-msvc. - [#1005](https://github.com/TokTok/c-toxcore/pull/1005) Use the correct repository name in the coverage badge. - [#1003](https://github.com/TokTok/c-toxcore/pull/1003) Remove LOGGER_ERROR for harmless send failure. - [#1001](https://github.com/TokTok/c-toxcore/pull/1001) Add conference_by_uid and conference_get_uid functions. - [#1000](https://github.com/TokTok/c-toxcore/pull/1000) Limit number of group chats to 65536. - [#998](https://github.com/TokTok/c-toxcore/pull/998) Use named function types for group callbacks. - [#997](https://github.com/TokTok/c-toxcore/pull/997) Style fixes in TCP code; remove MIN and PAIR from util.h. - [#996](https://github.com/TokTok/c-toxcore/pull/996) Add the bazel build as one of the PR blocking builds. - [#995](https://github.com/TokTok/c-toxcore/pull/995) Fix style in some header files. - [#994](https://github.com/TokTok/c-toxcore/pull/994) Fix style in DHT.c. - [#993](https://github.com/TokTok/c-toxcore/pull/993) Move `load_state` and its helper functions to their own module. - [#991](https://github.com/TokTok/c-toxcore/pull/991) Use named function types for friend_connection callbacks. - [#990](https://github.com/TokTok/c-toxcore/pull/990) Use named function types for friend_requests callbacks. - [#989](https://github.com/TokTok/c-toxcore/pull/989) Use named function types for callbacks in net_crypto. - [#987](https://github.com/TokTok/c-toxcore/pull/987) Use named types for onion callbacks. - [#986](https://github.com/TokTok/c-toxcore/pull/986) Simplify Travis-CI FreeBSD build - [#985](https://github.com/TokTok/c-toxcore/pull/985) Clarify the intent of "file kinds" in the API. - [#984](https://github.com/TokTok/c-toxcore/pull/984) Avoid side-effectful assignments in conditionals. - [#981](https://github.com/TokTok/c-toxcore/pull/981) Factor out time keeping code into its own module: mono_time.c. - [#979](https://github.com/TokTok/c-toxcore/pull/979) Add a thread-safe version of unix_time and friends. - [#978](https://github.com/TokTok/c-toxcore/pull/978) Rename `BS_LIST` to `BS_List` to follow the naming conventions. - [#977](https://github.com/TokTok/c-toxcore/pull/977) Remove VLA usage from `send_audio_packet`. - [#976](https://github.com/TokTok/c-toxcore/pull/976) Call the "peer leaves" callback only once on group delete. - [#975](https://github.com/TokTok/c-toxcore/pull/975) Factor out the actual test code from conference_test. - [#972](https://github.com/TokTok/c-toxcore/pull/972) Add a test that reproduces the NULL peer nick bug. - [#968](https://github.com/TokTok/c-toxcore/pull/968) Make tox.c unambiguously parseable. - [#967](https://github.com/TokTok/c-toxcore/pull/967) lan_discovery_test and version_test cleanup - [#966](https://github.com/TokTok/c-toxcore/pull/966) Use run_auto_test.h test fixture for some auto-tests. - [#965](https://github.com/TokTok/c-toxcore/pull/965) Add `#include ` for `std::printf`. - [#964](https://github.com/TokTok/c-toxcore/pull/964) Add some tests for our ring_buffer implementation. - [#962](https://github.com/TokTok/c-toxcore/pull/962) Collect `PACKET_ID*` constants in `net_crypto.h`, cleanup their uses - [#958](https://github.com/TokTok/c-toxcore/pull/958) Fix leak of Logger instances in dht_test. - [#957](https://github.com/TokTok/c-toxcore/pull/957) Remove broken conference tests. - [#955](https://github.com/TokTok/c-toxcore/pull/955) Another TCP_test upgrade - [#954](https://github.com/TokTok/c-toxcore/pull/954) Proposal: Make arg `host` understand clearly. - [#953](https://github.com/TokTok/c-toxcore/pull/953) Add missing MAX_HOSTNAME_LENGTH doc. - [#945](https://github.com/TokTok/c-toxcore/pull/945) Add a test to try and overflow the send queue in net_crypto. - [#943](https://github.com/TokTok/c-toxcore/pull/943) Correct check for net_crypto packet index. - [#942](https://github.com/TokTok/c-toxcore/pull/942) Simplify Travis CI builds. - [#932](https://github.com/TokTok/c-toxcore/pull/932) Various minor cleanups in `net_crypto`. ### Closed issues: - [#1015](https://github.com/TokTok/c-toxcore/issues/1015) Improve Solaris support - [#1004](https://github.com/TokTok/c-toxcore/issues/1004) qTox: "Program received signal SIGPIPE, Broken pipe." with TokTok-c-toxcore-v0.2.3_GH0 on FreeBSD 11.x. - [#988](https://github.com/TokTok/c-toxcore/issues/988) Registration on https://nodes.tox.chat (question) - [#982](https://github.com/TokTok/c-toxcore/issues/982) Merge the two travis stages for freebsd back into one - [#970](https://github.com/TokTok/c-toxcore/issues/970) Crash with persistent groups - [#963](https://github.com/TokTok/c-toxcore/issues/963) ToxAV's `rb_write` function is written in a strange way - [#946](https://github.com/TokTok/c-toxcore/issues/946) [API] for max proxy address length - [#944](https://github.com/TokTok/c-toxcore/issues/944) How detect that friend is busy - [#936](https://github.com/TokTok/c-toxcore/issues/936) Help needed in testing a tox client,I need some dummy toxids to test . - [#923](https://github.com/TokTok/c-toxcore/issues/923) Crash on malloc in ping_array_add - [#911](https://github.com/TokTok/c-toxcore/issues/911) Weekly Tox Dev Meeting - [#910](https://github.com/TokTok/c-toxcore/issues/910) Crash in clear_entry in ping_array.c - [#903](https://github.com/TokTok/c-toxcore/issues/903) c-toxcore and LGPL (question) - [#528](https://github.com/TokTok/c-toxcore/issues/528) c-toxcore on Windows can be compiled using MSYS2 (with modern MinGW-w64) - [#472](https://github.com/TokTok/c-toxcore/issues/472) Crash in ping_array.c:35 - [#450](https://github.com/TokTok/c-toxcore/issues/450) Run format-test earlier in the build - [#429](https://github.com/TokTok/c-toxcore/issues/429) Cannot build on Windows using MinGW ## v0.2.3 ### Merged PRs: - [#952](https://github.com/TokTok/c-toxcore/pull/952) Release v0.2.3 - [#951](https://github.com/TokTok/c-toxcore/pull/951) Only run astyle if the astyle binary exists. - [#950](https://github.com/TokTok/c-toxcore/pull/950) Remove utils.c and utils.h from toxencryptsave build. - [#949](https://github.com/TokTok/c-toxcore/pull/949) Fixes to the imported sodium sources to compile without warnings. - [#948](https://github.com/TokTok/c-toxcore/pull/948) Add a MAX_HOSTNAME_LENGTH constant. - [#947](https://github.com/TokTok/c-toxcore/pull/947) Remove the format test. - [#937](https://github.com/TokTok/c-toxcore/pull/937) Add new Circle CI configuration. - [#935](https://github.com/TokTok/c-toxcore/pull/935) Add a test for double conference invite. - [#933](https://github.com/TokTok/c-toxcore/pull/933) Add Logger to various net_crypto functions, and add `const` to Logger where possible. - [#931](https://github.com/TokTok/c-toxcore/pull/931) Avoid conditional-uninitialised warning for tcp test. - [#930](https://github.com/TokTok/c-toxcore/pull/930) Disable UDP when proxy is enabled. - [#928](https://github.com/TokTok/c-toxcore/pull/928) Use clang-format for C++ code. - [#927](https://github.com/TokTok/c-toxcore/pull/927) Add assertions to bootstrap tests for correct connection type. - [#926](https://github.com/TokTok/c-toxcore/pull/926) Make NULL options behave the same as default options. - [#925](https://github.com/TokTok/c-toxcore/pull/925) Add tests for what happens when passing an invalid proxy host. - [#924](https://github.com/TokTok/c-toxcore/pull/924) Make the net_crypto connection state an enum. - [#922](https://github.com/TokTok/c-toxcore/pull/922) Clarify/Improve test_some test - [#921](https://github.com/TokTok/c-toxcore/pull/921) Beginnings of a TCP_test.c overhaul - [#920](https://github.com/TokTok/c-toxcore/pull/920) Add test for creating multiple conferences in one tox. - [#918](https://github.com/TokTok/c-toxcore/pull/918) Merge irungentoo/master into toktok - [#917](https://github.com/TokTok/c-toxcore/pull/917) Add random testing program. - [#916](https://github.com/TokTok/c-toxcore/pull/916) Fix linking with address sanitizer. - [#915](https://github.com/TokTok/c-toxcore/pull/915) Remove resource_leak_test. - [#914](https://github.com/TokTok/c-toxcore/pull/914) Make dht_test more stable. - [#913](https://github.com/TokTok/c-toxcore/pull/913) Minor cleanup: return early on error condition. - [#906](https://github.com/TokTok/c-toxcore/pull/906) Sort bazel build file according to buildifier standard. - [#905](https://github.com/TokTok/c-toxcore/pull/905) In DEBUG mode, make toxcore crash on signed integer overflow. - [#902](https://github.com/TokTok/c-toxcore/pull/902) Log only the filename, not the full path in LOGGER. - [#899](https://github.com/TokTok/c-toxcore/pull/899) Fix macOS macro because of GNU Mach - [#898](https://github.com/TokTok/c-toxcore/pull/898) Fix enumeration of Crypto_Connection instances - [#897](https://github.com/TokTok/c-toxcore/pull/897) Fix ipport_isset: port 0 is not a valid port. - [#894](https://github.com/TokTok/c-toxcore/pull/894) Fix logging related crash in bootstrap node - [#893](https://github.com/TokTok/c-toxcore/pull/893) Fix bootstrap crashes, still - [#892](https://github.com/TokTok/c-toxcore/pull/892) Add empty logger to DHT bootstrap daemons. - [#887](https://github.com/TokTok/c-toxcore/pull/887) Fix FreeBSD build on Travis - [#884](https://github.com/TokTok/c-toxcore/pull/884) Fix the often call of event tox_friend_connection_status - [#883](https://github.com/TokTok/c-toxcore/pull/883) Make toxcore compile on BSD - [#878](https://github.com/TokTok/c-toxcore/pull/878) fix DHT_bootstrap key loading - [#877](https://github.com/TokTok/c-toxcore/pull/877) Add minitox to under "Other resources" section in the README - [#875](https://github.com/TokTok/c-toxcore/pull/875) Make bootstrap daemon use toxcore's version - [#867](https://github.com/TokTok/c-toxcore/pull/867) Improve network error reporting on Windows - [#841](https://github.com/TokTok/c-toxcore/pull/841) Only check full rtp offset if RTP_LARGE_FRAME is set - [#823](https://github.com/TokTok/c-toxcore/pull/823) Finish @Diadlo's network Family abstraction. - [#822](https://github.com/TokTok/c-toxcore/pull/822) Move system header includes from network.h to network.c ### Closed issues: - [#900](https://github.com/TokTok/c-toxcore/issues/900) Log messages include the full build path - [#881](https://github.com/TokTok/c-toxcore/issues/881) Toxcore does not build with cmake on OpenBSD. - [#879](https://github.com/TokTok/c-toxcore/issues/879) DHT_bootstrap asserts due to no default logger - [#868](https://github.com/TokTok/c-toxcore/issues/868) A tox_friend_connection_status event often occurs ## v0.2.2 ### Merged PRs: - [#872](https://github.com/TokTok/c-toxcore/pull/872) Restrict packet kinds that can be sent through onion path. - [#864](https://github.com/TokTok/c-toxcore/pull/864) CMake warn if libconfig not found - [#863](https://github.com/TokTok/c-toxcore/pull/863) Remove broken and unmaintained scripts. - [#862](https://github.com/TokTok/c-toxcore/pull/862) Release v0.2.2 - [#859](https://github.com/TokTok/c-toxcore/pull/859) Add clarifying comment to cryptpacket_received function. - [#857](https://github.com/TokTok/c-toxcore/pull/857) Avoid the use of rand() in tests. - [#852](https://github.com/TokTok/c-toxcore/pull/852) bugfix build error on MacOS - [#846](https://github.com/TokTok/c-toxcore/pull/846) Disallow stderr logger by default. - [#845](https://github.com/TokTok/c-toxcore/pull/845) Fix coveralls reporting. - [#844](https://github.com/TokTok/c-toxcore/pull/844) Add COVERAGE cmake flag for clang. - [#825](https://github.com/TokTok/c-toxcore/pull/825) Add default stderr logger for logging to nullptr. - [#824](https://github.com/TokTok/c-toxcore/pull/824) Simplify sendpacket function, deduplicate some logic. - [#809](https://github.com/TokTok/c-toxcore/pull/809) Remove the use of the 'hh' format specifier. - [#801](https://github.com/TokTok/c-toxcore/pull/801) Add logging to the onion_test. - [#797](https://github.com/TokTok/c-toxcore/pull/797) Move struct DHT_Friend into DHT.c. ### Closed issues: - [#873](https://github.com/TokTok/c-toxcore/issues/873) Onion vulnerability - [#786](https://github.com/TokTok/c-toxcore/issues/786) Make format strings msvc/mingw-happy ## v0.2.1 ### Merged PRs: - [#839](https://github.com/TokTok/c-toxcore/pull/839) Update changelog for 0.2.1 - [#837](https://github.com/TokTok/c-toxcore/pull/837) Update version to 0.2.1. - [#833](https://github.com/TokTok/c-toxcore/pull/833) Add missing tox_nospam_size() function - [#832](https://github.com/TokTok/c-toxcore/pull/832) Don't set RTP_LARGE_FRAME on rtp audio packets - [#831](https://github.com/TokTok/c-toxcore/pull/831) Don't throw away rtp packets from old Toxcore - [#828](https://github.com/TokTok/c-toxcore/pull/828) Make file transfers 50% faster. ## v0.2.0 ### Merged PRs: - [#821](https://github.com/TokTok/c-toxcore/pull/821) Remove deprecated conference namelist change callback. - [#820](https://github.com/TokTok/c-toxcore/pull/820) Fix auto_tests to stop using the deprecated conference API. - [#819](https://github.com/TokTok/c-toxcore/pull/819) Change default username to empty string - [#818](https://github.com/TokTok/c-toxcore/pull/818) Change README to talk about cmake instead of autoreconf. - [#817](https://github.com/TokTok/c-toxcore/pull/817) Fix warning on Mac OS X and FreeBSD. - [#815](https://github.com/TokTok/c-toxcore/pull/815) Some minor cleanups suggested by cppcheck. - [#814](https://github.com/TokTok/c-toxcore/pull/814) Fix memory leak of Logger instance on error paths. - [#813](https://github.com/TokTok/c-toxcore/pull/813) Minor cleanups: dead stores and avoiding complex macros. - [#811](https://github.com/TokTok/c-toxcore/pull/811) Update changelog for 0.2.0 - [#808](https://github.com/TokTok/c-toxcore/pull/808) Fix a bunch of compiler warnings and remove suppressions. - [#807](https://github.com/TokTok/c-toxcore/pull/807) Link all tests to the android cpufeatures library if available. - [#806](https://github.com/TokTok/c-toxcore/pull/806) Fix toxcore.pc generation. - [#805](https://github.com/TokTok/c-toxcore/pull/805) Add an option that allows us to specify that we require toxav. - [#804](https://github.com/TokTok/c-toxcore/pull/804) Fix OSX tests: find(1) doesn't work like on Linux. - [#803](https://github.com/TokTok/c-toxcore/pull/803) Fix the windows build: pthread needs to be linked after vpx. - [#800](https://github.com/TokTok/c-toxcore/pull/800) Make group number in the toxav public API uint32_t - [#799](https://github.com/TokTok/c-toxcore/pull/799) Implement the "persistent conference" callback changes as new functions. - [#798](https://github.com/TokTok/c-toxcore/pull/798) Add deprecation notices to functions that will go away in v0.3.0. - [#796](https://github.com/TokTok/c-toxcore/pull/796) Make some sizeof tests linux-only. - [#794](https://github.com/TokTok/c-toxcore/pull/794) Remove apidsl from the build. - [#793](https://github.com/TokTok/c-toxcore/pull/793) Add a bazel test that ensures all our projects are GPL-3.0. - [#792](https://github.com/TokTok/c-toxcore/pull/792) Increase range of ports available to Toxes during tests - [#791](https://github.com/TokTok/c-toxcore/pull/791) Run all tests in parallel on Travis. - [#790](https://github.com/TokTok/c-toxcore/pull/790) Disable lan discovery in most tests. - [#789](https://github.com/TokTok/c-toxcore/pull/789) Remove tox_test from autotools build. - [#788](https://github.com/TokTok/c-toxcore/pull/788) Don't print trace level logging in tests. - [#787](https://github.com/TokTok/c-toxcore/pull/787) Split up tox_test into multiple smaller tests - [#784](https://github.com/TokTok/c-toxcore/pull/784) Use Wine Devel instead of Wine Staging - [#783](https://github.com/TokTok/c-toxcore/pull/783) Send 0 as peer number in CHANGE_OCCURRED group event. - [#782](https://github.com/TokTok/c-toxcore/pull/782) Use `const` more in C code. - [#781](https://github.com/TokTok/c-toxcore/pull/781) Don't build all the small sub-libraries. - [#780](https://github.com/TokTok/c-toxcore/pull/780) Get rid of the only GNU extension we used. - [#779](https://github.com/TokTok/c-toxcore/pull/779) Remove leftover symmetric key from DHT struct. - [#778](https://github.com/TokTok/c-toxcore/pull/778) Add static asserts for all the struct sizes in toxcore. - [#776](https://github.com/TokTok/c-toxcore/pull/776) Optionally use newer cmake features. - [#775](https://github.com/TokTok/c-toxcore/pull/775) Look for dependencies in third_party/ - [#774](https://github.com/TokTok/c-toxcore/pull/774) Improve gtest finding, support local checkout. - [#773](https://github.com/TokTok/c-toxcore/pull/773) Add gtest include directory to -I flags if found. - [#772](https://github.com/TokTok/c-toxcore/pull/772) Reject discovery packets coming from outside the "LAN". - [#771](https://github.com/TokTok/c-toxcore/pull/771) Adopt the "change occurred" API change from isotoxin-groupchat. - [#770](https://github.com/TokTok/c-toxcore/pull/770) Add MSVC compilation instructions - [#767](https://github.com/TokTok/c-toxcore/pull/767) Build toxcore with libsodium.dll instead of libsodium.lib. - [#766](https://github.com/TokTok/c-toxcore/pull/766) Remove libcheck from the dependencies. - [#765](https://github.com/TokTok/c-toxcore/pull/765) Make outgoing Filetransfers round-robin. - [#764](https://github.com/TokTok/c-toxcore/pull/764) Fix LAN discovery on FreeBSD. - [#761](https://github.com/TokTok/c-toxcore/pull/761) use official debian domain - [#760](https://github.com/TokTok/c-toxcore/pull/760) Make cmake script more forgiving. - [#759](https://github.com/TokTok/c-toxcore/pull/759) Use more ubuntu packages; remove hstox for now. - [#757](https://github.com/TokTok/c-toxcore/pull/757) Improve stability of crypto_memcmp test. - [#756](https://github.com/TokTok/c-toxcore/pull/756) Format .cpp files with format-source. - [#755](https://github.com/TokTok/c-toxcore/pull/755) Add some unit tests for util.h. - [#754](https://github.com/TokTok/c-toxcore/pull/754) Move the tox_sync tool to the toxins repository. - [#753](https://github.com/TokTok/c-toxcore/pull/753) Move irc_syncbot to the toxins repository. - [#752](https://github.com/TokTok/c-toxcore/pull/752) Move tox_shell program to the toxins repository. - [#751](https://github.com/TokTok/c-toxcore/pull/751) Use the markdown GPLv3 license in the c-toxcore repo. - [#750](https://github.com/TokTok/c-toxcore/pull/750) Remove csrc from the RTPHeader struct. - [#748](https://github.com/TokTok/c-toxcore/pull/748) Revert "Add correction message type" - [#745](https://github.com/TokTok/c-toxcore/pull/745) Change the "capabilities" field to a "flags" field. - [#742](https://github.com/TokTok/c-toxcore/pull/742) Improve conference test stability. - [#741](https://github.com/TokTok/c-toxcore/pull/741) Add `-D__STDC_LIMIT_MACROS=1` for C++ code. - [#739](https://github.com/TokTok/c-toxcore/pull/739) Add RTP header fields for the full frame length and offset. - [#737](https://github.com/TokTok/c-toxcore/pull/737) Use nullptr as NULL pointer constant instead of NULL or 0. - [#736](https://github.com/TokTok/c-toxcore/pull/736) Avoid clashes with "build" directories on case-insensitive file systems. - [#734](https://github.com/TokTok/c-toxcore/pull/734) Make audio/video bit rates "properties" - [#733](https://github.com/TokTok/c-toxcore/pull/733) Fix link in README.md - [#730](https://github.com/TokTok/c-toxcore/pull/730) Fix out of bounds read in error case in messenger_test. - [#729](https://github.com/TokTok/c-toxcore/pull/729) Remove dead return statement. - [#728](https://github.com/TokTok/c-toxcore/pull/728) Disable the autotools build in PR builds. - [#727](https://github.com/TokTok/c-toxcore/pull/727) Rename some rtp header struct members to be clearer. - [#725](https://github.com/TokTok/c-toxcore/pull/725) Publish a single public BUILD target for c-toxcore. - [#723](https://github.com/TokTok/c-toxcore/pull/723) Use for alloca on FreeBSD. - [#722](https://github.com/TokTok/c-toxcore/pull/722) Use self-built portaudio instead of system-provided. - [#721](https://github.com/TokTok/c-toxcore/pull/721) Manually serialise RTPHeader struct instead of memcpy. - [#718](https://github.com/TokTok/c-toxcore/pull/718) Improve sending of large video frames in toxav. - [#716](https://github.com/TokTok/c-toxcore/pull/716) Add comment from #629 in ring_buffer.c. - [#714](https://github.com/TokTok/c-toxcore/pull/714) Make BUILD files more finely-grained. - [#713](https://github.com/TokTok/c-toxcore/pull/713) Add BUILD files for all the little tools in the repo. - [#712](https://github.com/TokTok/c-toxcore/pull/712) Fix high quality video sending (backport to 0.1.x). - [#711](https://github.com/TokTok/c-toxcore/pull/711) Make the monolith test a C++ binary. - [#710](https://github.com/TokTok/c-toxcore/pull/710) Don't allocate or dereference Tox_Options in tests. - [#709](https://github.com/TokTok/c-toxcore/pull/709) Remove nTox from the repo. - [#708](https://github.com/TokTok/c-toxcore/pull/708) Add testing/*.c (except av_test) to bazel build. - [#707](https://github.com/TokTok/c-toxcore/pull/707) Fix log message in simple_conference_test: invite -> message. - [#705](https://github.com/TokTok/c-toxcore/pull/705) Add correction support for conference - [#703](https://github.com/TokTok/c-toxcore/pull/703) Add a simple conference test with 3 friends. - [#702](https://github.com/TokTok/c-toxcore/pull/702) Update to astyle 2.04 on CircleCI to get the correct result - [#701](https://github.com/TokTok/c-toxcore/pull/701) Add astyle to Circle CI build. - [#700](https://github.com/TokTok/c-toxcore/pull/700) Use more descriptive names in bwcontroller. - [#699](https://github.com/TokTok/c-toxcore/pull/699) Add some explanatory comments to the toxav audio code. - [#698](https://github.com/TokTok/c-toxcore/pull/698) Extract named constants from magic numbers in toxav/audio.c. - [#697](https://github.com/TokTok/c-toxcore/pull/697) Use C99 standard in bazel builds. - [#694](https://github.com/TokTok/c-toxcore/pull/694) Add bazel build scripts for c-toxcore. - [#693](https://github.com/TokTok/c-toxcore/pull/693) Make libcheck optional for windows builds. - [#691](https://github.com/TokTok/c-toxcore/pull/691) Don't install packages needlessly on Travis - [#690](https://github.com/TokTok/c-toxcore/pull/690) Run fewer Travis jobs during Pull Requests. - [#689](https://github.com/TokTok/c-toxcore/pull/689) Make Net_Crypto a module-private type. - [#688](https://github.com/TokTok/c-toxcore/pull/688) Make DHT a module-private type. - [#687](https://github.com/TokTok/c-toxcore/pull/687) Use apidsl to generate LAN_discovery.h. - [#686](https://github.com/TokTok/c-toxcore/pull/686) Remove hstox test for now. - [#685](https://github.com/TokTok/c-toxcore/pull/685) Add message type for correction - [#684](https://github.com/TokTok/c-toxcore/pull/684) Add random_u16 function and rename the others to match. - [#682](https://github.com/TokTok/c-toxcore/pull/682) Use larger arrays in crypto timing tests. - [#681](https://github.com/TokTok/c-toxcore/pull/681) Fix some memory or file descriptor leaks in test code. - [#680](https://github.com/TokTok/c-toxcore/pull/680) Filter out annoying log statements in unit tests. - [#679](https://github.com/TokTok/c-toxcore/pull/679) Use apidsl to generate ping.h. - [#678](https://github.com/TokTok/c-toxcore/pull/678) Sort monolith.h according to ls(1): uppercase first. - [#677](https://github.com/TokTok/c-toxcore/pull/677) Make pack/unpack_ip_port public DHT functions. - [#675](https://github.com/TokTok/c-toxcore/pull/675) Make Onion_Announce a module-private type. - [#674](https://github.com/TokTok/c-toxcore/pull/674) Make TCP_Client_Connection a module-private type. - [#673](https://github.com/TokTok/c-toxcore/pull/673) Move TCP_Secure_Connection from .h to .c file. - [#672](https://github.com/TokTok/c-toxcore/pull/672) Make Friend_Connections a module-private type. - [#670](https://github.com/TokTok/c-toxcore/pull/670) Make Friend_Requests a module-private type. - [#669](https://github.com/TokTok/c-toxcore/pull/669) Make Onion_Client a module-private type. - [#668](https://github.com/TokTok/c-toxcore/pull/668) Make Ping_Array a module-private type. - [#667](https://github.com/TokTok/c-toxcore/pull/667) pkg-config .pc files: added .private versions of Libs and Required - [#666](https://github.com/TokTok/c-toxcore/pull/666) Fix some typos in code and cmake comments - [#665](https://github.com/TokTok/c-toxcore/pull/665) Remove useless if statement - [#662](https://github.com/TokTok/c-toxcore/pull/662) Move Networking_Core struct into the .c file. - [#661](https://github.com/TokTok/c-toxcore/pull/661) Disable asan, since it seems to break on travis. - [#660](https://github.com/TokTok/c-toxcore/pull/660) Increase test retries to 10 (basically infinite). - [#659](https://github.com/TokTok/c-toxcore/pull/659) Fix formatting in some C files. - [#658](https://github.com/TokTok/c-toxcore/pull/658) Call freeaddrinfo on error paths in net_getipport. - [#657](https://github.com/TokTok/c-toxcore/pull/657) Zero-initialise stack-allocated objects in hstox driver. - [#656](https://github.com/TokTok/c-toxcore/pull/656) Fix file descriptor leak in hstox test. - [#654](https://github.com/TokTok/c-toxcore/pull/654) Bump toxcore version to 0.2.0. - [#652](https://github.com/TokTok/c-toxcore/pull/652) Add support for building the monolith test on android. - [#650](https://github.com/TokTok/c-toxcore/pull/650) Remove deprecated ToxDNS - [#648](https://github.com/TokTok/c-toxcore/pull/648) Make hstox compile on FreeBSD - [#624](https://github.com/TokTok/c-toxcore/pull/624) Update rpm spec and use variables in cmake instead of hardcoded paths - [#616](https://github.com/TokTok/c-toxcore/pull/616) Add projects link to Readme. - [#613](https://github.com/TokTok/c-toxcore/pull/613) Fix travis - [#605](https://github.com/TokTok/c-toxcore/pull/605) Fix OS X Travis. - [#598](https://github.com/TokTok/c-toxcore/pull/598) Fix typos in docs - [#578](https://github.com/TokTok/c-toxcore/pull/578) Split toxav_bit_rate_set() into two functions to hold the maximum bitrates libvpx supports - [#477](https://github.com/TokTok/c-toxcore/pull/477) Update install instructions to use CMake - [#465](https://github.com/TokTok/c-toxcore/pull/465) Add Alpine linux Dockerfile in addition to the existing Debian one - [#442](https://github.com/TokTok/c-toxcore/pull/442) Generate only one large library "libtoxcore". - [#334](https://github.com/TokTok/c-toxcore/pull/334) Change toxencryptsave API to never overwrite pass keys. ### Closed issues: - [#810](https://github.com/TokTok/c-toxcore/issues/810) Release 0.2.0 - [#704](https://github.com/TokTok/c-toxcore/issues/704) Add CORRECTION support to group chats - [#620](https://github.com/TokTok/c-toxcore/issues/620) Video bug: large video frames are not sent correctly - [#606](https://github.com/TokTok/c-toxcore/issues/606) groupId is int whereas friendId is uint32_t, reason? - [#599](https://github.com/TokTok/c-toxcore/issues/599) Error when linking against libtoxcore: undefined reference to symbol 'crypto_hash_sha256' - [#572](https://github.com/TokTok/c-toxcore/issues/572) int32_t may be not large enough as a argument for video_bit_rate of vp8/9 codec - [#566](https://github.com/TokTok/c-toxcore/issues/566) LAYER #: modules for static linking - build issue - [#383](https://github.com/TokTok/c-toxcore/issues/383) TODO: add cmake instructions in README.md - [#42](https://github.com/TokTok/c-toxcore/issues/42) Remove ToxDNS and related stuff from toxcore ## v0.1.11 ### Merged PRs: - [#643](https://github.com/TokTok/c-toxcore/pull/643) Add .editorconfig - [#638](https://github.com/TokTok/c-toxcore/pull/638) Release v0.1.11 - [#637](https://github.com/TokTok/c-toxcore/pull/637) Update tox-bootstrapd Dockerfile - [#635](https://github.com/TokTok/c-toxcore/pull/635) Separate FreeBSD Travis build in 2 stages - [#632](https://github.com/TokTok/c-toxcore/pull/632) Lift libconfig to v1.7.1 - [#631](https://github.com/TokTok/c-toxcore/pull/631) Add aspcud for Opam - [#630](https://github.com/TokTok/c-toxcore/pull/630) Fix for Travis fail on addr_resolve testing - [#623](https://github.com/TokTok/c-toxcore/pull/623) Split video payload into multiple RTP messages when too big to fit into one - [#615](https://github.com/TokTok/c-toxcore/pull/615) forget DHT pubkey of offline friend after DHT timeout - [#611](https://github.com/TokTok/c-toxcore/pull/611) Fix typo - [#607](https://github.com/TokTok/c-toxcore/pull/607) set onion pingid timeout to announce timeout (300s) - [#592](https://github.com/TokTok/c-toxcore/pull/592) Adjust docs of few toxencrypt function to the code - [#587](https://github.com/TokTok/c-toxcore/pull/587) Fix tox test - [#586](https://github.com/TokTok/c-toxcore/pull/586) Improve LAN discovery - [#576](https://github.com/TokTok/c-toxcore/pull/576) Replace include(CTest) on enable_testing() - [#574](https://github.com/TokTok/c-toxcore/pull/574) Reset hole-punching parameters after not punching for a while - [#571](https://github.com/TokTok/c-toxcore/pull/571) Configure needs to find libsodium headers. - [#515](https://github.com/TokTok/c-toxcore/pull/515) Network cleanup: reduce dependency on system-defined constants - [#505](https://github.com/TokTok/c-toxcore/pull/505) Add FreeBSD Travis - [#500](https://github.com/TokTok/c-toxcore/pull/500) Fixed the bug when receipts for messages sent from the receipt callback never arrived. ### Closed issues: - [#493](https://github.com/TokTok/c-toxcore/issues/493) Receipts for messages sent from the receipt callback never arrive - [#240](https://github.com/TokTok/c-toxcore/issues/240) Tox doesn't reconnect after internet connection interruption - [#237](https://github.com/TokTok/c-toxcore/issues/237) Contacts are shown offline when they are online ## v0.1.10 ### Merged PRs: - [#575](https://github.com/TokTok/c-toxcore/pull/575) Release v0.1.10 - [#564](https://github.com/TokTok/c-toxcore/pull/564) Fix Windows build - [#542](https://github.com/TokTok/c-toxcore/pull/542) Save bandwidth by moderating onion pinging ## v0.1.9 ### Merged PRs: - [#563](https://github.com/TokTok/c-toxcore/pull/563) Release v0.1.9 - [#561](https://github.com/TokTok/c-toxcore/pull/561) Remove unused variable - [#560](https://github.com/TokTok/c-toxcore/pull/560) Fix non-portable zeroing out of doubles - [#559](https://github.com/TokTok/c-toxcore/pull/559) Fix theoretical memory leaks - [#557](https://github.com/TokTok/c-toxcore/pull/557) Document inverted mutex lock/unlock. - [#556](https://github.com/TokTok/c-toxcore/pull/556) Build tests on appveyor, the MSVC build, but don't run them yet. - [#555](https://github.com/TokTok/c-toxcore/pull/555) Fold hstox tests into the general linux test. - [#554](https://github.com/TokTok/c-toxcore/pull/554) Add a monolith_test that includes all toxcore sources. - [#553](https://github.com/TokTok/c-toxcore/pull/553) Factor out strict_abi cmake code into a separate module. - [#552](https://github.com/TokTok/c-toxcore/pull/552) Fix formatting and spelling in version-sync script. - [#551](https://github.com/TokTok/c-toxcore/pull/551) Forbid undefined symbols in shared libraries. - [#546](https://github.com/TokTok/c-toxcore/pull/546) Make variable names in file saving test less cryptic - [#539](https://github.com/TokTok/c-toxcore/pull/539) Make OSX test failures fail the Travis CI build. - [#537](https://github.com/TokTok/c-toxcore/pull/537) Fix TokTok/c-toxcore#535 - [#534](https://github.com/TokTok/c-toxcore/pull/534) Fix markdown formatting - [#530](https://github.com/TokTok/c-toxcore/pull/530) Implement missing TES constant functions. - [#511](https://github.com/TokTok/c-toxcore/pull/511) Save bandwidth by avoiding superfluous Nodes Requests to peers already on the Close List - [#506](https://github.com/TokTok/c-toxcore/pull/506) Add test case for title change - [#498](https://github.com/TokTok/c-toxcore/pull/498) DHT refactoring - [#487](https://github.com/TokTok/c-toxcore/pull/487) Split daemon's logging backends in separate modules - [#468](https://github.com/TokTok/c-toxcore/pull/468) Test for memberlist not changing after changing own name - [#449](https://github.com/TokTok/c-toxcore/pull/449) Use new encoding of `Maybe` in msgpack results. ### Closed issues: - [#482](https://github.com/TokTok/c-toxcore/issues/482) CMake can't detect and compile ToxAV on OSX ## v0.1.8 ### Merged PRs: - [#538](https://github.com/TokTok/c-toxcore/pull/538) Reverting tox_loop PR changes - [#536](https://github.com/TokTok/c-toxcore/pull/536) Release v0.1.8 - [#526](https://github.com/TokTok/c-toxcore/pull/526) Add TOX_NOSPAM_SIZE to the public API. - [#525](https://github.com/TokTok/c-toxcore/pull/525) Retry autotools tests the same way as cmake tests. - [#524](https://github.com/TokTok/c-toxcore/pull/524) Reduce ctest timeout to 2 minutes from 5 minutes. - [#512](https://github.com/TokTok/c-toxcore/pull/512) Add test for DHT pack_nodes and unpack_nodes - [#504](https://github.com/TokTok/c-toxcore/pull/504) CMake: install bootstrapd if it is built - [#488](https://github.com/TokTok/c-toxcore/pull/488) Save compiled Android artifacts after CircleCI builds. - [#473](https://github.com/TokTok/c-toxcore/pull/473) Added missing includes: and - [#335](https://github.com/TokTok/c-toxcore/pull/335) Implement tox_loop ### Closed issues: - [#535](https://github.com/TokTok/c-toxcore/issues/535) OS X tests failing - [#503](https://github.com/TokTok/c-toxcore/issues/503) Undefined functions: tox_pass_salt_length, tox_pass_key_length, tox_pass_encryption_extra_length - [#456](https://github.com/TokTok/c-toxcore/issues/456) Tox.h doesn't expose the size of the nospam. - [#411](https://github.com/TokTok/c-toxcore/issues/411) Reduce CTest timeout to 2 minutes ## v0.1.7 ### Merged PRs: - [#523](https://github.com/TokTok/c-toxcore/pull/523) Release v0.1.7 - [#521](https://github.com/TokTok/c-toxcore/pull/521) Fix appveyor script: install curl from chocolatey. - [#510](https://github.com/TokTok/c-toxcore/pull/510) Fix list malloc(0) bug - [#509](https://github.com/TokTok/c-toxcore/pull/509) Fix network malloc(0) bug - [#497](https://github.com/TokTok/c-toxcore/pull/497) Fix network - [#496](https://github.com/TokTok/c-toxcore/pull/496) Fix Travis always succeeding despite tests failing - [#491](https://github.com/TokTok/c-toxcore/pull/491) Add crypto_memzero for temp buffer - [#490](https://github.com/TokTok/c-toxcore/pull/490) Move c_sleep to helpers.h and misc_tools.h - [#486](https://github.com/TokTok/c-toxcore/pull/486) Remove empty line in Messenger.c - [#483](https://github.com/TokTok/c-toxcore/pull/483) Make BUILD_TOXAV an option and fail if dependencies are missing - [#481](https://github.com/TokTok/c-toxcore/pull/481) Remove dependency on strings.h - [#480](https://github.com/TokTok/c-toxcore/pull/480) Use VLA macro - [#479](https://github.com/TokTok/c-toxcore/pull/479) Fix pthreads in AppVeyor build - [#471](https://github.com/TokTok/c-toxcore/pull/471) Remove statics used in onion comparison functions. - [#461](https://github.com/TokTok/c-toxcore/pull/461) Replace part of network functions on platform-independent implementation - [#452](https://github.com/TokTok/c-toxcore/pull/452) Add VLA compatibility macro for C89-ish compilers. ### Closed issues: - [#495](https://github.com/TokTok/c-toxcore/issues/495) Fix heap buffer overflow introduced by #461 - [#494](https://github.com/TokTok/c-toxcore/issues/494) Format networking code introduced by #461 - [#474](https://github.com/TokTok/c-toxcore/issues/474) TOX_VERSION_PATCH isn't in sync with the version ## v0.1.6 ### Merged PRs: - [#460](https://github.com/TokTok/c-toxcore/pull/460) Release v0.1.6. - [#459](https://github.com/TokTok/c-toxcore/pull/459) Add Android build to CI. - [#454](https://github.com/TokTok/c-toxcore/pull/454) Add appveyor build for native windows tests. - [#448](https://github.com/TokTok/c-toxcore/pull/448) Only retry failed tests on Circle CI instead of all. - [#434](https://github.com/TokTok/c-toxcore/pull/434) Replace redundant packet type check in handler with assert. - [#432](https://github.com/TokTok/c-toxcore/pull/432) Remove some static variables - [#385](https://github.com/TokTok/c-toxcore/pull/385) Add platform-independent Socket and IP implementation ### Closed issues: - [#457](https://github.com/TokTok/c-toxcore/issues/457) EPOLLRDHUP not defined in android ndk on lower API that 21 - [#415](https://github.com/TokTok/c-toxcore/issues/415) Set up a native windows build on appveyor ## v0.1.5 ### Merged PRs: - [#447](https://github.com/TokTok/c-toxcore/pull/447) Release v0.1.5. - [#446](https://github.com/TokTok/c-toxcore/pull/446) Limit number of retries to 3. - [#445](https://github.com/TokTok/c-toxcore/pull/445) Make Travis tests slightly more robust by re-running them. - [#443](https://github.com/TokTok/c-toxcore/pull/443) Make building `DHT_bootstrap` in cmake optional. - [#433](https://github.com/TokTok/c-toxcore/pull/433) Add tutorial and "danger: experimental" banner to README. - [#431](https://github.com/TokTok/c-toxcore/pull/431) Update license headers and remove redundant file name comment. - [#424](https://github.com/TokTok/c-toxcore/pull/424) Fixed the FreeBSD build failure due to the undefined MSG_NOSIGNAL. - [#420](https://github.com/TokTok/c-toxcore/pull/420) Setup autotools to read .so version info from a separate file - [#418](https://github.com/TokTok/c-toxcore/pull/418) Clarify how the autotools build is done on Travis. - [#414](https://github.com/TokTok/c-toxcore/pull/414) Explicitly check if compiler supports C99 ### Closed issues: - [#413](https://github.com/TokTok/c-toxcore/issues/413) Support C compilation with `-std=c99` in autotools ## v0.1.4 ### Merged PRs: - [#422](https://github.com/TokTok/c-toxcore/pull/422) Release v0.1.4. - [#410](https://github.com/TokTok/c-toxcore/pull/410) Fix NaCl build: tar was called incorrectly. - [#409](https://github.com/TokTok/c-toxcore/pull/409) Clarify that the pass key `new` function can fail. - [#407](https://github.com/TokTok/c-toxcore/pull/407) Don't use `git.depth=1` anymore. - [#404](https://github.com/TokTok/c-toxcore/pull/404) Issue 404: semicolon not found - [#403](https://github.com/TokTok/c-toxcore/pull/403) Warn on -pedantic, don't error yet. - [#401](https://github.com/TokTok/c-toxcore/pull/401) Add logging callback to messenger_test. - [#400](https://github.com/TokTok/c-toxcore/pull/400) Run windows tests but ignore their failures. - [#398](https://github.com/TokTok/c-toxcore/pull/398) Portability Fixes - [#397](https://github.com/TokTok/c-toxcore/pull/397) Replace make_quick_sort with qsort - [#396](https://github.com/TokTok/c-toxcore/pull/396) Add an OSX build that doesn't run tests. - [#394](https://github.com/TokTok/c-toxcore/pull/394) CMake: Add soversion to library files to generate proper symlinks - [#393](https://github.com/TokTok/c-toxcore/pull/393) Set up autotools build to build against vanilla NaCl. - [#392](https://github.com/TokTok/c-toxcore/pull/392) Check that TCP connections aren't dropped in callbacks. - [#391](https://github.com/TokTok/c-toxcore/pull/391) Minor simplification in `file_seek` code. - [#390](https://github.com/TokTok/c-toxcore/pull/390) Always kill invalid file transfers when receiving file controls. - [#388](https://github.com/TokTok/c-toxcore/pull/388) Fix logging condition for IPv6 client timestamp updates. - [#387](https://github.com/TokTok/c-toxcore/pull/387) Eliminate dead return statement. - [#386](https://github.com/TokTok/c-toxcore/pull/386) Avoid accessing uninitialised memory in `net_crypto`. - [#381](https://github.com/TokTok/c-toxcore/pull/381) Remove `TOX_DEBUG` and have asserts always enabled. ### Closed issues: - [#378](https://github.com/TokTok/c-toxcore/issues/378) Replace all uses of `make_quick_sort` with `qsort` - [#364](https://github.com/TokTok/c-toxcore/issues/364) Delete misc_tools.h after replacing its use by qsort. - [#363](https://github.com/TokTok/c-toxcore/issues/363) Test against NaCl in addition to libsodium on Travis. ## v0.1.3 ### Merged PRs: - [#395](https://github.com/TokTok/c-toxcore/pull/395) Revert "Portability fixes" - [#380](https://github.com/TokTok/c-toxcore/pull/380) Test a few cmake option combinations before the build. - [#377](https://github.com/TokTok/c-toxcore/pull/377) Fix SSL verification in coveralls. - [#376](https://github.com/TokTok/c-toxcore/pull/376) Bring back autotools instructions - [#373](https://github.com/TokTok/c-toxcore/pull/373) Only fetch 1 revision from git during Travis builds. - [#369](https://github.com/TokTok/c-toxcore/pull/369) Integrate with CircleCI to build artifacts in the future - [#366](https://github.com/TokTok/c-toxcore/pull/366) Release v0.1.3. - [#362](https://github.com/TokTok/c-toxcore/pull/362) Remove .cabal-sandbox option from tox-spectest find line. - [#361](https://github.com/TokTok/c-toxcore/pull/361) Simplify integration as a third-party lib in cmake projects - [#354](https://github.com/TokTok/c-toxcore/pull/354) Add secure memcmp and memzero implementation. - [#324](https://github.com/TokTok/c-toxcore/pull/324) Do not compile and install DHT_bootstrap if it was disabled in configure - [#297](https://github.com/TokTok/c-toxcore/pull/297) Portability fixes ### Closed issues: - [#347](https://github.com/TokTok/c-toxcore/issues/347) Implement our own secure `memcmp` and `memzero` if libsodium isn't available - [#319](https://github.com/TokTok/c-toxcore/issues/319) toxcore installs `DHT_bootstrap` even though `--disable-daemon` is passed to `./configure` ## v0.1.2 ### Merged PRs: - [#355](https://github.com/TokTok/c-toxcore/pull/355) Release v0.1.2 - [#353](https://github.com/TokTok/c-toxcore/pull/353) Fix toxav use after free caused by premature MSI destruction - [#346](https://github.com/TokTok/c-toxcore/pull/346) Avoid array out of bounds read in friend saving. - [#344](https://github.com/TokTok/c-toxcore/pull/344) Remove unused get/set salt/key functions from toxencryptsave. - [#343](https://github.com/TokTok/c-toxcore/pull/343) Wrap all sodium/nacl functions in crypto_core.c. - [#341](https://github.com/TokTok/c-toxcore/pull/341) Add test to check if tox_new/tox_kill leaks. - [#336](https://github.com/TokTok/c-toxcore/pull/336) Correct TES docs to reflect how many bytes functions actually require. - [#333](https://github.com/TokTok/c-toxcore/pull/333) Use `tox_options_set_*` instead of direct member access. ### Closed issues: - [#345](https://github.com/TokTok/c-toxcore/issues/345) Array out of bounds read in "save" function - [#342](https://github.com/TokTok/c-toxcore/issues/342) Wrap all libsodium functions we use in toxcore in `crypto_core`. - [#278](https://github.com/TokTok/c-toxcore/issues/278) ToxAV use-after-free bug ## v0.1.1 ### Merged PRs: - [#337](https://github.com/TokTok/c-toxcore/pull/337) Release v0.1.1 - [#332](https://github.com/TokTok/c-toxcore/pull/332) Add test for encrypted savedata. - [#330](https://github.com/TokTok/c-toxcore/pull/330) Strengthen the note about ABI compatibility in tox.h. - [#328](https://github.com/TokTok/c-toxcore/pull/328) Drop the broken `TOX_VERSION_REQUIRE` macro. - [#326](https://github.com/TokTok/c-toxcore/pull/326) Fix unresolved reference in toxencryptsave API docs. - [#309](https://github.com/TokTok/c-toxcore/pull/309) Fixed attempt to join detached threads (fixes toxav test crash) - [#306](https://github.com/TokTok/c-toxcore/pull/306) Add option to disable local peer discovery ### Closed issues: - [#327](https://github.com/TokTok/c-toxcore/issues/327) The `TOX_VERSION_REQUIRE` macro is broken. - [#221](https://github.com/TokTok/c-toxcore/issues/221) Option to disable local peer detection ## v0.1.0 ### Merged PRs: - [#325](https://github.com/TokTok/c-toxcore/pull/325) Fix Libs line in toxcore.pc pkg-config file. - [#322](https://github.com/TokTok/c-toxcore/pull/322) Add compatibility pkg-config modules: libtoxcore, libtoxav. - [#318](https://github.com/TokTok/c-toxcore/pull/318) Fix `--enable-logging` flag in autotools configure script. - [#316](https://github.com/TokTok/c-toxcore/pull/316) Release 0.1.0. - [#315](https://github.com/TokTok/c-toxcore/pull/315) Fix version compatibility test. - [#314](https://github.com/TokTok/c-toxcore/pull/314) Fix off by one error in saving our own status message. - [#313](https://github.com/TokTok/c-toxcore/pull/313) Fix padding being in the wrong place in `SAVED_FRIEND` struct - [#312](https://github.com/TokTok/c-toxcore/pull/312) Conditionally enable non-portable assert on LP64. - [#310](https://github.com/TokTok/c-toxcore/pull/310) Add apidsl file for toxencryptsave. - [#307](https://github.com/TokTok/c-toxcore/pull/307) Clarify toxencryptsave documentation regarding buffer sizes - [#305](https://github.com/TokTok/c-toxcore/pull/305) Fix static builds - [#303](https://github.com/TokTok/c-toxcore/pull/303) Don't build nTox by default. - [#301](https://github.com/TokTok/c-toxcore/pull/301) Renamed messenger functions, prepend `m_`. - [#299](https://github.com/TokTok/c-toxcore/pull/299) net_crypto give handle_data_packet_helper a better name - [#294](https://github.com/TokTok/c-toxcore/pull/294) Don't error on warnings by default ### Closed issues: - [#317](https://github.com/TokTok/c-toxcore/issues/317) toxcore fails to build with autotools and debugging level enabled - [#311](https://github.com/TokTok/c-toxcore/issues/311) Incorrect padding - [#308](https://github.com/TokTok/c-toxcore/issues/308) Review TES and port it to APIDSL - [#293](https://github.com/TokTok/c-toxcore/issues/293) error building on ubuntu 14.04 - [#292](https://github.com/TokTok/c-toxcore/issues/292) Don't build nTox by default with CMake - [#290](https://github.com/TokTok/c-toxcore/issues/290) User Feed - [#266](https://github.com/TokTok/c-toxcore/issues/266) Support all levels listed in TOX_DHT_NAT_LEVEL - [#216](https://github.com/TokTok/c-toxcore/issues/216) When v0.1 release? ## v0.0.5 ### Merged PRs: - [#289](https://github.com/TokTok/c-toxcore/pull/289) Version Patch v0.0.4 => v0.0.5 - [#287](https://github.com/TokTok/c-toxcore/pull/287) Add CMake knobs to suppress building tests - [#286](https://github.com/TokTok/c-toxcore/pull/286) Support float32 and float64 in msgpack type printer. - [#285](https://github.com/TokTok/c-toxcore/pull/285) Mark `Tox_Options` struct as deprecated. - [#284](https://github.com/TokTok/c-toxcore/pull/284) Add NONE enumerator to bit mask. - [#281](https://github.com/TokTok/c-toxcore/pull/281) Made save format platform-independent - [#277](https://github.com/TokTok/c-toxcore/pull/277) Fix a memory leak in hstox interface - [#276](https://github.com/TokTok/c-toxcore/pull/276) Fix NULL pointer dereference in log calls - [#275](https://github.com/TokTok/c-toxcore/pull/275) Fix a memory leak in GroupAV - [#274](https://github.com/TokTok/c-toxcore/pull/274) Options in `new_messenger()` must never be null. - [#271](https://github.com/TokTok/c-toxcore/pull/271) Convert to and from network byte order in set/get nospam. - [#262](https://github.com/TokTok/c-toxcore/pull/262) Add ability to disable UDP hole punching ### Closed issues: - [#254](https://github.com/TokTok/c-toxcore/issues/254) Add option to disable UDP hole punching - [#215](https://github.com/TokTok/c-toxcore/issues/215) The current tox save format is non-portable - [#205](https://github.com/TokTok/c-toxcore/issues/205) nospam value is reversed in array returned by `tox_self_get_address()` ## v0.0.4 ### Merged PRs: - [#272](https://github.com/TokTok/c-toxcore/pull/272) v0.0.4 - [#265](https://github.com/TokTok/c-toxcore/pull/265) Disable -Wunused-but-set-variable compiler warning flag. - [#261](https://github.com/TokTok/c-toxcore/pull/261) Work around Travis issue that causes build failures. - [#260](https://github.com/TokTok/c-toxcore/pull/260) Support arbitrary video resolutions in av_test - [#257](https://github.com/TokTok/c-toxcore/pull/257) Add decode/encode PlainText test support. - [#256](https://github.com/TokTok/c-toxcore/pull/256) Add spectest to the cmake test suite. - [#255](https://github.com/TokTok/c-toxcore/pull/255) Disable some gcc-specific warnings. - [#249](https://github.com/TokTok/c-toxcore/pull/249) Use apidsl for the crypto_core API. - [#248](https://github.com/TokTok/c-toxcore/pull/248) Remove new_nonce function in favour of random_nonce. - [#224](https://github.com/TokTok/c-toxcore/pull/224) Add DHT_create_packet, an abstraction for DHT RPC packets ## v0.0.3 ### Merged PRs: - [#251](https://github.com/TokTok/c-toxcore/pull/251) Rename log levels to remove the extra "LOG" prefix. - [#250](https://github.com/TokTok/c-toxcore/pull/250) Release v0.0.3. - [#245](https://github.com/TokTok/c-toxcore/pull/245) Change packet kind enum to use hex constants. - [#243](https://github.com/TokTok/c-toxcore/pull/243) Enable address sanitizer on the cmake build. - [#242](https://github.com/TokTok/c-toxcore/pull/242) Remove assoc - [#241](https://github.com/TokTok/c-toxcore/pull/241) Move log callback to options. - [#233](https://github.com/TokTok/c-toxcore/pull/233) Enable all possible C compiler warning flags. - [#230](https://github.com/TokTok/c-toxcore/pull/230) Move packing and unpacking DHT request packets to DHT module. - [#228](https://github.com/TokTok/c-toxcore/pull/228) Remove unimplemented "time delta" parameter. - [#227](https://github.com/TokTok/c-toxcore/pull/227) Compile as C++ for windows builds. - [#223](https://github.com/TokTok/c-toxcore/pull/223) TravisCI shorten IRC message - [#220](https://github.com/TokTok/c-toxcore/pull/220) toxav renaming: group.{h,c} -> groupav.{h,c} - [#218](https://github.com/TokTok/c-toxcore/pull/218) Rename some internal "group chat" thing to "conference". - [#212](https://github.com/TokTok/c-toxcore/pull/212) Convert series of `NET_PACKET_*` defines into a typedef enum - [#196](https://github.com/TokTok/c-toxcore/pull/196) Update readme, moved the roadmap to a higher position - [#193](https://github.com/TokTok/c-toxcore/pull/193) Remove duplicate tests: split tests part 2. ### Closed issues: - [#40](https://github.com/TokTok/c-toxcore/issues/40) Stateless callbacks in toxcore's public API ## v0.0.2 ### Merged PRs: - [#207](https://github.com/TokTok/c-toxcore/pull/207) docs: correct instructions for cloning & harden against repo name changes - [#206](https://github.com/TokTok/c-toxcore/pull/206) Corrected libsodium tag - [#204](https://github.com/TokTok/c-toxcore/pull/204) Error if format_test can't be executed. - [#202](https://github.com/TokTok/c-toxcore/pull/202) Version Patch v0.0.2 - [#190](https://github.com/TokTok/c-toxcore/pull/190) Install libraries with RPATH. - [#189](https://github.com/TokTok/c-toxcore/pull/189) Use `socklen_t` instead of `unsigned int` in call to `accept`. - [#188](https://github.com/TokTok/c-toxcore/pull/188) Add option to set test timeout - [#187](https://github.com/TokTok/c-toxcore/pull/187) Add option to build tox-bootstrapd - [#185](https://github.com/TokTok/c-toxcore/pull/185) Import the hstox SUT interface from hstox. - [#183](https://github.com/TokTok/c-toxcore/pull/183) Set log level for DEBUG=ON to LOG_DEBUG. - [#182](https://github.com/TokTok/c-toxcore/pull/182) Remove return after no-return situation. - [#181](https://github.com/TokTok/c-toxcore/pull/181) Minor documentation fixes. - [#180](https://github.com/TokTok/c-toxcore/pull/180) Add the 'Tox' context object to the logger. - [#179](https://github.com/TokTok/c-toxcore/pull/179) Remove the `_test` suffix in `auto_test` calls. - [#178](https://github.com/TokTok/c-toxcore/pull/178) Rebuild apidsl'd headers in cmake. - [#177](https://github.com/TokTok/c-toxcore/pull/177) docs(INSTALL): update compiling instructions for Linux - [#176](https://github.com/TokTok/c-toxcore/pull/176) Merge irungentoo/toxcore into TokTok/c-toxcore. - [#173](https://github.com/TokTok/c-toxcore/pull/173) Duplicate tox_test to 4 other files. ### Closed issues: - [#201](https://github.com/TokTok/c-toxcore/issues/201) Logging callback was broken ## v0.0.1 ### Merged PRs: - [#174](https://github.com/TokTok/c-toxcore/pull/174) Remove redundant callback objects. - [#171](https://github.com/TokTok/c-toxcore/pull/171) Simple Version tick to v0.0.1 - [#170](https://github.com/TokTok/c-toxcore/pull/170) C++ the second round. - [#166](https://github.com/TokTok/c-toxcore/pull/166) Add version-sync script. - [#164](https://github.com/TokTok/c-toxcore/pull/164) Replace `void*` with `RingBuffer*` to avoid conversions. - [#163](https://github.com/TokTok/c-toxcore/pull/163) Move ring buffer out of toxcore/util into toxav. - [#162](https://github.com/TokTok/c-toxcore/pull/162) Allow the OSX build to fail on travis. - [#161](https://github.com/TokTok/c-toxcore/pull/161) Minor cleanups: unused vars, unreachable code, static globals. - [#160](https://github.com/TokTok/c-toxcore/pull/160) Work around bug in opencv3 headers. - [#157](https://github.com/TokTok/c-toxcore/pull/157) Make TCP_Connections module-private. - [#156](https://github.com/TokTok/c-toxcore/pull/156) Make TCP_Server opaque. - [#153](https://github.com/TokTok/c-toxcore/pull/153) Fix strict-ld grep expressions to include digits. - [#151](https://github.com/TokTok/c-toxcore/pull/151) Revert #130 "Make ToxAV stateless" - [#148](https://github.com/TokTok/c-toxcore/pull/148) Added UB comment r/t deleting a friend w/ active call - [#146](https://github.com/TokTok/c-toxcore/pull/146) Make group callbacks stateless - [#145](https://github.com/TokTok/c-toxcore/pull/145) Make internal chat list function take uint32_t* as well. - [#144](https://github.com/TokTok/c-toxcore/pull/144) Only build toxav if opus and vpx are found. - [#143](https://github.com/TokTok/c-toxcore/pull/143) Make toxcore code C++ compatible. - [#142](https://github.com/TokTok/c-toxcore/pull/142) Fix for windows dynamic libraries. - [#141](https://github.com/TokTok/c-toxcore/pull/141) const-correctness in windows code. - [#140](https://github.com/TokTok/c-toxcore/pull/140) Use C99 %zu format conversion in printf for size_t. - [#139](https://github.com/TokTok/c-toxcore/pull/139) Clean up Travis build a bit in preparation for osx/win. - [#138](https://github.com/TokTok/c-toxcore/pull/138) Remove format-source from travis script. - [#135](https://github.com/TokTok/c-toxcore/pull/135) Convert old groupchats to new API format - [#134](https://github.com/TokTok/c-toxcore/pull/134) Add some astyle options to make it do more. - [#133](https://github.com/TokTok/c-toxcore/pull/133) Ensure that all TODOs have an owner. - [#132](https://github.com/TokTok/c-toxcore/pull/132) Remove `else` directly after `return`. - [#130](https://github.com/TokTok/c-toxcore/pull/130) Make ToxAV stateless - [#129](https://github.com/TokTok/c-toxcore/pull/129) Use TokTok's apidsl instead of the iphydf one. - [#127](https://github.com/TokTok/c-toxcore/pull/127) Use "phase" script for travis build phases. - [#126](https://github.com/TokTok/c-toxcore/pull/126) Add option to build static libraries. - [#125](https://github.com/TokTok/c-toxcore/pull/125) Group #include directives in 3-4 groups. - [#123](https://github.com/TokTok/c-toxcore/pull/123) Use correct logical operator for tox_test - [#120](https://github.com/TokTok/c-toxcore/pull/120) make the majority of the callbacks stateless and add some status to a testcase - [#118](https://github.com/TokTok/c-toxcore/pull/118) Use `const` for version numbers. - [#117](https://github.com/TokTok/c-toxcore/pull/117) Add STRICT_ABI cmake flag to generate export lists. - [#116](https://github.com/TokTok/c-toxcore/pull/116) Fix potential null pointer dereference. - [#115](https://github.com/TokTok/c-toxcore/pull/115) Fix memory leak on error paths in tox_new. - [#114](https://github.com/TokTok/c-toxcore/pull/114) Fix compilation for Windows. - [#111](https://github.com/TokTok/c-toxcore/pull/111) Add debugging option to autotools configuration - [#110](https://github.com/TokTok/c-toxcore/pull/110) Comment intentional switch fallthroughs - [#109](https://github.com/TokTok/c-toxcore/pull/109) Separate ip_port packing from pack_nodes() and unpack_nodes() - [#108](https://github.com/TokTok/c-toxcore/pull/108) Prevent `` inclusion by ``. - [#107](https://github.com/TokTok/c-toxcore/pull/107) Print a message about missing astyle in format-source. - [#104](https://github.com/TokTok/c-toxcore/pull/104) Merge with irungentoo/master - [#103](https://github.com/TokTok/c-toxcore/pull/103) Allocate `sizeof(IP_ADAPTER_INFO)` bytes instead of `sizeof(T*)`. - [#101](https://github.com/TokTok/c-toxcore/pull/101) Add TODO for @mannol. - [#100](https://github.com/TokTok/c-toxcore/pull/100) Remove the packet mutation in toxav's bwcontroller. - [#99](https://github.com/TokTok/c-toxcore/pull/99) Make packet data a ptr-to-const. - [#97](https://github.com/TokTok/c-toxcore/pull/97) Improve static and const correctness. - [#96](https://github.com/TokTok/c-toxcore/pull/96) Improve C standard compliance. - [#94](https://github.com/TokTok/c-toxcore/pull/94) Rearrange fields to decrease size of structure - [#84](https://github.com/TokTok/c-toxcore/pull/84) Remove useless casts. - [#82](https://github.com/TokTok/c-toxcore/pull/82) Add missing #include to av_test.c. - [#81](https://github.com/TokTok/c-toxcore/pull/81) Match parameter names in declarations with their definitions. - [#80](https://github.com/TokTok/c-toxcore/pull/80) Sort #includes in all source files. - [#79](https://github.com/TokTok/c-toxcore/pull/79) Remove redundant `return` statements. - [#78](https://github.com/TokTok/c-toxcore/pull/78) Do not use `else` after `return`. - [#77](https://github.com/TokTok/c-toxcore/pull/77) Add OSX and Windows build to travis config. - [#76](https://github.com/TokTok/c-toxcore/pull/76) Remove unused and bit-rotten friends_test. - [#75](https://github.com/TokTok/c-toxcore/pull/75) Enable build of av_test. - [#74](https://github.com/TokTok/c-toxcore/pull/74) Add missing #includes to headers and rename tox_old to tox_group. - [#73](https://github.com/TokTok/c-toxcore/pull/73) Add braces to all if statements. - [#72](https://github.com/TokTok/c-toxcore/pull/72) Add getters/setters for options. - [#70](https://github.com/TokTok/c-toxcore/pull/70) Expose constants as functions. - [#68](https://github.com/TokTok/c-toxcore/pull/68) Add address sanitizer option to cmake file. - [#66](https://github.com/TokTok/c-toxcore/pull/66) Fix plane size calculation in test - [#65](https://github.com/TokTok/c-toxcore/pull/65) Avoid large stack allocations on thread stacks. - [#64](https://github.com/TokTok/c-toxcore/pull/64) Comment out useless TODO'd if block. - [#63](https://github.com/TokTok/c-toxcore/pull/63) Initialise the id in assoc_test. - [#62](https://github.com/TokTok/c-toxcore/pull/62) Reduce the timeout on travis to something much more reasonable - [#60](https://github.com/TokTok/c-toxcore/pull/60) Make friend requests stateless - [#59](https://github.com/TokTok/c-toxcore/pull/59) Replace uint with unsigned int in assoc.c. - [#58](https://github.com/TokTok/c-toxcore/pull/58) Make Message received receipts stateless - [#57](https://github.com/TokTok/c-toxcore/pull/57) Make Friend User Status stateless - [#55](https://github.com/TokTok/c-toxcore/pull/55) docs(INSTALL.md): update instructions for Gentoo - [#54](https://github.com/TokTok/c-toxcore/pull/54) Make typing change callback stateless - [#53](https://github.com/TokTok/c-toxcore/pull/53) Add format-source script. - [#52](https://github.com/TokTok/c-toxcore/pull/52) Build assoc DHT code on travis. - [#51](https://github.com/TokTok/c-toxcore/pull/51) Fix operation sequencing in TCP_test. - [#49](https://github.com/TokTok/c-toxcore/pull/49) Apidsl test - [#48](https://github.com/TokTok/c-toxcore/pull/48) Make friend message callback stateless - [#46](https://github.com/TokTok/c-toxcore/pull/46) Move logging to a callback. - [#45](https://github.com/TokTok/c-toxcore/pull/45) Stateless friend status message - [#43](https://github.com/TokTok/c-toxcore/pull/43) Allow NULL as argument to tox_kill. - [#41](https://github.com/TokTok/c-toxcore/pull/41) Fix warnings - [#39](https://github.com/TokTok/c-toxcore/pull/39) Merge irungentoo/toxcore into TokTok/c-toxcore. - [#38](https://github.com/TokTok/c-toxcore/pull/38) Try searching for libsodium with pkg-config in ./configure. - [#37](https://github.com/TokTok/c-toxcore/pull/37) Add missing DHT_bootstrap to CMakeLists.txt. - [#36](https://github.com/TokTok/c-toxcore/pull/36) Make tox_callback_friend_name stateless. - [#33](https://github.com/TokTok/c-toxcore/pull/33) Update readme with tentative roadmap, removed old todo.md - [#32](https://github.com/TokTok/c-toxcore/pull/32) Fix a bug I introduced that would make toxcore fail to initialise a second time - [#31](https://github.com/TokTok/c-toxcore/pull/31) 7. Travis envs - [#30](https://github.com/TokTok/c-toxcore/pull/30) 2. Hstox test - [#29](https://github.com/TokTok/c-toxcore/pull/29) 1. Move toxcore travis build scripts out of .travis.yml. - [#27](https://github.com/TokTok/c-toxcore/pull/27) 8. Stateless - [#26](https://github.com/TokTok/c-toxcore/pull/26) 6. Cmake bootstrapd - [#25](https://github.com/TokTok/c-toxcore/pull/25) 5. Coverage clang - [#24](https://github.com/TokTok/c-toxcore/pull/24) Silence/fix some compiler warnings. - [#23](https://github.com/TokTok/c-toxcore/pull/23) 4. Cmake - [#20](https://github.com/TokTok/c-toxcore/pull/20) 3. Travis astyle - [#13](https://github.com/TokTok/c-toxcore/pull/13) Enable, and report test status - [#12](https://github.com/TokTok/c-toxcore/pull/12) Fix readme for TokTok - [#11](https://github.com/TokTok/c-toxcore/pull/11) Documentation: SysVInit workaround for <1024 ports - [#2](https://github.com/TokTok/c-toxcore/pull/2) Enable toxcore logging when building on Travis. - [#1](https://github.com/TokTok/c-toxcore/pull/1) Apidsl fixes and start tracking test coverage ### Closed issues: - [#158](https://github.com/TokTok/c-toxcore/issues/158) Error while build with OpenCV 3.1 - [#147](https://github.com/TokTok/c-toxcore/issues/147) Add comment to m_delfriend about the NULL passing to the internal conn status cb - [#136](https://github.com/TokTok/c-toxcore/issues/136) Replace astyle by clang-format - [#113](https://github.com/TokTok/c-toxcore/issues/113) Toxcore tests fail - [#83](https://github.com/TokTok/c-toxcore/issues/83) Travis tests are hard to quickly parse from their output. - [#22](https://github.com/TokTok/c-toxcore/issues/22) Make the current tests exercise both ipv4 and ipv6. - [#9](https://github.com/TokTok/c-toxcore/issues/9) Fix the failing test - [#8](https://github.com/TokTok/c-toxcore/issues/8) Toxcore should make more liberal use of assertions - [#4](https://github.com/TokTok/c-toxcore/issues/4) Integrate hstox tests with toxcore Travis build c-toxcore-0.2.18/cmake/0000777000175000017500000000000014227324767013613 5ustar robinrobinc-toxcore-0.2.18/cmake/CompileGTest.cmake0000777000175000017500000000420314227324767017156 0ustar robinrobin# Find and compile the GTest library. include(CheckCXXCompilerFlag) include(CheckIncludeFileCXX) message(STATUS "Checking for gtest") # Look for the sources. find_file(GTEST_ALL_CC gtest-all.cc PATHS ${CMAKE_SOURCE_DIR}/third_party/googletest/googletest/src /usr/src/gtest/src NO_DEFAULT_PATH ) if(GTEST_ALL_CC) # ../.. from the source file is the source root. get_filename_component(GTEST_SRC_DIR ${GTEST_ALL_CC} DIRECTORY) get_filename_component(GTEST_SRC_ROOT ${GTEST_SRC_DIR} DIRECTORY) # Look for the header file. include(CheckIncludeFileCXX) include_directories(SYSTEM ${GTEST_SRC_ROOT}/include) check_include_file_cxx("gtest/gtest.h" HAVE_GTEST_GTEST_H) if(HAVE_GTEST_GTEST_H) message(STATUS "Found gtest: ${GTEST_SRC_ROOT}") add_library(gtest ${GTEST_SRC_DIR}/gtest-all.cc ${GTEST_SRC_DIR}/gtest_main.cc) target_include_directories(gtest PRIVATE ${GTEST_SRC_ROOT}) # Ignore all warnings for gtest. We don't care about their implementation. check_cxx_compiler_flag("-w" HAVE_CXX_W QUIET) if(HAVE_CXX_W) set_target_properties(gtest PROPERTIES COMPILE_FLAGS "-w") endif() set(HAVE_GTEST TRUE) set(TEST_CXX_FLAGS "") check_cxx_compiler_flag("-Wno-global-constructors" HAVE_CXX_W_NO_GLOBAL_CONSTRUCTORS QUIET) if(HAVE_CXX_W_NO_GLOBAL_CONSTRUCTORS) set(TEST_CXX_FLAGS "${TEST_CXX_FLAGS} -Wno-global-constructors") endif() check_cxx_compiler_flag("-Wno-zero-as-null-pointer-constant" HAVE_CXX_W_NO_ZERO_AS_NULL_POINTER_CONSTANT QUIET) if(HAVE_CXX_W_NO_ZERO_AS_NULL_POINTER_CONSTANT) set(TEST_CXX_FLAGS "${TEST_CXX_FLAGS} -Wno-zero-as-null-pointer-constant") endif() endif() endif() function(unit_test subdir target) if(HAVE_GTEST) add_executable(unit_${target}_test ${subdir}/${target}_test.cc) target_link_modules(unit_${target}_test toxcore gtest) set_target_properties(unit_${target}_test PROPERTIES COMPILE_FLAGS "${TEST_CXX_FLAGS}") add_test(NAME ${target} COMMAND ${CROSSCOMPILING_EMULATOR} unit_${target}_test) set_property(TEST ${target} PROPERTY ENVIRONMENT "LLVM_PROFILE_FILE=${target}.profraw") endif() endfunction() c-toxcore-0.2.18/cmake/Dependencies.cmake0000777000175000017500000000443214227324767017211 0ustar robinrobin############################################################################### # # :: For UNIX-like systems that have pkg-config. # ############################################################################### include(ModulePackage) find_package(Threads REQUIRED) find_library(NSL_LIBRARIES nsl ) find_library(RT_LIBRARIES rt ) find_library(SOCKET_LIBRARIES socket ) # For toxcore. pkg_use_module(LIBSODIUM libsodium ) # For toxav. pkg_use_module(OPUS "opus;Opus" ) pkg_use_module(VPX "vpx;libvpx" ) # For tox-bootstrapd. pkg_use_module(LIBCONFIG libconfig ) ############################################################################### # # :: For MSVC Windows builds. # # These require specific installation paths of dependencies: # - libsodium in third-party/libsodium/Win32/Release/v140/dynamic # - pthreads in third-party/pthreads-win32/Pre-built.2 # ############################################################################### if(MSVC) # libsodium # --------- if(NOT LIBSODIUM_FOUND) find_library(LIBSODIUM_LIBRARIES NAMES sodium libsodium PATHS "third_party/libsodium/Win32/Release/v140/dynamic" "third_party/libsodium/x64/Release/v140/dynamic" ) if(LIBSODIUM_LIBRARIES) include_directories("third_party/libsodium/include") set(LIBSODIUM_FOUND TRUE) message("libsodium: ${LIBSODIUM_LIBRARIES}") else() message(FATAL_ERROR "libsodium libraries not found") endif() endif() # pthreads # -------- if(CMAKE_USE_WIN32_THREADS_INIT) find_library(CMAKE_THREAD_LIBS_INIT NAMES pthreadVC2 PATHS "third_party/pthreads-win32/Pre-built.2/lib/x86" "third_party/pthreads-win32/Pre-built.2/lib/x64" ) if(CMAKE_THREAD_LIBS_INIT) include_directories("third_party/pthreads-win32/Pre-built.2/include") add_definitions(-DHAVE_STRUCT_TIMESPEC) message("libpthreads: ${CMAKE_THREAD_LIBS_INIT}") else() find_package(pthreads4w) if(NOT pthreads4w_FOUND) message(FATAL_ERROR "libpthreads libraries not found") endif() include_directories(${pthreads4w_INCLUDE_DIR}) link_libraries(${pthreads4w_LIBRARIES}) endif() endif() endif() c-toxcore-0.2.18/cmake/MacRpath.cmake0000777000175000017500000000173614227324767016326 0ustar robinrobin# Taken from https://cmake.org/Wiki/CMake_RPATH_handling#Always_full_RPATH. # # In many cases you will want to make sure that the required libraries are # always found independent from LD_LIBRARY_PATH and the install location. Then # you can use these settings: # Use, i.e. don't skip the full RPATH for the build tree. set(CMAKE_SKIP_BUILD_RPATH FALSE) # When building, don't use the install RPATH already # (but later on when installing). set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") # Add the automatically determined parts of the RPATH # which point to directories outside the build tree to the install RPATH. set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # The RPATH to be used when installing, but only if it's not a system directory. list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) if("${isSystemDir}" STREQUAL "-1") set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") endif() c-toxcore-0.2.18/cmake/ModulePackage.cmake0000777000175000017500000001371414227324767017327 0ustar robinrobinoption(ENABLE_SHARED "Build shared (dynamic) libraries for all modules" ON) option(ENABLE_STATIC "Build static libraries for all modules" ON) if(NOT ENABLE_SHARED AND NOT ENABLE_STATIC) message(WARNING "Both static and shared libraries are disabled; " "enabling only shared libraries. Use -DENABLE_SHARED or -DENABLE_STATIC to " "select one manually.") set(ENABLE_SHARED ON) endif() option(FULLY_STATIC "Build fully static executables" OFF) if(FULLY_STATIC) set(CMAKE_EXE_LINKER_FLAGS "-static -no-pie") # remove -Wl,-Bdynamic set(CMAKE_EXE_LINK_DYNAMIC_C_FLAGS) set(CMAKE_EXE_LINK_DYNAMIC_CXX_FLAGS) set(ENABLE_SHARED OFF) set(ENABLE_STATIC ON) endif() find_package(PkgConfig) function(pkg_use_module mod pkgs) foreach(pkg IN ITEMS ${pkgs}) if(PKG_CONFIG_FOUND) pkg_search_module(${mod} ${pkg}) endif() if(NOT ${mod}_FOUND) find_package(${pkg} QUIET) # This is very very ugly, but the variables are sometimes used in this scope # and sometimes in the parent scope, so we have to set them to both places. set(${mod}_FOUND ${${pkg}_FOUND}) set(${mod}_FOUND ${${pkg}_FOUND} PARENT_SCOPE) set(${mod}_LIBRARIES ${${pkg}_LIBS}) set(${mod}_LIBRARIES ${${pkg}_LIBS} PARENT_SCOPE) set(${mod}_LIBRARY_DIRS ${${pkg}_LIBRARY_DIRS}) set(${mod}_LIBRARY_DIRS ${${pkg}_LIBRARY_DIRS} PARENT_SCOPE) set(${mod}_INCLUDE_DIRS ${${pkg}_INCLUDE_DIRS}) set(${mod}_INCLUDE_DIRS ${${pkg}_INCLUDE_DIRS} PARENT_SCOPE) endif() if(${mod}_FOUND) link_directories(${${mod}_LIBRARY_DIRS}) include_directories(${${mod}_INCLUDE_DIRS}) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${${mod}_CFLAGS_OTHER}" PARENT_SCOPE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${${mod}_CFLAGS_OTHER}" PARENT_SCOPE) if(NOT MSVC) foreach(dir ${${mod}_INCLUDE_DIRS}) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -isystem ${dir}" PARENT_SCOPE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${dir}" PARENT_SCOPE) endforeach() endif() break() endif() endforeach() endfunction() function(add_module lib) set(${lib}_SOURCES ${ARGN} PARENT_SCOPE) if(ENABLE_SHARED) add_library(${lib}_shared SHARED ${ARGN}) set_target_properties(${lib}_shared PROPERTIES OUTPUT_NAME ${lib}) endif() if(ENABLE_STATIC) add_library(${lib}_static STATIC ${ARGN}) set_target_properties(${lib}_static PROPERTIES OUTPUT_NAME ${lib}) endif() endfunction() function(install_module lib) if(ENABLE_SHARED) set_target_properties(${lib}_shared PROPERTIES VERSION ${SOVERSION} SOVERSION ${SOVERSION_MAJOR} ) install(TARGETS ${lib}_shared RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() if(ENABLE_STATIC) install(TARGETS ${lib}_static RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() string(REPLACE ";" " " ${lib}_PKGCONFIG_LIBS "${${lib}_PKGCONFIG_LIBS}") string(REPLACE ";" " " ${lib}_PKGCONFIG_REQUIRES "${${lib}_PKGCONFIG_REQUIRES}") configure_file( "${${lib}_SOURCE_DIR}/other/pkgconfig/${lib}.pc.in" "${CMAKE_BINARY_DIR}/${lib}.pc" @ONLY ) configure_file( "${toxcore_SOURCE_DIR}/other/rpm/${lib}.spec.in" "${CMAKE_BINARY_DIR}/${lib}.spec" @ONLY ) install(FILES ${CMAKE_BINARY_DIR}/${lib}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) foreach(sublib ${${lib}_API_HEADERS}) string(REPLACE "^" ";" sublib ${sublib}) list(GET sublib 0 header) install(FILES ${header} ${ARGN}) endforeach() endfunction() function(target_link_modules target) # If the target we're adding dependencies to is a shared library, add it to # the set of targets. if(TARGET ${target}_shared) set(_targets ${_targets} ${target}_shared) # Shared libraries should first try to link against other shared libraries. set(${target}_shared_primary shared) # If that fails (because the shared target doesn't exist), try linking # against the static library. This requires the static library's objects to # be PIC. set(${target}_shared_secondary static) endif() # It can also be a static library at the same time. if(TARGET ${target}_static) set(_targets ${_targets} ${target}_static) # Static libraries aren't actually linked, but their dependencies are # recorded by "linking" them. If we link an executable to a static library, # we want to also link statically against its transitive dependencies. set(${target}_static_primary static) # If a dependency doesn't exist as static library, we link against the # shared one. set(${target}_static_secondary shared) endif() # If it's neither, then it's an executable. if(NOT _targets) set(_targets ${_targets} ${target}) # Executables preferably link against static libraries, so they are # standalone and can be shipped without any external dependencies. As a # frame of reference: tests become roughly 600-800K binaries instead of # 50-100K on x86_64 Linux. set(${target}_primary static) set(${target}_secondary shared) endif() foreach(dep ${ARGN}) foreach(_target ${_targets}) if(TARGET ${dep}_${${_target}_primary}) target_link_libraries(${_target} ${dep}_${${_target}_primary}) elseif(TARGET ${dep}_${${_target}_secondary}) target_link_libraries(${_target} ${dep}_${${_target}_secondary}) else() # We record the modules linked to this target, so that we can collect # them later when linking a composed module. list(FIND LINK_MODULES ${dep} _index) if(_index EQUAL -1) set(LINK_MODULES ${LINK_MODULES} ${dep}) endif() target_link_libraries(${_target} ${dep}) endif() endforeach() endforeach() set(${target}_LINK_MODULES ${${target}_LINK_MODULES} ${LINK_MODULES} PARENT_SCOPE) endfunction() c-toxcore-0.2.18/cmake/StrictAbi.cmake0000777000175000017500000000451014227324767016504 0ustar robinrobin################################################################################ # # :: Strict ABI # # Enabling the STRICT_ABI flag will generate and use an LD version script. # It ensures that the dynamic libraries (libtoxcore.so, libtoxav.so) only # export the symbols that are defined in their public API (tox.h and toxav.h, # respectively). # ################################################################################ find_program(SHELL NAMES sh dash bash zsh fish) macro(make_version_script) if(STRICT_ABI AND SHELL AND ENABLE_SHARED) _make_version_script(${ARGN}) endif() endmacro() function(_make_version_script target) set(${target}_VERSION_SCRIPT "${CMAKE_BINARY_DIR}/${target}.ld") file(WRITE ${${target}_VERSION_SCRIPT} "{ global:\n") foreach(sublib ${ARGN}) string(REPLACE "^" ";" sublib ${sublib}) list(GET sublib 0 header) list(GET sublib 1 ns) execute_process( COMMAND ${SHELL} -c "egrep '^\\w' ${header} | grep '${ns}_[a-z0-9_]*(' | grep -v '^typedef' | grep -o '${ns}_[a-z0-9_]*(' | egrep -o '\\w+' | sort -u" OUTPUT_VARIABLE sublib_SYMS OUTPUT_STRIP_TRAILING_WHITESPACE) string(REPLACE "\n" ";" sublib_SYMS ${sublib_SYMS}) foreach(sym ${sublib_SYMS}) file(APPEND ${${target}_VERSION_SCRIPT} "${sym};\n") endforeach(sym) endforeach(sublib) file(APPEND ${${target}_VERSION_SCRIPT} "local: *; };\n") set_target_properties(${target}_shared PROPERTIES LINK_FLAGS -Wl,--version-script,${${target}_VERSION_SCRIPT}) endfunction() option(STRICT_ABI "Enforce strict ABI export in dynamic libraries" OFF) if(WIN32 OR APPLE) # Windows and OSX don't have this linker functionality. set(STRICT_ABI OFF) endif() if(STRICT_ABI AND NOT ENABLE_STATIC) if(AUTOTEST) message("AUTOTEST option is incompatible with STRICT_ABI. Disabling AUTOTEST.") endif() set(AUTOTEST OFF) if(BUILD_MISC_TESTS) message("BUILD_MISC_TESTS option is incompatible with STRICT_ABI. Disabling BUILD_MISC_TESTS.") endif() set(BUILD_MISC_TESTS OFF) if(BOOTSTRAP_DAEMON) message("BOOTSTRAP_DAEMON option is incompatible with STRICT_ABI. Disabling BOOTSTRAP_DAEMON.") endif() set(BOOTSTRAP_DAEMON OFF) if(DHT_BOOTSTRAP) message("DHT_BOOTSTRAP option is incompatible with STRICT_ABI. Disabling DHT_BOOTSTRAP.") endif() set(DHT_BOOTSTRAP OFF) endif() c-toxcore-0.2.18/CMakeLists.txt0000777000175000017500000003527714227324767015314 0ustar robinrobin################################################################################ # # The main toxcore CMake build file. # # This file when processed with cmake produces: # - A number of small libraries (.a/.so/...) containing independent components # of toxcore. E.g. the DHT has its own library, and the system/network # abstractions are in their own library as well. These libraries are not # installed on `make install`. The toxav, and toxencryptsave libraries are # also not installed. # - A number of small programs, statically linked if possible. # - One big library containing all of the toxcore, toxav, and toxencryptsave # code. # ################################################################################ cmake_minimum_required(VERSION 2.8.12) cmake_policy(VERSION 2.8.12) project(toxcore) list(APPEND CMAKE_MODULE_PATH ${toxcore_SOURCE_DIR}/cmake) option(FLAT_OUTPUT_STRUCTURE "Whether to produce output artifacts in ${CMAKE_BINARY_DIR}/{bin,lib}" OFF) if(FLAT_OUTPUT_STRUCTURE) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) endif() set_source_files_properties( toxcore/mono_time.c toxcore/network.c toxcore/tox.c toxcore/util.c PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE) ################################################################################ # # :: Version management # ################################################################################ # This version is for the entire project. All libraries (core, av, ...) move in # versions in a synchronised way. set(PROJECT_VERSION_MAJOR "0") set(PROJECT_VERSION_MINOR "2") set(PROJECT_VERSION_PATCH "18") set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") # set .so library version / following libtool scheme # https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info file(STRINGS ${toxcore_SOURCE_DIR}/so.version SOVERSION_CURRENT REGEX "^CURRENT=[0-9]+$") string(SUBSTRING "${SOVERSION_CURRENT}" 8 -1 SOVERSION_CURRENT) file(STRINGS ${toxcore_SOURCE_DIR}/so.version SOVERSION_REVISION REGEX "^REVISION=[0-9]+$") string(SUBSTRING "${SOVERSION_REVISION}" 9 -1 SOVERSION_REVISION) file(STRINGS ${toxcore_SOURCE_DIR}/so.version SOVERSION_AGE REGEX "^AGE=[0-9]+$") string(SUBSTRING "${SOVERSION_AGE}" 4 -1 SOVERSION_AGE) # account for some libtool magic, see other/version-sync script for details math(EXPR SOVERSION_MAJOR ${SOVERSION_CURRENT}-${SOVERSION_AGE}) set(SOVERSION "${SOVERSION_MAJOR}.${SOVERSION_AGE}.${SOVERSION_REVISION}") message("SOVERSION: ${SOVERSION}") ################################################################################ # # :: Dependencies and configuration # ################################################################################ include(CTest) include(ModulePackage) include(StrictAbi) include(GNUInstallDirs) if(APPLE) include(MacRpath) endif() enable_testing() set(CMAKE_MACOSX_RPATH ON) if(${CMAKE_VERSION} VERSION_LESS "3.1.0") if(NOT MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") endif() else() # Set standard version for compiler. set(CMAKE_C_STANDARD 99) set(CMAKE_CXX_STANDARD 17) set(CMAKE_C_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF) message(STATUS "Supported C compiler features = ${CMAKE_C_COMPILE_FEATURES}") message(STATUS "Supported C++ compiler features = ${CMAKE_CXX_COMPILE_FEATURES}") endif() set(MIN_LOGGER_LEVEL "" CACHE STRING "Logging level to use (TRACE, DEBUG, INFO, WARNING, ERROR)") if(MIN_LOGGER_LEVEL) if(("${MIN_LOGGER_LEVEL}" STREQUAL "TRACE") OR ("${MIN_LOGGER_LEVEL}" STREQUAL "DEBUG") OR ("${MIN_LOGGER_LEVEL}" STREQUAL "INFO") OR ("${MIN_LOGGER_LEVEL}" STREQUAL "WARNING") OR ("${MIN_LOGGER_LEVEL}" STREQUAL "ERROR")) add_definitions(-DMIN_LOGGER_LEVEL=LOGGER_LEVEL_${MIN_LOGGER_LEVEL}) else() message(FATAL_ERROR "Unknown value provided for MIN_LOGGER_LEVEL: \"${MIN_LOGGER_LEVEL}\", must be one of TRACE, DEBUG, INFO, WARNING or ERROR") endif() endif() option(USE_IPV6 "Use IPv6 in tests" ON) if(NOT USE_IPV6) add_definitions(-DUSE_IPV6=0) endif() option(BUILD_MISC_TESTS "Build additional tests and utilities" OFF) option(BUILD_FUN_UTILS "Build additional just for fun utilities" OFF) option(AUTOTEST "Enable autotests (mainly for CI)" OFF) if (AUTOTEST) option(NON_HERMETIC_TESTS "Whether to build and run tests that depend on an internet connection" OFF) option(PROXY_TEST "Enable proxy test (needs HTTP/SOCKS5 proxy on port 8080/8081)" OFF) endif() option(BUILD_TOXAV "Whether to build the tox AV library" ON) option(MUST_BUILD_TOXAV "Fail the build if toxav cannot be built" OFF) option(DHT_BOOTSTRAP "Enable building of DHT_bootstrap" ON) option(BOOTSTRAP_DAEMON "Enable building of tox-bootstrapd" ON) if(BOOTSTRAP_DAEMON AND WIN32) message(WARNING "Building tox-bootstrapd for Windows is not supported, disabling") set(BOOTSTRAP_DAEMON OFF) endif() # Enabling this breaks all other tests and no network connections will be possible option(BUILD_FUZZ_TESTS "Build fuzzing harnesses" OFF) if(BUILD_FUZZ_TESTS) message(STATUS "Building in fuzz testing mode, no network connection will be possible") # Disable everything we can set(AUTOTEST OFF) set(BUILD_MISC_TESTS OFF) set(BUILD_FUN_UTILS OFF) set(ENABLE_SHARED OFF) set(MUST_BUILD_TOXAV OFF) set(BUILD_TOXAV OFF) set(BOOTSTRAP_DAEMON OFF) set(DHT_BOOTSTRAP OFF) endif() if(MSVC) option(MSVC_STATIC_SODIUM "Whether to link libsodium statically for MSVC" OFF) if(MSVC_STATIC_SODIUM) add_definitions(-DSODIUM_STATIC=1 -DSODIUM_EXPORT) endif() endif() include(Dependencies) if(MUST_BUILD_TOXAV) set(NO_TOXAV_ERROR_TYPE SEND_ERROR) else() set(NO_TOXAV_ERROR_TYPE WARNING) endif() if(BUILD_TOXAV) if(NOT OPUS_FOUND) message(${NO_TOXAV_ERROR_TYPE} "Option BUILD_TOXAV is enabled but required library OPUS was not found.") set(BUILD_TOXAV OFF) endif() if(NOT VPX_FOUND) message(${NO_TOXAV_ERROR_TYPE} "Option BUILD_TOXAV is enabled but required library VPX was not found.") set(BUILD_TOXAV OFF) endif() endif() # Disable float/double packing in CMP (C MessagePack library). # We don't transfer floats over the network, so we disable this functionality. add_definitions(-DCMP_NO_FLOAT=1) ################################################################################ # # :: Tox Core Library # ################################################################################ # toxcore_PKGCONFIG_LIBS is what's added to the Libs: line in toxcore.pc. It # needs to contain all the libraries a program using toxcore should link against # if it's statically linked. If it's dynamically linked, there is no need to # explicitly link against all the dependencies, but it doesn't harm much(*) # either. # # (*) It allows client code to use symbols from our dependencies without # explicitly linking against them. set(toxcore_PKGCONFIG_LIBS) # Requires: in pkg-config file. set(toxcore_PKGCONFIG_REQUIRES) set(toxcore_SOURCES third_party/cmp/cmp.c third_party/cmp/cmp.h toxcore/announce.c toxcore/announce.h toxcore/bin_pack.c toxcore/bin_pack.h toxcore/bin_unpack.c toxcore/bin_unpack.h toxcore/ccompat.c toxcore/ccompat.h toxcore/crypto_core.c toxcore/crypto_core.h toxcore/DHT.c toxcore/DHT.h toxcore/events/conference_connected.c toxcore/events/conference_invite.c toxcore/events/conference_message.c toxcore/events/conference_peer_list_changed.c toxcore/events/conference_peer_name.c toxcore/events/conference_title.c toxcore/events/events_alloc.c toxcore/events/events_alloc.h toxcore/events/file_chunk_request.c toxcore/events/file_recv.c toxcore/events/file_recv_chunk.c toxcore/events/file_recv_control.c toxcore/events/friend_connection_status.c toxcore/events/friend_lossless_packet.c toxcore/events/friend_lossy_packet.c toxcore/events/friend_message.c toxcore/events/friend_name.c toxcore/events/friend_read_receipt.c toxcore/events/friend_request.c toxcore/events/friend_status.c toxcore/events/friend_status_message.c toxcore/events/friend_typing.c toxcore/events/self_connection_status.c toxcore/forwarding.c toxcore/forwarding.h toxcore/friend_connection.c toxcore/friend_connection.h toxcore/friend_requests.c toxcore/friend_requests.h toxcore/group.c toxcore/group.h toxcore/group_announce.c toxcore/group_announce.h toxcore/group_moderation.c toxcore/group_moderation.h toxcore/LAN_discovery.c toxcore/LAN_discovery.h toxcore/list.c toxcore/list.h toxcore/logger.c toxcore/logger.h toxcore/Messenger.c toxcore/Messenger.h toxcore/mono_time.c toxcore/mono_time.h toxcore/net_crypto.c toxcore/net_crypto.h toxcore/network.c toxcore/network.h toxcore/onion_announce.c toxcore/onion_announce.h toxcore/onion.c toxcore/onion_client.c toxcore/onion_client.h toxcore/onion.h toxcore/ping_array.c toxcore/ping_array.h toxcore/ping.c toxcore/ping.h toxcore/state.c toxcore/state.h toxcore/TCP_client.c toxcore/TCP_client.h toxcore/TCP_common.c toxcore/TCP_common.h toxcore/TCP_connection.c toxcore/TCP_connection.h toxcore/TCP_server.c toxcore/TCP_server.h toxcore/timed_auth.c toxcore/timed_auth.h toxcore/tox_api.c toxcore/tox.c toxcore/tox_dispatch.c toxcore/tox_dispatch.h toxcore/tox_events.c toxcore/tox_events.h toxcore/tox.h toxcore/tox_private.c toxcore/tox_private.h toxcore/tox_unpack.c toxcore/tox_unpack.h toxcore/util.c toxcore/util.h) set(toxcore_LINK_MODULES ${toxcore_LINK_MODULES} ${LIBSODIUM_LIBRARIES}) set(toxcore_PKGCONFIG_REQUIRES ${toxcore_PKGCONFIG_REQUIRES} libsodium) set(toxcore_API_HEADERS ${toxcore_SOURCE_DIR}/toxcore/tox.h^tox ${toxcore_SOURCE_DIR}/toxcore/tox_events.h^tox ${toxcore_SOURCE_DIR}/toxcore/tox_dispatch.h^tox) ################################################################################ # # :: Audio/Video Library # ################################################################################ if(BUILD_TOXAV) set(toxcore_SOURCES ${toxcore_SOURCES} toxav/audio.c toxav/audio.h toxav/bwcontroller.c toxav/bwcontroller.h toxav/groupav.c toxav/groupav.h toxav/msi.c toxav/msi.h toxav/ring_buffer.c toxav/ring_buffer.h toxav/rtp.c toxav/rtp.h toxav/toxav.c toxav/toxav.h toxav/toxav_old.c toxav/video.c toxav/video.h) set(toxcore_API_HEADERS ${toxcore_API_HEADERS} ${toxcore_SOURCE_DIR}/toxav/toxav.h^toxav) set(toxcore_LINK_MODULES ${toxcore_LINK_MODULES} ${OPUS_LIBRARIES} ${VPX_LIBRARIES}) set(toxcore_PKGCONFIG_REQUIRES ${toxcore_PKGCONFIG_REQUIRES} opus vpx) endif() ################################################################################ # # :: Block encryption libraries # ################################################################################ set(toxcore_SOURCES ${toxcore_SOURCES} toxencryptsave/toxencryptsave.c toxencryptsave/toxencryptsave.h) set(toxcore_API_HEADERS ${toxcore_API_HEADERS} ${toxcore_SOURCE_DIR}/toxencryptsave/toxencryptsave.h^tox) ################################################################################ # # :: System dependencies # ################################################################################ # These need to come after other dependencies, since e.g. libvpx may depend on # pthread, but doesn't list it in VPX_LIBRARIES. We're adding it here, after # any potential libvpx linking. message("CMAKE_THREAD_LIBS_INIT: ${CMAKE_THREAD_LIBS_INIT}") if(CMAKE_THREAD_LIBS_INIT) set(toxcore_LINK_MODULES ${toxcore_LINK_MODULES} ${CMAKE_THREAD_LIBS_INIT}) set(toxcore_PKGCONFIG_LIBS ${toxcore_PKGCONFIG_LIBS} ${CMAKE_THREAD_LIBS_INIT}) endif() if(NSL_LIBRARIES) set(toxcore_LINK_MODULES ${toxcore_LINK_MODULES} ${NSL_LIBRARIES}) set(toxcore_PKGCONFIG_LIBS ${toxcore_PKGCONFIG_LIBS} -lnsl) endif() if(RT_LIBRARIES) set(toxcore_LINK_MODULES ${toxcore_LINK_MODULES} ${RT_LIBRARIES}) set(toxcore_PKGCONFIG_LIBS ${toxcore_PKGCONFIG_LIBS} -lrt) endif() if(SOCKET_LIBRARIES) set(toxcore_LINK_MODULES ${toxcore_LINK_MODULES} ${SOCKET_LIBRARIES}) set(toxcore_PKGCONFIG_LIBS ${toxcore_PKGCONFIG_LIBS} -lsocket) endif() if(WIN32) set(toxcore_LINK_MODULES ${toxcore_LINK_MODULES} ws2_32 iphlpapi) set(toxcore_PKGCONFIG_LIBS ${toxcore_PKGCONFIG_LIBS} -lws2_32 -liphlpapi) endif() ################################################################################ # # :: All layers together in one library for ease of use # ################################################################################ # Create combined library from all the sources. add_module(toxcore ${toxcore_SOURCES}) # Link it to all dependencies. target_link_modules(toxcore ${toxcore_LINK_MODULES}) # Make version script (on systems that support it) to limit symbol visibility. make_version_script(toxcore ${toxcore_API_HEADERS}) # Generate pkg-config file, install library to "${CMAKE_INSTALL_LIBDIR}" and install headers to # "${CMAKE_INSTALL_INCLUDEDIR}/tox". install_module(toxcore DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/tox) ################################################################################ # # :: Unit tests: no networking, just pure function calls. # ################################################################################ include(CompileGTest) # The actual unit tests follow. # unit_test(toxav ring_buffer) unit_test(toxav rtp) unit_test(toxcore DHT) unit_test(toxcore bin_pack) unit_test(toxcore crypto_core) unit_test(toxcore group_announce) unit_test(toxcore group_moderation) unit_test(toxcore mono_time) unit_test(toxcore ping_array) unit_test(toxcore tox) unit_test(toxcore util) add_subdirectory(testing) ################################################################################ # # :: Automated regression tests: create a tox network and run integration tests # ################################################################################ if(AUTOTEST) add_subdirectory(auto_tests) endif() ################################################################################ # # :: Bootstrap daemon # ################################################################################ if(DHT_BOOTSTRAP) add_executable(DHT_bootstrap other/DHT_bootstrap.c other/bootstrap_node_packets.c) target_link_modules(DHT_bootstrap toxcore misc_tools) install(TARGETS DHT_bootstrap RUNTIME DESTINATION bin) endif() if(BOOTSTRAP_DAEMON) if(LIBCONFIG_FOUND) add_subdirectory(other/bootstrap_daemon) else() message(WARNING "Option BOOTSTRAP_DAEMON is enabled but required library LIBCONFIG was not found.") set(BOOTSTRAP_DAEMON OFF) endif() endif() if(BUILD_FUN_UTILS) add_subdirectory(other/fun) endif() if (BUILD_FUZZ_TESTS) add_subdirectory(testing/fuzzing) endif() c-toxcore-0.2.18/codecov.yml0000777000175000017500000000053414227324767014705 0ustar robinrobin--- coverage: precision: 2 round: down range: "80...100" status: project: default: # Allow coverage to fluctuate 2% up and down. We can never go below 80% # because of the above range, but toxcore coverage fluctuates a lot due # to low coverage of error paths that sometimes happen. threshold: 2% c-toxcore-0.2.18/conanfile.py0000777000175000017500000000537414227324767015057 0ustar robinrobin# pylint: disable=not-callable import os import re from conans import CMake from conans import ConanFile from conans.tools import collect_libs from conans.tools import load class ToxConan(ConanFile): name = "c-toxcore" url = "https://tox.chat" description = "The future of online communications." license = "GPL-3.0-only" settings = "os", "compiler", "build_type", "arch" requires = "libsodium/1.0.18", "opus/1.3.1", "libvpx/1.9.0" generators = "cmake_find_package" scm = {"type": "git", "url": "auto", "revision": "auto"} options = { "shared": [True, False], "with_tests": [True, False], } default_options = { "shared": False, "with_tests": False, } _cmake = None def _create_cmake(self): if self._cmake is not None: return self._cmake self._cmake = CMake(self) self._cmake.definitions["AUTOTEST"] = self.options.with_tests self._cmake.definitions["BUILD_MISC_TESTS"] = self.options.with_tests self._cmake.definitions[ "CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS"] = self.options.shared self._cmake.definitions["ENABLE_SHARED"] = self.options.shared self._cmake.definitions["ENABLE_STATIC"] = not self.options.shared self._cmake.definitions["MUST_BUILD_TOXAV"] = True if self.settings.compiler == "Visual Studio": self._cmake.definitions["MSVC_STATIC_SODIUM"] = True self._cmake.definitions[ "FLAT_OUTPUT_STRUCTURE"] = self.options.shared self._cmake.configure() return self._cmake def set_version(self): content = load(os.path.join(self.recipe_folder, "CMakeLists.txt")) version_major = re.search(r"set\(PROJECT_VERSION_MAJOR \"(.*)\"\)", content).group(1) version_minor = re.search(r"set\(PROJECT_VERSION_MINOR \"(.*)\"\)", content).group(1) version_patch = re.search(r"set\(PROJECT_VERSION_PATCH \"(.*)\"\)", content).group(1) self.version = "%s.%s.%s" % ( version_major.strip(), version_minor.strip(), version_patch.strip(), ) def requirements(self): if self.settings.os == "Windows": self.requires("pthreads4w/3.0.0") def build(self): cmake = self._create_cmake() cmake.build() if self.options.with_tests: cmake.test(output_on_failure=True) def package(self): cmake = self._create_cmake() cmake.install() def package_info(self): self.cpp_info.libs = collect_libs(self) if self.settings.os == "Windows": self.cpp_info.system_libs = ["Ws2_32", "Iphlpapi"] c-toxcore-0.2.18/configure.ac0000777000175000017500000003773614227324767015044 0ustar robinrobin# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.65]) AC_INIT([tox], [0.2.18]) AC_CONFIG_AUX_DIR(configure_aux) AC_CONFIG_SRCDIR([toxcore/net_crypto.c]) AM_INIT_AUTOMAKE([foreign 1.10 -Wall -Werror subdir-objects tar-ustar]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AC_CONFIG_MACRO_DIR([m4]) EXTRA_LT_LDFLAGS= if test "x${prefix}" = "xNONE"; then prefix="${ac_default_prefix}" fi BUILD_DHT_BOOTSTRAP_DAEMON="no" BUILD_DHT_BOOTSTRAP="no" BUILD_TESTS="yes" BUILD_AV="yes" BUILD_TESTING="yes" LIBCONFIG_FOUND="no" WANT_NACL="no" ADD_NACL_OBJECTS_TO_PKGCONFIG="yes" SET_SO_VERSION="yes" AC_ARG_ENABLE([soname-versions], [AC_HELP_STRING([--enable-soname-versions], [enable soname versions (must be disabled for android) (default: enabled)]) ], [ if test "x$enableval" = "xno"; then SET_SO_VERSION="no" elif test "x$enableval" = "xyes"; then SET_SO_VERSION="yes" fi ] ) AM_CONDITIONAL(SET_SO_VERSION, test "x$SET_SO_VERSION" = "xyes") AC_ARG_ENABLE([nacl], [AC_HELP_STRING([--enable-nacl], [use nacl instead of libsodium (default: disabled)]) ], [ if test "x$enableval" = "xno"; then WANT_NACL="no" elif test "x$enableval" = "xyes"; then WANT_NACL="yes" fi ] ) AC_ARG_ENABLE([randombytes-stir], [AC_HELP_STRING([--enable-randombytes-stir], [use randombytes_stir() instead of sodium_init() for faster startup on android (default: disabled)]) ], [ if test "x$enableval" = "xyes"; then if test "x$WANT_NACL" = "xyes"; then AC_MSG_WARN([randombytes_stir() is not available with NaCl library]) else AC_DEFINE([USE_RANDOMBYTES_STIR], [1], [randombytes_stir() instead of sodium_init()]) fi fi ] ) AC_ARG_WITH(log-level, AC_HELP_STRING([--with-log-level=LEVEL], [Logger levels: TRACE; DEBUG; INFO; WARNING; ERROR ]), [ if test "x$withval" = "xTRACE"; then AC_DEFINE([MIN_LOGGER_LEVEL], [LOGGER_LEVEL_TRACE], [Logger_Level value]) elif test "x$withval" = "xDEBUG"; then AC_DEFINE([MIN_LOGGER_LEVEL], [LOGGER_LEVEL_DEBUG], [Logger_Level value]) elif test "x$withval" = "xINFO"; then AC_DEFINE([MIN_LOGGER_LEVEL], [LOGGER_LEVEL_INFO], [Logger_Level value]) elif test "x$withval" = "xWARNING"; then AC_DEFINE([MIN_LOGGER_LEVEL], [LOGGER_LEVEL_WARNING], [Logger_Level value]) elif test "x$withval" = "xERROR"; then AC_DEFINE([MIN_LOGGER_LEVEL], [LOGGER_LEVEL_ERROR], [Logger_Level value]) else AC_MSG_WARN([Invalid logger level: $withval. Using default.]) fi ] ) PKG_PROG_PKG_CONFIG AC_ARG_ENABLE([av], [AC_HELP_STRING([--disable-av], [build AV support libraries (default: auto)]) ], [ if test "x$enableval" = "xno"; then BUILD_AV="no" elif test "x$enableval" = "xyes"; then BUILD_AV="yes" fi ] ) AC_ARG_ENABLE([tests], [AC_HELP_STRING([--disable-tests], [build unit tests (default: auto)]) ], [ if test "x$enableval" = "xno"; then BUILD_TESTS="no" elif test "x$enableval" = "xyes"; then BUILD_TESTS="yes" fi ] ) AC_ARG_ENABLE([daemon], [AC_HELP_STRING([--enable-daemon], [build DHT bootstrap daemon (default: auto)]) ], [ if test "x$enableval" = "xno"; then BUILD_DHT_BOOTSTRAP_DAEMON="no" elif test "x$enableval" = "xyes"; then BUILD_DHT_BOOTSTRAP_DAEMON="yes" fi ] ) AC_ARG_ENABLE([dht-bootstrap], [AC_HELP_STRING([--enable-dht-bootstrap], [build DHT bootstrap utility (default: disabled)]) ], [ if test "x$enableval" = "xno"; then BUILD_DHT_BOOTSTRAP="no" elif test "x$enableval" = "xyes"; then BUILD_DHT_BOOTSTRAP="yes" fi ] ) AC_ARG_ENABLE([rt], [AC_HELP_STRING([--disable-rt], [Disables the librt check (default: auto)]) ], [ if test "x$enableval" = "xno"; then DISABLE_RT="yes" elif test "x$enableval" = "xyes"; then DISABLE_RT="no" fi ] ) AC_ARG_ENABLE([testing], [AC_HELP_STRING([--disable-testing], [build various testing tools (default: auto)]) ], [ if test "x$enableval" = "xno"; then BUILD_TESTING="no" elif test "x$enableval" = "xyes"; then BUILD_TESTING="yes" fi ] ) AC_ARG_ENABLE([[epoll]], [AS_HELP_STRING([[--enable-epoll[=ARG]]], [enable epoll support (yes, no, auto) [auto]])], [enable_epoll=${enableval}], [enable_epoll='auto'] ) AC_ARG_ENABLE([[ipv6]], [AS_HELP_STRING([[--disable-ipv6[=ARG]]], [use ipv4 in tests (yes, no, auto) [auto]])], [use_ipv6=${enableval}], [use_ipv6='auto'] ) if test "$use_ipv6" != "yes"; then AC_DEFINE([USE_IPV6],[0],[define to 0 to force ipv4]) fi AX_HAVE_EPOLL if test "$enable_epoll" != "no"; then if test "${ax_cv_have_epoll}" = "yes"; then AC_DEFINE([TCP_SERVER_USE_EPOLL],[1],[define to 1 to enable epoll support]) enable_epoll='yes' else if test "$enable_epoll" = "yes"; then AC_MSG_ERROR([[Support for epoll was explicitly requested but cannot be enabled on this platform.]]) fi enable_epoll='no' fi fi DEPSEARCH= LIBSODIUM_SEARCH_HEADERS= LIBSODIUM_SEARCH_LIBS= NACL_SEARCH_HEADERS= NACL_SEARCH_LIBS= AC_ARG_WITH(dependency-search, AC_HELP_STRING([--with-dependency-search=DIR], [search for dependencies in DIR, i.e., look for libraries in DIR/lib and for headers in DIR/include]), [ DEPSEARCH="$withval" ] ) if test -n "$DEPSEARCH"; then CFLAGS="$CFLAGS -I$DEPSEARCH/include" CPPFLAGS="$CPPFLAGS -I$DEPSEARCH/include" LDFLAGS="$LDFLAGS -L$DEPSEARCH/lib" export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$DEPSEARCH/lib/pkgconfig fi AC_ARG_WITH(nacl-headers, AC_HELP_STRING([--with-nacl-headers=DIR], [search for nacl header files in DIR]), [ NACL_SEARCH_HEADERS="$withval" AC_MSG_NOTICE([will search for nacl header files in $withval]) ] ) AC_ARG_WITH(nacl-libs, AC_HELP_STRING([--with-nacl-libs=DIR], [search for nacl libraries in DIR]), [ NACL_SEARCH_LIBS="$withval" AC_MSG_NOTICE([will search for nacl libraries in $withval]) ] ) AC_ARG_WITH(libsodium-headers, AC_HELP_STRING([--with-libsodium-headers=DIR], [search for libsodium header files in DIR]), [ LIBSODIUM_SEARCH_HEADERS="$withval" AC_MSG_NOTICE([will search for libsodium header files in $withval]) ] ) AC_ARG_WITH(libsodium-libs, AC_HELP_STRING([--with-libsodium-libs=DIR], [search for libsodium libraries in DIR]), [ LIBSODIUM_SEARCH_LIBS="$withval" AC_MSG_NOTICE([will search for libsodium libraries in $withval]) ] ) if test "x$WANT_NACL" = "xyes"; then enable_shared=no enable_static=yes fi # Checks for programs. AC_PROG_CC_C99 if test "x$ac_cv_prog_cc_c99" = "xno" ; then AC_MSG_ERROR([c-toxcore requires a C99 compatible compiler]) fi AM_PROG_CC_C_O m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) AC_LIBTOOL_WIN32_DLL AC_PROG_LIBTOOL WIN32=no MACH=no AC_CANONICAL_HOST case $host_os in *mingw*) WIN32="yes" EXTRA_LT_LDFLAGS="$EXTRA_LT_LDFLAGS -no-undefined" ;; *solaris*) LIBS="$LIBS -lssp -lsocket -lnsl" ;; *qnx*) LIBS="$LIBS -lsocket" ;; *freebsd*|*openbsd*) LDFLAGS="$LDFLAGS -L/usr/local/lib" CFLAGS="$CFLAGS -I/usr/local/include" CPPFLAGS="$CPPFLAGS -I/usr/local/include" ADD_NACL_OBJECTS_TO_PKGCONFIG="no" ;; darwin*) MACH=yes ;; esac AM_CONDITIONAL(WIN32, test "x$WIN32" = "xyes") AC_SUBST(EXTRA_LT_LDFLAGS) # Needed math flags for some compilers MATH_LDFLAGS="-lm" AC_SUBST(MATH_LDFLAGS) # Checks for libraries. AC_CHECK_FUNCS([explicit_bzero memset_s]) PKG_CHECK_MODULES([LIBSODIUM], [libsodium], [ LIBSODIUM_FOUND="yes" ], [ LIBSODIUM_FOUND="no" ]) if test "x$WANT_NACL" = "xyes"; then NACL_LIBS= NACL_LDFLAGS= NACL_OBJECTS= NACL_OBJECTS_PKGCONFIG= LDFLAGS_SAVE="$LDFLAGS" if test -n "$NACL_SEARCH_LIBS"; then LDFLAGS="-L$NACL_SEARCH_LIBS $LDFLAGS" AC_CHECK_LIB(nacl, random, [ NACL_LDFLAGS="-L$NACL_SEARCH_LIBS" NACL_LIBS="-lnacl" ], [ AC_MSG_ERROR([library nacl was not found in requested location $NACL_SEARCH_LIBS]) ] ) else AC_CHECK_LIB(nacl, random, [], [ AC_MSG_ERROR([you enabled nacl support, but library nacl was not found on your system]) ] ) fi if (test -f "$NACL_SEARCH_LIBS/cpucycles.o") && (test -f "$NACL_SEARCH_LIBS/randombytes.o"); then NACL_OBJECTS="$NACL_SEARCH_LIBS/cpucycles.o $NACL_SEARCH_LIBS/randombytes.o" AC_MSG_NOTICE([found extra NaCl objects: $NACL_OBJECTS]) if test "x$ADD_NACL_OBJECTS_TO_PKGCONFIG" = "xyes"; then AC_MSG_NOTICE([adding extra NaCl objects to pkg-config file]) NACL_OBJECTS_PKGCONFIG="$NACL_OBJECTS" fi else AC_MSG_ERROR([required NaCl object files cpucycles.o randombytes.o not found, please specify their location using the --with-nacl-libs parameter]) fi LDFLAGS="$LDFLAGS_SAVE" AC_SUBST(NACL_LIBS) AC_SUBST(NACL_LDFLAGS) AC_SUBST(NACL_OBJECTS) AC_SUBST(NACL_OBJECTS_PKGCONFIG) elif test "x$LIBSODIUM_FOUND" = "xno"; then LIBSODIUM_LIBS= LIBSODIUM_LDFLAGS= LDFLAGS_SAVE="$LDFLAGS" if test -n "$LIBSODIUM_SEARCH_LIBS"; then LDFLAGS="-L$LIBSODIUM_SEARCH_LIBS $LDFLAGS" AC_CHECK_LIB(sodium, crypto_pwhash_scryptsalsa208sha256, [ LIBSODIUM_LDFLAGS="-L$LIBSODIUM_SEARCH_LIBS" LIBSODIUM_LIBS="-lsodium" ], [ AC_MSG_ERROR([required library libsodium was not found in requested location $LIBSODIUM_SEARCH_LIBS or library version is too old]) ] ) else AC_CHECK_LIB(sodium, crypto_pwhash_scryptsalsa208sha256, [], [ AC_MSG_ERROR([required library libsodium was not found on your system, please check http://download.libsodium.org/libsodium/releases/ or library version is too old]) ] ) fi LDFLAGS="$LDFLAGS_SAVE" AC_SUBST(LIBSODIUM_LIBS) AC_SUBST(LIBSODIUM_LDFLAGS) fi # Checks for header files. AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdint.h stdlib.h string.h sys/socket.h sys/time.h unistd.h]) if test "x$WANT_NACL" = "xyes"; then NACL_CFLAGS= CFLAGS_SAVE="$CFLAGS" CPPFLAGS_SAVE="$CPPFLAGS" if test -n "$NACL_SEARCH_HEADERS"; then CFLAGS="-I$NACL_SEARCH_HEADERS $CFLAGS" CPPFLAGS="-I$NACL_SEARCH_HEADERS $CPPFLAGS" AC_CHECK_HEADER(crypto_box.h, [ NACL_CFLAGS="-I$NACL_SEARCH_HEADERS" ], [ AC_MSG_ERROR([header files for library nacl were not found in requested location $NACL_SEARCH_HEADERS]) ] ) else AC_CHECK_HEADER(crypto_box.h, [], [ AC_MSG_ERROR([you enabled nacl support, but nacl header files were not found on your system]) ] ) fi CFLAGS="$CFLAGS_SAVE" CPPFLAGS="$CPPFLAGS_SAVE" AC_SUBST(NACL_CFLAGS) AC_DEFINE([VANILLA_NACL], [1], [use nacl instead of libsodium]) elif test "x$LIBSODIUM_FOUND" = "xno"; then LIBSODIUM_CFLAGS= CFLAGS_SAVE="$CFLAGS" CPPFLAGS_SAVE="$CPPFLAGS" if test -n "$LIBSODIUM_SEARCH_HEADERS"; then CFLAGS="-I$LIBSODIUM_SEARCH_HEADERS $CFLAGS" CPPFLAGS="-I$LIBSODIUM_SEARCH_HEADERS $CPPFLAGS" AC_CHECK_HEADER(sodium.h, [ LIBSODIUM_CFLAGS="-I$LIBSODIUM_SEARCH_HEADERS" ], [ AC_MSG_ERROR([header files for required library libsodium were not found in requested location $LIBSODIUM_SEARCH_HEADERS]) ] ) else AC_CHECK_HEADER(sodium.h, [], [ AC_MSG_ERROR([header files for required library libsodium was not found on your system, please check http://download.libsodium.org/libsodium/releases/]) ] ) fi CFLAGS="$CFLAGS_SAVE" CPPFLAGS="$CPPFLAGS_SAVE" AC_SUBST(LIBSODIUM_CFLAGS) fi # Checks for library functions. if (test "x$WIN32" != "xyes") && (test "x$MACH" != "xyes") && (test "x${host_os#*openbsd}" = "x$host_os") && (test "x$DISABLE_RT" != "xyes"); then AC_CHECK_LIB(rt, clock_gettime, [ RT_LIBS="-lrt" AC_SUBST(RT_LIBS) ], [ AC_MSG_ERROR([required library rt was not found on your system]) ] ) fi AX_PTHREAD( [], [ AC_MSG_ERROR([required library pthread was not found on your system]) ] ) AC_CHECK_LIB([pthread], [pthread_self], [ PTHREAD_LDFLAGS="-lpthread" AC_SUBST(PTHREAD_LDFLAGS) ] ) if test "x$BUILD_AV" = "xyes"; then PKG_CHECK_MODULES([OPUS], [opus], [], [ AC_MSG_WARN([disabling AV support $OPUS_PKG_ERRORS]) BUILD_AV="no" ] ) fi if test "x$BUILD_AV" = "xyes"; then PKG_CHECK_MODULES([VPX], [vpx], [], [ AC_MSG_WARN([disabling AV support $VPX_PKG_ERRORS]) BUILD_AV="no" ] ) fi if test "x$BUILD_AV" = "xyes"; then # toxcore lib needs an global? # So far this works okay AV_LIBS="$OPUS_LIBS $VPX_LIBS" AC_SUBST(AV_LIBS) AV_CFLAGS="$OPUS_CFLAGS $VPX_CFLAGS" AC_SUBST(AV_CFLAGS) fi if test -n "$PKG_CONFIG"; then if test "x$BUILD_DHT_BOOTSTRAP_DAEMON" = "xyes"; then PKG_CHECK_MODULES([LIBCONFIG], [libconfig >= 1.4.6], [ LIBCONFIG_FOUND="yes" ], [ AC_MSG_WARN([$LIBCONFIG_PKG_ERRORS]) AC_MSG_WARN([libconfig not available, will not build DHT bootstrap daemon]) BUILD_DHT_BOOTSTRAP_DAEMON="no" ]) fi else AC_MSG_WARN([pkg-config was not found on your system, will search for libraries manually]) fi if (test "x$BUILD_DHT_BOOTSTRAP_DAEMON" = "xyes") && \ (test "x$LIBCONFIG_FOUND" = "xno"); then AC_CHECK_HEADER(libconfig.h, [], [ AC_MSG_WARN([header files for library libconfig was not found on your system, not building DHT bootstrap daemon]) BUILD_DHT_BOOTSTRAP_DAEMON="no" ] ) if test "x$BUILD_DHT_BOOTSTRAP_DAEMON" = "xyes"; then AC_CHECK_LIB(config, config_read, [], [ AC_MSG_WARN([library libconfig was not found on the system]) BUILD_DHT_BOOTSTRAP_DAEMON="no" ] ) fi fi if test "x$WIN32" = "xyes"; then AC_CHECK_LIB(ws2_32, main, [ WINSOCK2_LIBS="-liphlpapi -lws2_32" AC_SUBST(WINSOCK2_LIBS) ], [ AC_MSG_ERROR([required library was not found on the system, please check your MinGW installation]) ] ) fi AM_CONDITIONAL(BUILD_DHT_BOOTSTRAP_DAEMON, test "x$BUILD_DHT_BOOTSTRAP_DAEMON" = "xyes") AM_CONDITIONAL(BUILD_DHT_BOOTSTRAP, test "x$BUILD_DHT_BOOTSTRAP" = "xyes") AM_CONDITIONAL(BUILD_TESTS, test "x$BUILD_TESTS" = "xyes") AM_CONDITIONAL(BUILD_AV, test "x$BUILD_AV" = "xyes") AM_CONDITIONAL(BUILD_TESTING, test "x$BUILD_TESTING" = "xyes") AM_CONDITIONAL(WITH_NACL, test "x$WANT_NACL" = "xyes") AM_CONDITIONAL(WIN32, test "x$WIN32" = "xyes") AC_CONFIG_FILES([Makefile build/Makefile libtoxcore.pc tox.spec ]) AM_COND_IF(BUILD_AV, [ AC_CONFIG_FILES([libtoxav.pc]) ],) AC_OUTPUT c-toxcore-0.2.18/docs/0000777000175000017500000000000014227324767013463 5ustar robinrobinc-toxcore-0.2.18/docs/apidsl.md0000777000175000017500000000322414227324767015265 0ustar robinrobinThis folder contains the input file (``tox.in.h``) that has to be used to generate the ``tox.h`` api with: https://github.com/TokTok/apidsl # Minimal requirements There are some minimal requirements to contribute to ``tox.h``: * unix environment * ``astyle`` ``>=2.03`` * [``apidsl``](https://github.com/TokTok/apidsl) (you can use provided service with curl instead) ## Quick way If you want to do it quickly and you don't have time for anything other than copypasting commands, you should have ``curl`` installed. 1. Make sure that you have ``curl`` and ``>=astyle-2.03`` installed 2. Modify [``tox.api.h``](/toxcore/tox.api.h) 3. Run command below ↓ Command to run from ``toxcore`` directory (quick way, involves using curl): ```bash # For tox.h: curl -X POST --data-binary @- https://apidsl.herokuapp.com/apidsl \ < toxcore/tox.api.h \ | astyle --options=other/astyle/astylerc \ > toxcore/tox.h # For toxav.h: curl -X POST --data-binary @- https://apidsl.herokuapp.com/apidsl \ < toxav/toxav.api.h \ | astyle --options=other/astyle/astylerc \ > toxav/toxav.h ``` You may want to make sure with ``git diff`` that changes made in ``tox.h`` reflect changes in ``tox.in.h``. And you're done. ## Manually If you prefer to have more control over what is happening, there are steps below: 1. Install [``apidsl``](https://github.com/TokTok/apidsl) 2. Install ``astyle``, version 2.03 or later. 3. Modify [``tox.api.h``](/toxcore/tox.api.h) 4. Use ``apidsl`` ``??`` 5. Parse generated ``tox.h`` with astyle, minimal command for it would be: ```bash astyle --options=other/astyle/astylerc toxcore/tox.h ``` **Always pass output from ``apidsl`` through astyle.** c-toxcore-0.2.18/docs/av_api.md0000777000175000017500000001614414227324767015255 0ustar robinrobin# A/V API reference ## Take toxmsi/phone.c as a reference ### Initialization: ``` phone_t* initPhone(uint16_t _listen_port, uint16_t _send_port); ``` function initializes sample phone. _listen_port and _send_port are variables only meant for local testing. You will not have to do anything regarding to that since everything will be started within a messenger. Phone requires one msi session and two rtp sessions ( one for audio and one for video ). ``` msi_session_t* msi_init_session( void* _core_handler, const uint8_t* _user_agent ); ``` initializes msi session. Params: ``` void* _core_handler - pointer to an object handling networking, const uint8_t* _user_agent - string describing phone client version. ``` Return value: msi_session_t* - pointer to a newly created msi session handler. ### msi_session_t reference: How to handle msi session: Controlling is done via callbacks and action handlers. First register callbacks for every state/action received and make sure NOT TO PLACE SOMETHING LIKE LOOPS THAT TAKES A LOT OF TIME TO EXECUTE; every callback is being called directly from event loop. You can find examples in phone.c. Register callbacks: ``` void msi_register_callback_call_started ( MCALLBACK ); void msi_register_callback_call_canceled ( MCALLBACK ); void msi_register_callback_call_rejected ( MCALLBACK ); void msi_register_callback_call_ended ( MCALLBACK ); void msi_register_callback_recv_invite ( MCALLBACK ); void msi_register_callback_recv_ringing ( MCALLBACK ); void msi_register_callback_recv_starting ( MCALLBACK ); void msi_register_callback_recv_ending ( MCALLBACK ); void msi_register_callback_recv_error ( MCALLBACK ); void msi_register_callback_requ_timeout ( MCALLBACK ); ``` MCALLBACK is defined as: void (*callback) (void* _arg) msi_session_t* handler is being thrown as \_arg so you can use that and \_agent_handler to get to your own phone handler directly from callback. Actions: ``` int msi_invite ( msi_session_t* _session, call_type _call_type, uint32_t _timeoutms ); ``` Sends call invite. Before calling/sending invite msi_session_t::_friend_id is needed to be set or else it will not work. _call_type is type of the call ( Audio/Video ) and _timeoutms is how long will poll wait until request is terminated. ``` int msi_hangup ( msi_session_t* _session ); ``` Hangs up active call ``` int msi_answer ( msi_session_t* _session, call_type _call_type ); ``` Answer incoming call. _call_type set's callee call type. ``` int msi_cancel ( msi_session_t* _session ); ``` Cancel current request. ``` int msi_reject ( msi_session_t* _session ); ``` Reject incoming call. ### Now for rtp: You will need 2 sessions; one for audio one for video. You start them with: ``` rtp_session_t* rtp_init_session ( int _max_users, int _multi_session ); ``` Params: ``` int _max_users - max users. -1 if undefined int _multi_session - any positive number means uses multi session; -1 if not. ``` Return value: ``` rtp_session_t* - pointer to a newly created rtp session handler. ``` ### How to handle rtp session: Take a look at ``` void* phone_handle_media_transport_poll ( void* _hmtc_args_p ) in phone.c ``` on example. Basically what you do is just receive a message via: ``` struct rtp_msg_s* rtp_recv_msg ( rtp_session_t* _session ); ``` and then you use payload within the rtp_msg_s struct. Don't forget to deallocate it with: void rtp_free_msg ( rtp_session_t* _session, struct rtp_msg_s* _msg ); Receiving should be thread safe so don't worry about that. When you capture and encode a payload you want to send it ( obviously ). first create a new message with: ``` struct rtp_msg_s* rtp_msg_new ( rtp_session_t* _session, const uint8_t* _data, uint32_t _length ); ``` and then send it with: ``` int rtp_send_msg ( rtp_session_t* _session, struct rtp_msg_s* _msg, void* _core_handler ); ``` _core_handler is the same network handler as in msi_session_s struct. ## A/V initialization: ``` int init_receive_audio(codec_state *cs); int init_receive_video(codec_state *cs); Initialises the A/V decoders. On failure it will print the reason and return 0. On success it will return 1. int init_send_audio(codec_state *cs); int init_send_video(codec_state *cs); Initialises the A/V encoders. On failure it will print the reason and return 0. On success it will return 1. init_send_audio will also let the user select an input device. init_send_video will determine the webcam's output codec and initialise the appropriate decoder. int video_encoder_refresh(codec_state *cs, int bps); Reinitialises the video encoder with a new bitrate. ffmpeg does not expose the needed VP8 feature to change the bitrate on the fly, so this serves as a workaround. In the future, VP8 should be used directly and ffmpeg should be dropped from the dependencies. The variable bps is the required bitrate in bits per second. ``` ### A/V encoding/decoding: ``` void *encode_video_thread(void *arg); ``` Spawns the video encoding thread. The argument should hold a pointer to a codec_state. This function should only be called if video encoding is supported (when init_send_video returns 1). Each video frame gets encoded into a packet, which is sent via RTP. Every 60 frames a new bidirectional interframe is encoded. ``` void *encode_audio_thread(void *arg); ``` Spawns the audio encoding thread. The argument should hold a pointer to a codec_state. This function should only be called if audio encoding is supported (when init_send_audio returns 1). Audio frames are read from the selected audio capture device during initialisation. This audio capturing can be rerouted to a different device on the fly. Each audio frame is encoded into a packet, and sent via RTP. All audio frames have the same amount of samples, which is defined in AV_codec.h. ``` int video_decoder_refresh(codec_state *cs, int width, int height); ``` Sets the SDL window dimensions and creates a pixel buffer with the requested size. It also creates a scaling context, which will be used to convert the input image format to YUV420P. ``` void *decode_video_thread(void *arg); ``` Spawns a video decoding thread. The argument should hold a pointer to a codec_state. The codec_state is assumed to contain a successfully initialised video decoder. This function reads video packets and feeds them to the video decoder. If the video frame's resolution has changed, video_decoder_refresh() is called. Afterwards, the frame is displayed on the SDL window. ``` void *decode_audio_thread(void *arg); ``` Spawns an audio decoding thread. The argument should hold a pointer to a codec_state. The codec_state is assumed to contain a successfully initialised audio decoder. All received audio packets are pushed into a jitter buffer and are reordered. If there is a missing packet, or a packet has arrived too late, it is treated as a lost packet and the audio decoder is informed of the packet loss. The audio decoder will then try to reconstruct the lost packet, based on information from previous packets. Audio is played on the default OpenAL output device. If you have any more qustions/bug reports/feature request contact the following users on the irc channel #tox-dev on irc.freenode.net: For RTP and MSI: mannol For audio and video: Martijnvdc c-toxcore-0.2.18/docs/Doxyfile0000777000175000017500000034273614227324767015213 0ustar robinrobin# Doxyfile 1.9.2 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the configuration # file that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # https://www.gnu.org/software/libiconv/ for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = "Tox Protocol Reference Implementation" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "The future of online communications" # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = _docs # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. # The default value is: NO. CREATE_SUBDIRS = NO # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode # U+3044. # The default value is: NO. ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, # Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), # Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, # Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, # Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, # Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, # Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. # The default value is: YES. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found # as the leading text of the brief description, will be stripped from the text # and the result, after processing the whole list, is used as the annotated # text. Otherwise, the brief description is used as-is. If left blank, the # following values are used ($name is automatically replaced with the name of # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = YES # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which # header file to include in order to use a class. If left blank only the name of # the header file containing the class definition is used. Otherwise one should # specify the list of include paths that are normally passed to the compiler # using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = NO # If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line # such as # /*************** # as being the beginning of a Javadoc-style comment "banner". If set to NO, the # Javadoc-style will behave just like regular comments and it will not be # interpreted by doxygen. # The default value is: NO. JAVADOC_BANNER = NO # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this # tag to YES if you prefer the old behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # By default Python docstrings are displayed as preformatted text and doxygen's # special commands cannot be used. By setting PYTHON_DOCSTRING to NO the # doxygen's special commands can be used and the contents of the docstring # documentation blocks is shown as doxygen documentation. # The default value is: YES. PYTHON_DOCSTRING = YES # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new # page for each member. If set to NO, the documentation of a member will be part # of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: # name=value # For example adding # "sideeffect=@par Side Effects:^^" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". Note that you cannot put \n's in the value part of an alias # to insert newlines (in the resulting output). You can put ^^ in the value part # of an alias to insert a newline as if a physical newline was in the original # file. When you need a literal { or } or , in the value part of an alias you # have to escape them by means of a backslash (\), this can lead to conflicts # with the commands \{ and \} for these it is advised to use the version @{ and # @} or use a double escape (\\{ and \\}) ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice # sources only. Doxygen will then generate output that is more tailored for that # language. For instance, namespaces will be presented as modules, types will be # separated into more groups, etc. # The default value is: NO. OPTIMIZE_OUTPUT_SLICE = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, JavaScript, # Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, # VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: # FortranFree, unknown formatted Fortran: Fortran. In the later case the parser # tries to guess whether the code is fixed or free formatted code, this is the # default for Fortran type files). For instance to make doxygen treat .inc files # as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. When specifying no_extension you should add # * to the FILE_PATTERNS. # # Note see also the list of default file extension mappings. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See https://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. # Minimum value: 0, maximum value: 99, default value: 5. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 5 # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = NO # If one adds a struct or class to a group and this option is enabled, then also # any nested class or struct is added to the same group. By default this option # is disabled and one has to add nested compounds explicitly via \ingroup. # The default value is: NO. GROUP_NESTED_COMPOUNDS = NO # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 # The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use # during processing. When set to 0 doxygen will based this on the number of # cores available in the system. You can set it explicitly to a value larger # than 0 to get more control over the balance between CPU load and processing # speed. At this moment only the input processing can be done using multiple # threads. Since this is still an experimental feature the default is set to 1, # which effectively disables parallel processing. Please report any issues you # encounter. Generating dot graphs in parallel is controlled by the # DOT_NUM_THREADS setting. # Minimum value: 0, maximum value: 32, default value: 1. NUM_PROC_THREADS = 1 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual # methods of a class will be included in the documentation. # The default value is: NO. EXTRACT_PRIV_VIRTUAL = NO # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are # included in the documentation. If set to NO, only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If this flag is set to YES, the name of an unnamed parameter in a declaration # will be determined by the corresponding definition. By default unnamed # parameters remain unnamed in the output. # The default value is: YES. RESOLVE_UNNAMED_PARAMS = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option # has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # declarations. If set to NO, these declarations will be included in the # documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. INTERNAL_DOCS = NO # With the correct setting of option CASE_SENSE_NAMES doxygen will better be # able to match the capabilities of the underlying filesystem. In case the # filesystem is case sensitive (i.e. it supports files in the same directory # whose names only differ in casing), the option must be set to YES to properly # deal with such files in case they appear in the input. For filesystems that # are not case sensitive the option should be be set to NO to properly deal with # output files written for symbols that only differ in casing, such as for two # classes, one named CLASS and the other named Class, and to also support # references to files without having to specify the exact matching casing. On # Windows (including Cygwin) and MacOS, users should typically set this option # to NO, whereas on Linux or other Unix flavors it should typically be set to # YES. # The default value is: system dependent. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will # append additional text to a page's title, such as Class Reference. If set to # YES the compound reference will be hidden. # The default value is: NO. HIDE_COMPOUND_REFERENCE= NO # If the SHOW_HEADERFILE tag is set to YES then the documentation for a class # will show which file needs to be included to use the class. # The default value is: YES. SHOW_HEADERFILE = YES # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader # which file to include in order to use the member. # The default value is: NO. SHOW_GROUPED_MEMB_INC = NO # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will # be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the alphabetical # list. # The default value is: NO. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo # list. This list is created by putting \todo commands in the documentation. # The default value is: YES. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test # list. This list is created by putting \test commands in the documentation. # The default value is: YES. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the # documentation. If the initializer consists of more lines than specified here # it will be hidden. Use a value of 0 to hide initializers completely. The # appearance of the value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES, the # list will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. See also section "Changing the # layout of pages" for information. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = NO # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as documenting some parameters in # a documented function twice, or documenting parameters that don't exist or # using markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES # If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete # function parameter documentation. If set to NO, doxygen will accept that some # parameters have no documentation without warning. # The default value is: YES. WARN_IF_INCOMPLETE_DOC = NO # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO, doxygen will only warn about wrong parameter # documentation, but not about the absence of documentation. If EXTRACT_ALL is # set to YES then this flag will automatically be disabled. See also # WARN_IF_INCOMPLETE_DOC # The default value is: NO. WARN_NO_PARAMDOC = NO # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when # a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS # then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but # at the end of the doxygen process doxygen will return with a non-zero status. # Possible values are: NO, YES and FAIL_ON_WARNINGS. # The default value is: NO. WARN_AS_ERROR = NO # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. INPUT = toxav toxcore toxencryptsave # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: # https://www.gnu.org/software/libiconv/) for the list of possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # # Note the list of default checked file patterns might differ from the list of # default file extension mappings. # # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, # *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, # *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C # comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, # *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.idl \ *.ddl \ *.odl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.l \ *.cs \ *.d \ *.php \ *.php4 \ *.php5 \ *.phtml \ *.inc \ *.m \ *.markdown \ *.md \ *.mm \ *.dox \ *.py \ *.pyw \ *.f90 \ *.f95 \ *.f03 \ *.f08 \ *.f18 \ *.f \ *.for \ *.vhd \ *.vhdl \ *.ucf \ *.qsf \ *.ice # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # # # where is the value of the INPUT_FILTER tag, and is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: pattern=filter # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # entity all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see https://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. # The default value is: YES. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = YES # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefore more robust against future updates. # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = doxygen-awesome-css/doxygen-awesome.css # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a color-wheel, see # https://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use gray-scales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to YES can help to show when doxygen was last run and thus if the # documentation is up to date. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML # documentation will contain a main index with vertical navigation menus that # are dynamically created via JavaScript. If disabled, the navigation index will # consists of multiple levels of tabs that are statically embedded in every HTML # page. Disable this option to support browsers that do not have JavaScript, # like the Qt help browser. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_MENUS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: # https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To # create a documentation set, doxygen will generate a Makefile in the HTML # output directory. Running make will produce the docset in that directory and # running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy # genXcode/_index.html for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # on Windows. In the beginning of 2021 Microsoft took the original page, with # a.o. the download links, offline the HTML help workshop was already many years # in maintenance mode). You can download the HTML help workshop from the web # archives at Installation executable (see: # http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo # ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler (hhc.exe). If non-empty, # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated # (YES) or that it should be included in the main .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated # (YES) or a normal table of contents (NO) in the .chm file. Furthermore it # enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location (absolute path # including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to # run qhelpgenerator on the generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value is set to YES, a side panel will be generated containing a tree-like # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine tune the look of the index (see "Fine-tuning the output"). As an # example, the default style sheet generated by doxygen has an example that # shows how to put an image at the root of the tree instead of the PROJECT_NAME. # Since the tree basically has the same information as the tab index, you could # consider setting DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO # When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the # FULL_SIDEBAR option determines if the side bar is limited to only the treeview # area (value NO) or if it should extend to the full height of the window (value # YES). Setting this to YES gives a layout similar to # https://docs.readthedocs.io with more room for contents, but less room for the # project logo, title, and description. If either GENERATOR_TREEVIEW or # DISABLE_INDEX is set to NO, this option has no effect. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. FULL_SIDEBAR = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 # If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg # tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see # https://inkscape.org) to generate formulas as SVG images instead of PNGs for # the HTML output. These images will generally look nicer at scaled resolutions. # Possible values are: png (the default) and svg (looks nicer but requires the # pdf2svg or inkscape tool). # The default value is: png. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FORMULA_FORMAT = png # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. 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 # to create new LaTeX commands to be used in formulas as building blocks. See # the section "Including formulas" for details. FORMULA_MACROFILE = # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # https://www.mathjax.org) which uses client side JavaScript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO # With MATHJAX_VERSION it is possible to specify the MathJax version to be used. # Note that the different versions of MathJax have different requirements with # regards to the different settings, so it is possible that also other MathJax # settings have to be changed when switching between the different MathJax # versions. # Possible values are: MathJax_2 and MathJax_3. # The default value is: MathJax_2. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_VERSION = MathJax_2 # When MathJax is enabled you can set the default output format to be used for # the MathJax output. For more details about the output format see MathJax # version 2 (see: # http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 # (see: # http://docs.mathjax.org/en/latest/web/components/output.html). # Possible values are: HTML-CSS (which is slower, but has the best # compatibility. This is the name for Mathjax version 2, for MathJax version 3 # this will be translated into chtml), NativeMML (i.e. MathML. Only supported # for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This # is the name for Mathjax version 3, for MathJax version 2 this will be # translated into HTML-CSS) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from https://www.mathjax.org before deployment. The default value is: # - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 # - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # for MathJax version 2 (see # https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # For example for MathJax version 3 (see # http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): # MATHJAX_EXTENSIONS = ams # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: # http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically # , /