From 3105cc20ef3173b87fdc1688962ed6318a1fd039 Mon Sep 17 00:00:00 2001 From: Green Sky Date: Wed, 12 Mar 2025 19:16:50 +0100 Subject: [PATCH] Squashed 'external/toxcore/c-toxcore/' changes from d9b8fa6098d..81b1e4f6348 81b1e4f6348 chore: Release v0.2.21-rc.1 9303e2e49a1 chore: Update the pkgsrc versions in the update-versions tool 71ec4b3b1e9 chore: Update the version-sync script to work in a post-tox.api.h world 66da842f753 chore: Add version update script compatible with ci-tools. 199878f7660 chore: Use new bazel script for circle ci. 8278e9cda46 chore: Add release issue template and workflow. a9bb3a1c4d1 chore: Fix alpine-s390x build. 6e0a641272e chore: Add a source tarball deploy workflow. 4adebe4d8b1 chore: Don't upload ios/macos variants in deploy workflows. 18f1d858ccb chore: Move one of the 3 freebsd builds to post-submit. 432ab60c002 feat: Add a Makefile for the single file deploy build. a86c0011fd5 chore: Add deploy job for single C file library. 2e7495e8f2a docs: Update changelog format to use the new clog-compatible way. a682da99e84 chore: Export wasmExports from the wasm binary. 12f34cdff27 chore: Add wasm to the nightly binary deploys. 1451029613f chore: Add strict-abi support for macOS/iOS. c53c30e09d9 chore: Add time option to manual fuzz trigger. 2ccecdc2a1a chore: Add remaining fuzz tests to cflite. 4626c2e230e test: Add a Net_Crypto fuzz test. b4a0e617c48 refactor: Use IP string length from ip_ntoa instead of strlen. b85b91f22f6 cleanup: rename getnodes/sendnodes to nodes request/response This change alignes the naming to be closer to the spec and make it less ambiguous. This change also changes the naming of some private/experimental marked APIs. - tox_callback_dht_nodes_response() - tox_dht_nodes_request() - Tox_Event_Dht_Get_Nodes_Response f1991aaa029 perf: Use stack allocation for strerror rendering. 3984211ccbf cleanup: remove kicked peers from saved peers list 26a991ed2be fix: ip to string function not accepting tcp families 712861f2e6d cleanup: Make websockify output qtox-compatible logging. 01932ea2f73 chore: Add opus and vpx to the toxcore wasm build. d29c42ef631 refactor: don't fully discard received DHT nodes. This is mostly forward thinking, where we might introduce other ip families, in addition to ipv4, ipv6, tcp_ipv4 etc. 21e2325934f chore: Fix xcframework tarball creation. b10c8b766ba chore: Fix xcframework checksum creation. 93787a9322e chore: Add ios/macos framework build. 9f723f891d3 fix: run do_gca also in bootstrap nodes 496cc703556 chore: Support arm64 iphone simulator. aa0e2a8e928 chore: Add support for more iOS architectures. 13ad8e81cbf chore: Add binary deploy workflows. c8344726378 refactor: Move tox_log_level out into its own file. 8799bea76c3 cleanup: Mark events/dispatch headers as experimental. d4164edb548 refactor: Remove tox_types.h; use `struct` tags instead. d408c982090 refactor: Move `Tox_Options` to `tox_options.h`. 5ab42d41209 chore: Move most cirrus jobs to circleci. 463eeae1144 cleanup: Avoid clashing with global define `DEBUG`. 92cc1e91747 refactor: Make Tox_Options own the passed proxy host and savedata. f276b397226 test: Add some more asserts for I/O and alloc to succeed. edb4dfc4869 fix: Don't crash on malloc failures in bin_unpack. be457d5d0b2 cleanup: Use tox memory for bin_unpack and net_strerror. git-subtree-dir: external/toxcore/c-toxcore git-subtree-split: 81b1e4f6348124784088591c4fe9ab41e273031d --- .circleci/bazel-test | 12 - .circleci/config.yml | 53 +- .cirrus.yml | 72 +-- .clog.toml | 3 + .clusterfuzzlite/Dockerfile | 22 +- .clusterfuzzlite/build.sh | 15 +- .github/ISSUE_TEMPLATE/release.yml | 24 + .github/scripts/cmake-android | 65 --- .github/scripts/cmake-osx | 1 - .github/scripts/flags-clang.sh | 2 + .github/workflows/cflite_batch.yml | 12 +- .github/workflows/cflite_cron.yml | 3 +- .github/workflows/cflite_pr.yml | 36 ++ .github/workflows/ci.yml | 17 +- .github/workflows/deploy.yml | 358 ++++++++++++++ .github/workflows/docker.yml | 20 - .github/workflows/draft.yml | 17 + .github/workflows/post-submit.yml | 10 +- .github/workflows/release.yml | 18 +- .reviewable/completion.js | 76 +++ .reviewable/settings.yaml | 4 + BUILD.bazel | 6 + CHANGELOG.md | 346 +++++++++++-- CMakeLists.txt | 16 +- auto_tests/CMakeLists.txt | 2 +- auto_tests/TCP_test.c | 22 +- ...i_test.c => dht_nodes_response_api_test.c} | 19 +- auto_tests/file_saving_test.c | 25 +- auto_tests/network_test.c | 15 +- auto_tests/proxy_test.c | 6 +- cmake/StrictAbi.cmake | 38 +- configure.ac | 2 +- other/DHT_bootstrap.c | 2 + .../docker/tox-bootstrapd.sha256 | 2 +- other/bootstrap_daemon/src/tox-bootstrapd.c | 2 + .../websocket/websockify/go.sum | 3 + .../websocket/websockify/websockify.go | 59 ++- other/deploy/android.sh | 102 ++++ other/deploy/apple/.gitignore | 5 + other/deploy/apple/Info.plist | 28 ++ other/deploy/apple/LICENSE | 1 + other/deploy/apple/download-nightly.sh | 29 ++ other/deploy/apple/make-framework.sh | 71 +++ other/deploy/apple/toxcore.podspec | 24 + other/deploy/deps.sh | 30 ++ other/deploy/ios.sh | 58 +++ other/deploy/linux.sh | 29 ++ other/deploy/macos.sh | 37 ++ other/deploy/single-file/.gitignore | 1 + other/deploy/single-file/Makefile | 26 + .../{ => deploy/single-file}/make_single_file | 15 +- .../{Dockerfile => alpine-s390x.Dockerfile} | 0 .../alpine-s390x.Dockerfile.dockerignore | 24 + other/docker/alpine-s390x/dockerignore | 1 + other/docker/alpine-s390x/run | 6 +- other/docker/cppcheck/toxcore.cfg | 4 - other/docker/goblint/goblint.Dockerfile | 4 +- other/docker/goblint/sodium.c | 11 + other/docker/modules/check | 36 +- other/docker/modules/dockerignore | 2 + other/docker/modules/modules.Dockerfile | 5 +- .../modules/modules.Dockerfile.dockerignore | 25 + other/docker/modules/run | 7 +- other/docker/pkgsrc/dockerignore | 1 + other/docker/pkgsrc/pkgsrc.Dockerfile | 11 +- .../pkgsrc/pkgsrc.Dockerfile.dockerignore | 1 + other/docker/pkgsrc/pkgsrc.patch | 31 ++ other/docker/sparse/sparse.Dockerfile | 4 +- other/docker/tcc/tcc.Dockerfile | 6 +- other/docker/wasm/run | 3 + other/docker/wasm/wasm.Dockerfile | 136 ++++++ .../docker/wasm/wasm.Dockerfile.dockerignore | 23 + other/emscripten/Dockerfile | 85 ---- other/emscripten/build | 3 - other/proxy/proxy_server.go | 4 +- other/version-sync | 44 +- so.version | 4 +- testing/fuzzing/CMakeLists.txt | 5 +- testing/fuzzing/bootstrap_fuzz_test.cc | 8 +- testing/fuzzing/e2e_fuzz_test.cc | 3 +- testing/fuzzing/fuzz_support.cc | 53 +- testing/fuzzing/fuzz_support.hh | 54 ++- testing/fuzzing/protodump.cc | 40 +- testing/fuzzing/protodump_reduce.cc | 2 +- testing/fuzzing/rebuild_protodump | 6 +- testing/fuzzing/toxsave_fuzz_test.cc | 2 + third_party/.gitignore | 3 +- tools/update-versions.sh | 15 + toxav/rtp.c | 22 +- toxav/rtp.h | 3 +- toxav/toxav.c | 12 +- toxcore/BUILD.bazel | 44 ++ toxcore/DHT.c | 98 ++-- toxcore/DHT.h | 16 +- toxcore/Makefile.inc | 185 +++---- toxcore/Messenger.c | 2 +- toxcore/TCP_common.c | 4 +- toxcore/TCP_server.c | 9 +- toxcore/bin_pack_test.cc | 17 +- toxcore/bin_unpack.c | 19 +- toxcore/bin_unpack.h | 3 +- toxcore/events/dht_get_nodes_response.c | 227 --------- toxcore/events/dht_nodes_response.c | 222 +++++++++ toxcore/events/events_alloc.h | 2 +- toxcore/forwarding_fuzz_test.cc | 24 +- toxcore/group_chats.c | 30 +- toxcore/net_crypto.h | 8 + toxcore/net_crypto_fuzz_test.cc | 93 ++++ toxcore/net_profile.c | 2 +- toxcore/net_profile.h | 2 +- toxcore/network.c | 100 ++-- toxcore/network.h | 49 +- toxcore/onion_client.c | 3 +- toxcore/tox.c | 16 +- toxcore/tox.h | 443 +---------------- toxcore/tox_api.c | 228 +-------- toxcore/tox_dispatch.c | 12 +- toxcore/tox_dispatch.h | 8 +- toxcore/tox_event.c | 8 +- toxcore/tox_event.h | 10 +- toxcore/tox_events.c | 6 +- toxcore/tox_events.h | 20 +- toxcore/tox_log_level.c | 27 ++ toxcore/tox_log_level.h | 58 +++ toxcore/tox_options.c | 285 +++++++++++ toxcore/tox_options.h | 455 ++++++++++++++++++ toxcore/tox_private.c | 26 +- toxcore/tox_private.h | 40 +- toxcore/tox_struct.h | 7 +- toxcore/tox_test.cc | 2 + 130 files changed, 3604 insertions(+), 1776 deletions(-) delete mode 100755 .circleci/bazel-test create mode 100644 .clog.toml create mode 100644 .github/ISSUE_TEMPLATE/release.yml delete mode 100755 .github/scripts/cmake-android create mode 100644 .github/workflows/cflite_pr.yml create mode 100644 .github/workflows/deploy.yml create mode 100644 .github/workflows/draft.yml create mode 100644 .reviewable/completion.js create mode 100644 .reviewable/settings.yaml rename auto_tests/{dht_getnodes_api_test.c => dht_nodes_response_api_test.c} (84%) create mode 100755 other/deploy/android.sh create mode 100644 other/deploy/apple/.gitignore create mode 100644 other/deploy/apple/Info.plist create mode 120000 other/deploy/apple/LICENSE create mode 100755 other/deploy/apple/download-nightly.sh create mode 100755 other/deploy/apple/make-framework.sh create mode 100644 other/deploy/apple/toxcore.podspec create mode 100755 other/deploy/deps.sh create mode 100755 other/deploy/ios.sh create mode 100755 other/deploy/linux.sh create mode 100755 other/deploy/macos.sh create mode 100644 other/deploy/single-file/.gitignore create mode 100644 other/deploy/single-file/Makefile rename other/{ => deploy/single-file}/make_single_file (66%) rename other/docker/alpine-s390x/{Dockerfile => alpine-s390x.Dockerfile} (100%) create mode 100644 other/docker/alpine-s390x/alpine-s390x.Dockerfile.dockerignore create mode 100644 other/docker/alpine-s390x/dockerignore create mode 100644 other/docker/modules/dockerignore create mode 100644 other/docker/modules/modules.Dockerfile.dockerignore create mode 100644 other/docker/pkgsrc/dockerignore create mode 100644 other/docker/pkgsrc/pkgsrc.patch create mode 100755 other/docker/wasm/run create mode 100644 other/docker/wasm/wasm.Dockerfile create mode 100644 other/docker/wasm/wasm.Dockerfile.dockerignore delete mode 100644 other/emscripten/Dockerfile delete mode 100755 other/emscripten/build create mode 100755 tools/update-versions.sh delete mode 100644 toxcore/events/dht_get_nodes_response.c create mode 100644 toxcore/events/dht_nodes_response.c create mode 100644 toxcore/net_crypto_fuzz_test.cc create mode 100644 toxcore/tox_log_level.c create mode 100644 toxcore/tox_log_level.h create mode 100644 toxcore/tox_options.c create mode 100644 toxcore/tox_options.h diff --git a/.circleci/bazel-test b/.circleci/bazel-test deleted file mode 100755 index b44119f..0000000 --- a/.circleci/bazel-test +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -set -eux - -git submodule update --init --recursive -/src/workspace/tools/inject-repo c-toxcore -# TODO(iphydf): Re-enable fuzz-test when https://github.com/tweag/rules_nixpkgs/issues/442 is fixed. -cd /src/workspace && bazel test -k \ - --build_tag_filters=-haskell,-fuzz-test \ - --test_tag_filters=-haskell,-fuzz-test \ - -- \ - "$@" diff --git a/.circleci/config.yml b/.circleci/config.yml index 264139a..2b64161 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,11 +6,13 @@ workflows: circleci: jobs: - bazel-asan - - bazel-dbg - - bazel-opt + - bazel-debug + - bazel-msan + - bazel-release - clang-analyze - cpplint - static-analysis + - cimple - cimplefmt - generate-events @@ -18,31 +20,45 @@ jobs: bazel-asan: working_directory: /tmp/cirrus-ci-build docker: - - image: toxchat/toktok-stack:latest-asan + - image: toxchat/toktok-stack:latest steps: - checkout - - run: .circleci/bazel-test + - run: bash <(curl -s https://raw.githubusercontent.com/TokTok/ci-tools/refs/heads/master/tools/circleci-bazel-test) + --build_tag_filters=-haskell,-fuzz-test + --test_tag_filters=-haskell,-fuzz-test //c-toxcore/... - bazel-dbg: + bazel-debug: working_directory: /tmp/cirrus-ci-build docker: - - image: toxchat/toktok-stack:latest-debug + - image: toxchat/toktok-stack:latest steps: - checkout - - run: .circleci/bazel-test + - run: bash <(curl -s https://raw.githubusercontent.com/TokTok/ci-tools/refs/heads/master/tools/circleci-bazel-test) + --build_tag_filters=-haskell + --test_tag_filters=-haskell //c-toxcore/... - bazel-opt: + bazel-msan: working_directory: /tmp/cirrus-ci-build docker: - - image: toxchat/toktok-stack:latest-release + - image: toxchat/toktok-stack:latest steps: - checkout - - run: .circleci/bazel-test + - run: bash <(curl -s https://raw.githubusercontent.com/TokTok/ci-tools/refs/heads/master/tools/circleci-bazel-test) + //c-toxcore/auto_tests:lossless_packet_test + + bazel-release: + working_directory: /tmp/cirrus-ci-build + docker: + - image: toxchat/toktok-stack:latest + + steps: + - checkout + - run: bash <(curl -s https://raw.githubusercontent.com/TokTok/ci-tools/refs/heads/master/tools/circleci-bazel-test) //c-toxcore/... static-analysis: @@ -106,6 +122,23 @@ jobs: - run: git submodule update --init --recursive - run: other/analysis/run-cpplint + cimple: + working_directory: /tmp/cirrus-ci-build + docker: + - image: toxchat/toktok-stack:latest-release + + steps: + - checkout + - run: git submodule update --init --recursive + - run: /src/workspace/tools/inject-repo c-toxcore + - run: cd /src/workspace && + bazel test + -k + --build_tag_filters=haskell + --test_tag_filters=haskell + -- + //c-toxcore/... + cimplefmt: working_directory: ~/work machine: { image: ubuntu-2204:current } diff --git a/.cirrus.yml b/.cirrus.yml index d434f09..e772275 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,76 +1,8 @@ --- -bazel-opt_task: - timeout_in: 10m - container: - image: toxchat/toktok-stack:latest-release - cpu: 8 - memory: 2G - configure_script: - - git submodule update --init --recursive - - /src/workspace/tools/inject-repo c-toxcore - test_all_script: - - cd /src/workspace && tools/retry 5 bazel - test -k - --build_tag_filters=-haskell - --test_tag_filters=-haskell - -- - //c-toxcore/... - -//c-toxcore/auto_tests:tcp_relay_test # Cirrus doesn't allow external network connections. - -bazel-dbg_task: - timeout_in: 10m - container: - image: toxchat/toktok-stack:latest-debug - cpu: 8 - memory: 2G - configure_script: - - git submodule update --init --recursive - - /src/workspace/tools/inject-repo c-toxcore - test_all_script: - - cd /src/workspace && tools/retry 5 bazel - test -k - --build_tag_filters=-haskell - --test_tag_filters=-haskell - -- - //c-toxcore/... - -//c-toxcore/auto_tests:tcp_relay_test # Cirrus doesn't allow external network connections. - -bazel-msan_task: - timeout_in: 10m - container: - image: toxchat/toktok-stack:latest-msan - cpu: 4 - memory: 2G - configure_script: - - git submodule update --init --recursive - - /src/workspace/tools/inject-repo c-toxcore - test_all_script: - - cd /src/workspace && tools/retry 5 bazel - test -k - -- - //c-toxcore/auto_tests:lossless_packet_test - -cimple_task: - timeout_in: 5m - 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 - --build_tag_filters=haskell - --test_tag_filters=haskell - -- - //c-toxcore/... - freebsd_task: timeout_in: 5m freebsd_instance: - image_family: freebsd-14-1 + image_family: freebsd-14-2 configure_script: - PAGER=cat ASSUME_ALWAYS_YES=YES pkg install cmake @@ -87,7 +19,7 @@ freebsd_task: test_all_script: - | # TODO(iphydf): Investigate FreeBSD failures on these tests. - sed -Ei -e '/\(dht_getnodes_api\)/s/^/#/' auto_tests/CMakeLists.txt + sed -Ei -e '/\(dht_nodes_response_api\)/s/^/#/' auto_tests/CMakeLists.txt cmake . \ -DMIN_LOGGER_LEVEL=TRACE \ -DMUST_BUILD_TOXAV=ON \ diff --git a/.clog.toml b/.clog.toml new file mode 100644 index 0000000..3b3f535 --- /dev/null +++ b/.clog.toml @@ -0,0 +1,3 @@ +[clog] +repository = "https://github.com/TokTok/c-toxcore" +changelog = "CHANGELOG.md" diff --git a/.clusterfuzzlite/Dockerfile b/.clusterfuzzlite/Dockerfile index e563011..4fa7632 100644 --- a/.clusterfuzzlite/Dockerfile +++ b/.clusterfuzzlite/Dockerfile @@ -3,19 +3,23 @@ # 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/* +RUN apt-get update \ + && apt-get -y install --no-install-suggests --no-install-recommends \ + cmake \ + pkg-config \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] # 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 +RUN tar zxf <(curl -L https://github.com/jedisct1/libsodium/releases/download/1.0.20-RELEASE/libsodium-1.0.20.tar.gz) \ + && cd libsodium-* \ + && ./configure --enable-shared=no \ + && make install \ + && cd .. # Copy your project's source code. COPY . $SRC/c-toxcore diff --git a/.clusterfuzzlite/build.sh b/.clusterfuzzlite/build.sh index 59adb61..9496f15 100644 --- a/.clusterfuzzlite/build.sh +++ b/.clusterfuzzlite/build.sh @@ -1,6 +1,16 @@ #!/bin/bash -eu -FUZZ_TARGETS="bootstrap_fuzz_test toxsave_fuzz_test" +FUZZ_TARGETS=( + DHT_fuzz_test + bootstrap_fuzz_test + # e2e_fuzz_test + forwarding_fuzz_test + group_announce_fuzz_test + group_moderation_fuzz_test + net_crypto_fuzz_test + tox_events_fuzz_test + toxsave_fuzz_test +) # out of tree build cd "$WORK" @@ -12,11 +22,10 @@ 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 +for TARGET in "${FUZZ_TARGETS[@]}"; do # build fuzzer target cmake --build ./ --target "$TARGET" diff --git a/.github/ISSUE_TEMPLATE/release.yml b/.github/ISSUE_TEMPLATE/release.yml new file mode 100644 index 0000000..f484963 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release.yml @@ -0,0 +1,24 @@ +name: 🚀 Release +description: Build and deploy a new release +title: Release tracking issue +labels: [chore] +type: Task +body: + - type: textarea + id: release-notes + attributes: + label: Release notes + description: Write something nice about the new release. + placeholder: "Here's our latest awesome release!" + validations: + required: true + - type: dropdown + id: production + attributes: + label: Release type + description: Whether this is a production release or a release candidate. + options: + - Release candidate + - Production release + validations: + required: true diff --git a/.github/scripts/cmake-android b/.github/scripts/cmake-android deleted file mode 100755 index 95ec660..0000000 --- a/.github/scripts/cmake-android +++ /dev/null @@ -1,65 +0,0 @@ -#!/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=21 - ;; - arm64-v8a) - TARGET=aarch64-linux-android - NDK_API=21 - ;; - x86) - TARGET=i686-linux-android - NDK_API=21 - ;; - 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 --disable-pie -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 . diff --git a/.github/scripts/cmake-osx b/.github/scripts/cmake-osx index 1ee1e9b..7cf6ede 100755 --- a/.github/scripts/cmake-osx +++ b/.github/scripts/cmake-osx @@ -9,7 +9,6 @@ brew update brew install \ libconfig \ - libsodium \ libvpx \ opus diff --git a/.github/scripts/flags-clang.sh b/.github/scripts/flags-clang.sh index f0d9a11..02fbd76 100644 --- a/.github/scripts/flags-clang.sh +++ b/.github/scripts/flags-clang.sh @@ -69,6 +69,8 @@ add_cxx_flag -Wno-c99-extensions add_cxx_flag -Wno-old-style-cast # GTest does this. add_cxx_flag -Wno-global-constructors +# Needed for some fuzzers. +add_cxx_flag -Wno-exit-time-destructors # Downgrade to warning so we still see it. add_flag -Wno-error=unreachable-code diff --git a/.github/workflows/cflite_batch.yml b/.github/workflows/cflite_batch.yml index d853507..cfb39fd 100644 --- a/.github/workflows/cflite_batch.yml +++ b/.github/workflows/cflite_batch.yml @@ -1,11 +1,20 @@ # 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 + inputs: + fuzz-seconds: + description: 'Number of seconds to fuzz (total, not per test)' + required: false + type: number + default: 3600 + permissions: read-all + jobs: BatchFuzzing: runs-on: ubuntu-latest @@ -27,7 +36,8 @@ jobs: uses: google/clusterfuzzlite/actions/run_fuzzers@v1 with: github-token: ${{ secrets.GITHUB_TOKEN }} - fuzz-seconds: 3600 # 60min + # 1 hour on schedule, configurable on manual trigger. + fuzz-seconds: ${{ github.event.inputs.fuzz-seconds || 3600 }} mode: 'batch' sanitizer: ${{ matrix.sanitizer }} # Optional but recommended: For storing certain artifacts from fuzzing. diff --git a/.github/workflows/cflite_cron.yml b/.github/workflows/cflite_cron.yml index c127a67..c544a6d 100644 --- a/.github/workflows/cflite_cron.yml +++ b/.github/workflows/cflite_cron.yml @@ -7,6 +7,7 @@ on: workflow_dispatch: # Manual trigger for testing permissions: read-all + jobs: Pruning: runs-on: ubuntu-latest @@ -26,6 +27,7 @@ jobs: 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: @@ -47,4 +49,3 @@ jobs: 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". - diff --git a/.github/workflows/cflite_pr.yml b/.github/workflows/cflite_pr.yml new file mode 100644 index 0000000..f61644a --- /dev/null +++ b/.github/workflows/cflite_pr.yml @@ -0,0 +1,36 @@ +# Derived from: https://google.github.io/clusterfuzzlite/running-clusterfuzzlite/github-actions/ + +name: ClusterFuzzLite pull request fuzzing + +on: + pull_request: + types: [opened, synchronize] + +jobs: + Fuzzing: + 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: 300 # 5 mins (total time, not per test) + mode: 'code-change' + sanitizer: ${{ matrix.sanitizer }} + # Optional but recommended: For storing certain artifacts from fuzzing. + # See later section on "Git repo for storage". + storage-repo: https://github.com/TokTok/toktok-fuzzer.git + storage-repo-branch: master # Optional. Defaults to "main" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0b832d3..48df322 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: strategy: fail-fast: false matrix: - tool: [autotools, clang-tidy, compcert, cppcheck, doxygen, goblint, infer, freebsd, misra, modules, pkgsrc, rpm, slimcc, sparse, tcc, tokstyle] + tool: [autotools, clang-tidy, compcert, cppcheck, doxygen, goblint, infer, misra, modules, pkgsrc, rpm, slimcc, sparse, tcc, tokstyle] runs-on: ubuntu-22.04 steps: - name: Set up Docker Buildx @@ -60,17 +60,6 @@ jobs: - name: Build, test, and upload coverage run: other/docker/coverage/run - build-android: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - 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 - build-macos: runs-on: macos-latest steps: @@ -132,7 +121,7 @@ jobs: run: | # TODO(iphydf): Investigate NetBSD failures on these tests. - sed -Ei -e '/\((TCP|dht_getnodes_api)\)/s/^/#/' auto_tests/CMakeLists.txt + sed -Ei -e '/\((TCP|dht_nodes_response_api)\)/s/^/#/' auto_tests/CMakeLists.txt cmake . \ -DMIN_LOGGER_LEVEL=TRACE \ -DMUST_BUILD_TOXAV=ON \ @@ -171,7 +160,7 @@ jobs: run: | # TODO(iphydf): Investigate FreeBSD failures on these tests. - sed -Ei -e '/\(dht_getnodes_api\)/s/^/#/' auto_tests/CMakeLists.txt + sed -Ei -e '/\(dht_nodes_response_api\)/s/^/#/' auto_tests/CMakeLists.txt cmake . \ -DMIN_LOGGER_LEVEL=TRACE \ -DMUST_BUILD_TOXAV=ON \ diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..4ec1f54 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,358 @@ +name: deploy + +on: + # Allow manual trigger. + workflow_dispatch: + pull_request: + branches: ["master"] + push: + branches: ["master"] + tags: ["v*"] + +# Cancel old PR builds when pushing new commits. +concurrency: + group: deploy-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + + ################################################################################################ + # Preparation jobs + ################################################################################################ + + prepare: + name: Prepare + uses: TokTok/ci-tools/.github/workflows/deploy-prepare.yml@master + + ################################################################################################ + # Build and deploy jobs (PR and push) + ################################################################################################ + + build-linux: + name: Linux + needs: [prepare] + strategy: + matrix: + arch: [aarch64, x86_64] + runs-on: ${{ matrix.arch == 'aarch64' && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Install build tools + run: sudo apt-get install -y --no-install-recommends ninja-build yasm + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: deps-prefix-linux-${{ matrix.arch }} + key: ${{ github.job }}-${{ matrix.arch }}-deps + - name: Run build + run: other/deploy/linux.sh "${{ matrix.arch }}" + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: toxcore-linux-${{ matrix.arch }} + path: toxcore-linux-${{ matrix.arch }} + if-no-files-found: error + - name: Get tag name for release file name + if: contains(github.ref, 'refs/tags/v') + id: get_version + run: | + VERSION="$(echo "$GITHUB_REF" | cut -d / -f 3)" + echo "release_tarball=toxcore-$VERSION-linux-${{ matrix.arch }}.tar.gz" >>$GITHUB_OUTPUT + - name: Create tarball for release upload + if: contains(github.ref, 'refs/tags/v') + run: | + tar zcf "${{ steps.get_version.outputs.release_tarball }}" toxcore-linux-${{ matrix.arch }} + sha256sum "${{ steps.get_version.outputs.release_tarball }}" >"${{ steps.get_version.outputs.release_tarball }}.sha256" + - name: Upload to versioned release + if: contains(github.ref, 'refs/tags/v') + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + draft: true + artifacts: "${{ steps.get_version.outputs.release_tarball }},${{ steps.get_version.outputs.release_tarball }}.sha256" + - name: Create tarball for nightly upload + run: | + tar zcf toxcore-nightly-linux-${{ matrix.arch }}.tar.gz toxcore-linux-${{ matrix.arch }} + sha256sum toxcore-nightly-linux-${{ matrix.arch }}.tar.gz >toxcore-nightly-linux-${{ matrix.arch }}.tar.gz.sha256 + - name: Upload to nightly release + uses: ncipollo/release-action@v1 + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + with: + allowUpdates: true + tag: nightly + omitBodyDuringUpdate: true + omitNameDuringUpdate: true + prerelease: true + replacesArtifacts: true + artifacts: "toxcore-nightly-linux-${{ matrix.arch }}.tar.gz,toxcore-nightly-linux-${{ matrix.arch }}.tar.gz.sha256" + + build-macos: + name: macOS + needs: [prepare] + strategy: + matrix: + arch: [arm64, x86_64] + runs-on: ${{ matrix.arch == 'arm64' && 'macos-14' || 'macos-13' }} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: deps-prefix-macos-${{ matrix.arch }} + key: ${{ github.job }}-${{ matrix.arch }}-deps + - name: Run build + run: other/deploy/macos.sh "${{ matrix.arch }}" + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: toxcore-macos-${{ matrix.arch }} + path: toxcore-macos-${{ matrix.arch }} + if-no-files-found: error + + build-ios: + name: iOS + needs: [prepare] + strategy: + matrix: + target: [ios-arm64, ios-armv7, ios-armv7s, iphonesimulator-arm64, iphonesimulator-x86_64] + runs-on: 'macos-14' + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: deps-prefix-${{ matrix.target }} + key: ${{ github.job }}-${{ matrix.target }}-deps + - name: Run build + run: other/deploy/ios.sh "${{ matrix.target }}" + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: toxcore-${{ matrix.target }} + path: toxcore-${{ matrix.target }} + if-no-files-found: error + + build-xcode-framework: + name: Xcode Framework + needs: [build-ios, build-macos] + runs-on: 'macos-14' + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Download artifact for ios + uses: actions/download-artifact@v4 + with: + pattern: toxcore-ios-* + - name: Download artifact for iphonesimulator + uses: actions/download-artifact@v4 + with: + pattern: toxcore-iphonesimulator-* + - name: Download artifact for macos + uses: actions/download-artifact@v4 + with: + pattern: toxcore-macos-* + - name: Run build + run: | + mv toxcore-* other/deploy/apple/ + other/deploy/apple/make-framework.sh + tar -C other/deploy/apple -zcf toxcore-xcframework.tar.gz Tox.xcframework + shasum -a 256 toxcore-xcframework.tar.gz >toxcore-xcframework.tar.gz.sha256 + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: toxcore-xcframework + path: other/deploy/apple/Tox.xcframework + if-no-files-found: error + - name: Get tag name for release file name + if: contains(github.ref, 'refs/tags/v') + id: get_version + run: | + VERSION="$(echo "$GITHUB_REF" | cut -d / -f 3)" + echo "release_tarball=toxcore-$VERSION-xcframework.tar.gz" >>$GITHUB_OUTPUT + - name: Create tarball for release upload + if: contains(github.ref, 'refs/tags/v') + run: | + cp toxcore-xcframework.tar.gz "${{ steps.get_version.outputs.release_tarball }}" + cp toxcore-xcframework.tar.gz.sha256 "${{ steps.get_version.outputs.release_tarball }}.sha256" + - name: Upload to versioned release + if: contains(github.ref, 'refs/tags/v') + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + draft: true + artifacts: "${{ steps.get_version.outputs.release_tarball }},${{ steps.get_version.outputs.release_tarball }}.sha256" + - name: Create tarball for nightly upload + run: | + cp toxcore-xcframework.tar.gz toxcore-nightly-xcframework.tar.gz + cp toxcore-xcframework.tar.gz.sha256 toxcore-nightly-xcframework.tar.gz.sha256 + - name: Upload to nightly release + uses: ncipollo/release-action@v1 + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + with: + allowUpdates: true + tag: nightly + omitBodyDuringUpdate: true + omitNameDuringUpdate: true + prerelease: true + replacesArtifacts: true + artifacts: "toxcore-nightly-xcframework.tar.gz,toxcore-nightly-xcframework.tar.gz.sha256" + + build-android: + name: Android + needs: [prepare] + strategy: + matrix: + arch: [armeabi-v7a, arm64-v8a, x86, x86_64] + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: deps-prefix-android-${{ matrix.arch }} + key: ${{ github.job }}-${{ matrix.arch }}-deps + - name: Run build + run: other/deploy/android.sh "${{ matrix.arch }}" + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: toxcore-android-${{ matrix.arch }} + path: toxcore-android-${{ matrix.arch }} + if-no-files-found: error + - name: Get tag name for release file name + if: contains(github.ref, 'refs/tags/v') + id: get_version + run: | + VERSION="$(echo "$GITHUB_REF" | cut -d / -f 3)" + echo "release_tarball=toxcore-$VERSION-android-${{ matrix.arch }}.tar.gz" >>$GITHUB_OUTPUT + - name: Create tarball for release upload + if: contains(github.ref, 'refs/tags/v') + run: | + tar zcf "${{ steps.get_version.outputs.release_tarball }}" toxcore-android-${{ matrix.arch }} + sha256sum "${{ steps.get_version.outputs.release_tarball }}" >"${{ steps.get_version.outputs.release_tarball }}.sha256" + - name: Upload to versioned release + if: contains(github.ref, 'refs/tags/v') + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + draft: true + artifacts: "${{ steps.get_version.outputs.release_tarball }},${{ steps.get_version.outputs.release_tarball }}.sha256" + - name: Create tarball for nightly upload + run: | + tar zcf toxcore-nightly-android-${{ matrix.arch }}.tar.gz toxcore-android-${{ matrix.arch }} + sha256sum toxcore-nightly-android-${{ matrix.arch }}.tar.gz >toxcore-nightly-android-${{ matrix.arch }}.tar.gz.sha256 + - name: Upload to nightly release + uses: ncipollo/release-action@v1 + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + with: + allowUpdates: true + tag: nightly + omitBodyDuringUpdate: true + omitNameDuringUpdate: true + prerelease: true + replacesArtifacts: true + artifacts: "toxcore-nightly-android-${{ matrix.arch }}.tar.gz,toxcore-nightly-android-${{ matrix.arch }}.tar.gz.sha256" + + build-wasm: + name: WebAssembly + needs: [prepare] + runs-on: ubuntu-24.04 + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to DockerHub + if: ${{ github.event_name == 'push' }} + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build and push + uses: docker/build-push-action@v6 + with: + file: other/docker/wasm/wasm.Dockerfile + push: ${{ github.event_name == 'push' }} + tags: toxchat/c-toxcore:wasm + cache-from: type=registry,ref=toxchat/c-toxcore:wasm + cache-to: type=inline + outputs: type=docker + - name: Extract wasm build + run: docker run --rm --entrypoint tar toxchat/c-toxcore:wasm -C /wasm/bin -c libtoxcore.js libtoxcore.wasm >toxcore-wasm.tar + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: toxcore-wasm.tar + path: toxcore-wasm.tar + if-no-files-found: error + - name: Compress tarball + run: gzip toxcore-wasm.tar + - name: Get tag name for release file name + if: contains(github.ref, 'refs/tags/v') + id: get_version + run: | + VERSION="$(echo "$GITHUB_REF" | cut -d / -f 3)" + echo "release_tarball=toxcore-$VERSION-wasm.tar.gz" >>$GITHUB_OUTPUT + - name: Create tarball for release upload + if: contains(github.ref, 'refs/tags/v') + run: | + cp toxcore-wasm.tar.gz "${{ steps.get_version.outputs.release_tarball }}" + - name: Upload to versioned release + if: contains(github.ref, 'refs/tags/v') + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + draft: true + artifacts: "${{ steps.get_version.outputs.release_tarball }}" + - name: Create tarball for nightly upload + run: | + cp toxcore-wasm.tar.gz toxcore-nightly-wasm.tar.gz + - name: Upload to nightly release + uses: ncipollo/release-action@v1 + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + with: + allowUpdates: true + tag: nightly + omitBodyDuringUpdate: true + omitNameDuringUpdate: true + prerelease: true + replacesArtifacts: true + artifacts: "toxcore-nightly-wasm.tar.gz" + + build-single-file: + name: Single file + needs: [prepare] + uses: TokTok/ci-tools/.github/workflows/deploy-artifact.yml@master + with: + project-name: toxcore + artifact-source: toxcore-{av,core}.c + artifact-versioned: toxcore-$VERSION-{av,core}.c + build: single-file + run: | + other/deploy/single-file/make_single_file -av >toxcore-av.c + other/deploy/single-file/make_single_file -core >toxcore-core.c + + build-tarball: + name: Source tarball + needs: [prepare] + uses: TokTok/ci-tools/.github/workflows/deploy-artifact.yml@master + with: + project-name: toxcore + artifact-source: tox-*.tar.{gz,xz} + artifact-versioned: $VERSION.tar.{gz,xz} + build: tarball + run: | + sudo apt-get install -y --no-install-recommends libsodium-dev + autoreconf -fi + ./configure + make dist + for f in tox-*.tar.gz; do + gunzip -c "$f" | xz -z - >"${f%.gz}.xz" + done diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 9b7092f..c800d6e 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -98,26 +98,6 @@ jobs: 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@v3 - - name: Login to DockerHub - if: ${{ github.event_name == 'push' }} - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push - uses: docker/build-push-action@v5 - 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: diff --git a/.github/workflows/draft.yml b/.github/workflows/draft.yml new file mode 100644 index 0000000..6d2f854 --- /dev/null +++ b/.github/workflows/draft.yml @@ -0,0 +1,17 @@ +name: draft + +on: + push: + branches: [master] + pull_request_target: + branches: [master] + types: [opened, reopened, synchronize] + +# Cancel old builds when pushing new commits. +concurrency: + group: draft-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + release: + uses: TokTok/ci-tools/.github/workflows/release-drafter.yml@master diff --git a/.github/workflows/post-submit.yml b/.github/workflows/post-submit.yml index 1976d54..f1758ab 100644 --- a/.github/workflows/post-submit.yml +++ b/.github/workflows/post-submit.yml @@ -5,15 +5,19 @@ on: branches: [master] jobs: - build-alpine-s390x: - runs-on: ubuntu-latest + build: + strategy: + fail-fast: false + matrix: + tool: [alpine-s390x, freebsd] + runs-on: ubuntu-22.04 steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Docker Build uses: docker/build-push-action@v5 with: - file: other/docker/alpine-s390x/Dockerfile + file: other/docker/${{ matrix.tool }}/${{ matrix.tool }}.Dockerfile docker-coverage: runs-on: ubuntu-latest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9f4ee30..a5556ca 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,12 +1,18 @@ name: release on: - push: - branches: [master] - pull_request_target: - branches: [master] - types: [opened, reopened, synchronize] + issues: + types: [assigned] + +concurrency: + group: release-${{ github.event.issue.number }} + cancel-in-progress: true jobs: release: - uses: TokTok/ci-tools/.github/workflows/release-drafter.yml@master + name: Release + uses: TokTok/ci-tools/.github/workflows/release-deploy.yml@master + with: + production: true + secrets: + TOKEN_RELEASES: ${{ secrets.TOKEN_RELEASES }} diff --git a/.reviewable/completion.js b/.reviewable/completion.js new file mode 100644 index 0000000..1bef3b6 --- /dev/null +++ b/.reviewable/completion.js @@ -0,0 +1,76 @@ +// jshint esversion: 6 + +// This code will check that the pull request has been approved via GitHub +// review approval by a minimum number of reviewers and by all assignees, and +// that no changes were requested by any reviewers. Only reviewers with write +// access to the repository are considered. +// +// This is very similar to GitHub's built-in branch protection option to require +// pull request reviews before merging, but allows for much more flexibility and +// customization. + +// dependencies: lodash4 + +// Helper function to check if a user is a bot. +function isBotAuthor(author) { + return ( + author.username.endsWith("[bot]") || author.username.startsWith("toktok-") + ); +} + +function equals(a) { + return (b) => a === b; +} + +// The number of approvals required to merge: at least 2 humans must approve the +// code. If the author is a bot, then 2 approvals are required; otherwise, only +// 1 approval is required (because 1 human wrote the code, so they approve). +let numApprovalsRequired = isBotAuthor(review.pullRequest.author) ? 2 : 1; + +const approvals = review.pullRequest.approvals; + +let numApprovals = _.filter(approvals, equals("approved")).length; +const numRejections = _.filter(approvals, equals("changes_requested")).length; + +const discussionBlockers = _(review.discussions) + .filter((x) => !x.resolved) + .flatMap("participants") + .filter((x) => !x.resolved) + .map((user) => _.pick(user, "username")) + .value(); + +let pendingReviewers = _(discussionBlockers) + .map((user) => _.pick(user, "username")) + .concat(review.pullRequest.requestedReviewers) + .value(); + +const required = _.map(review.pullRequest.assignees, "username"); +_.pull(required, review.pullRequest.author.username); +if (required.length) { + numApprovalsRequired = _.max([required.length, numApprovalsRequired]); + numApprovals = + _(approvals).pick(required).filter(equals("approved")).size() + + _.min([numApprovals, numApprovalsRequired - required.length]); + pendingReviewers = _(required) + .reject((username) => approvals[username] === "approved") + .reject((username) => pendingReviewers.length && approvals[username]) + .map((username) => ({ username })) + .concat(pendingReviewers) + .value(); +} + +pendingReviewers = _.uniqBy(pendingReviewers, "username"); + +const description = + (numRejections ? `${numRejections} change requests, ` : "") + + `${numApprovals} of ${numApprovalsRequired} approvals obtained`; +const shortDescription = + (numRejections ? `${numRejections} ✗, ` : "") + + `${numApprovals} of ${numApprovalsRequired} ✓`; + +return { + completed: numApprovals >= numApprovalsRequired, + description, + shortDescription, + pendingReviewers, +}; diff --git a/.reviewable/settings.yaml b/.reviewable/settings.yaml new file mode 100644 index 0000000..361886f --- /dev/null +++ b/.reviewable/settings.yaml @@ -0,0 +1,4 @@ +# Reviewable settings file. Read the docs at https://docs.reviewable.io/repositories.html#store-repository-settings-using-the-reviewable-directory +approval-text: ":lgtm_strong:" +github-status: + updates: always diff --git a/BUILD.bazel b/BUILD.bazel index 481b46a..a5c465a 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -10,6 +10,8 @@ genrule( "//c-toxcore/toxcore:tox.h", "//c-toxcore/toxcore:tox_dispatch.h", "//c-toxcore/toxcore:tox_events.h", + "//c-toxcore/toxcore:tox_log_level.h", + "//c-toxcore/toxcore:tox_options.h", "//c-toxcore/toxcore:tox_private.h", "//c-toxcore/toxencryptsave:toxencryptsave.h", ], @@ -18,6 +20,8 @@ genrule( "tox/tox.h", "tox/tox_dispatch.h", "tox/tox_events.h", + "tox/tox_log_level.h", + "tox/tox_options.h", "tox/tox_private.h", "tox/toxencryptsave.h", ], @@ -26,6 +30,8 @@ genrule( cp $(location //c-toxcore/toxcore:tox.h) $(GENDIR)/c-toxcore/tox/tox.h cp $(location //c-toxcore/toxcore:tox_dispatch.h) $(GENDIR)/c-toxcore/tox/tox_dispatch.h cp $(location //c-toxcore/toxcore:tox_events.h) $(GENDIR)/c-toxcore/tox/tox_events.h + cp $(location //c-toxcore/toxcore:tox_log_level.h) $(GENDIR)/c-toxcore/tox/tox_log_level.h + cp $(location //c-toxcore/toxcore:tox_options.h) $(GENDIR)/c-toxcore/tox/tox_options.h cp $(location //c-toxcore/toxcore:tox_private.h) $(GENDIR)/c-toxcore/tox/tox_private.h cp $(location //c-toxcore/toxencryptsave:toxencryptsave.h) $(GENDIR)/c-toxcore/tox/toxencryptsave.h """, diff --git a/CHANGELOG.md b/CHANGELOG.md index 36bfb39..dd1f073 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,41 @@ + +## v0.2.21-rc.1 (2025-02-24) -## v0.2.20 +### Release notes + +Pre-release for toxcore. Primarily, we now have an experimental network profiling callback. + +#### Features + +- Add a Makefile for the single file deploy build. ([432ab60c](https://github.com/TokTok/c-toxcore/commit/432ab60c0023e3eb2f02db3d54d7d3aec94c4098)) +- Implement Tox network profiler ([80fabd4a](https://github.com/TokTok/c-toxcore/commit/80fabd4a72921c555a0e931ce593b216f086733c)) +- Add `to_string` functions for toxencryptsave errors. ([d10c966b](https://github.com/TokTok/c-toxcore/commit/d10c966b9985ea1fd479bcb8496a3663d21db0ab)) +- implement the last 2 missing network struct functions and make use of them ([ac812871](https://github.com/TokTok/c-toxcore/commit/ac812871a2ec42c37dd7f73bf0f7a6734dfc0bf2)) +- Add option to disable DNS lookups in toxcore. ([819aa2b2](https://github.com/TokTok/c-toxcore/commit/819aa2b26182f703855b09ad3dd618786a64c6cb)) +- **net:** add missing connect to network struct ([2e94da60](https://github.com/TokTok/c-toxcore/commit/2e94da60d098329b2b78a881865f7602b3ff2728)) + +#### Performance + +- Use stack allocation for strerror rendering. ([f1991aaa](https://github.com/TokTok/c-toxcore/commit/f1991aaa02978a3cb866826d2a5f24ac1e2fdd16)) + +#### Bug Fixes + +- ip to string function not accepting tcp families ([26a991ed](https://github.com/TokTok/c-toxcore/commit/26a991ed2beeb52750258bf43406f039838f439a)) +- run `do_gca` also in bootstrap nodes ([9f723f89](https://github.com/TokTok/c-toxcore/commit/9f723f891d3761d317eaaafa82ece42f5a1b0e96)) +- Don't crash on malloc failures in `bin_unpack.` ([edb4dfc4](https://github.com/TokTok/c-toxcore/commit/edb4dfc4869bdd1d1048c88842f9e1ae8bcd3c85)) +- Fake broadcast address for 127.x.x.x ([d9b8fa60](https://github.com/TokTok/c-toxcore/commit/d9b8fa6098de6c074038b6664d2572627540b148)) +- Avoid `memcpy`-ing structs into onion ping id data. ([3cfe41c7](https://github.com/TokTok/c-toxcore/commit/3cfe41c758791ac1a9006ee2241a4fbd8c16db7a)) +- Add more information on why the frame was not sent. ([e32ac001](https://github.com/TokTok/c-toxcore/commit/e32ac0019388a5eaaaa91fcf84c1650c8a87f9c5)) +- Allow TCP connections to fail `connect` calls. ([ab887003](https://github.com/TokTok/c-toxcore/commit/ab8870036879e766111d6c854408fdee6018f5ed)) +- Allow peers to reconnect to group chats using a password ([fc065060](https://github.com/TokTok/c-toxcore/commit/fc0650601c163f9e035de2fce3cc58fab1ad9615)) +- reduce memory usage in group chats by 75% Significantly reduced the memory usage of groups since all message slots are preallocated for every peer for send and receive buffers of buffer size (hundreds of MiB peak when save contained alot of peers to try to connect to) ([11ab1d2a](https://github.com/TokTok/c-toxcore/commit/11ab1d2a7232eee19b51ce126ccce267d6578903)) +- friend requests with very long messages are no longer dropped ([93aafd78](https://github.com/TokTok/c-toxcore/commit/93aafd78c1ff74ed994426cbe07f031795923d3c)) +- windows use of REUSEADDR ([0ac23cee](https://github.com/TokTok/c-toxcore/commit/0ac23cee035cd1b66d81d2603b2464426a32fce7)) + + + +## v0.2.20 (2024-11-11) ### Merged PRs: @@ -30,7 +65,21 @@ - [#2692](https://github.com/TokTok/c-toxcore/pull/2692) refactor: Make tox-bootstrapd use bool instead of int - [#2651](https://github.com/TokTok/c-toxcore/pull/2651) refactor: Make ToxAV independent of toxcore internals. -## v0.2.19 +#### Bug Fixes + +- Add missing free in `dht_get_nodes_response` event. ([3acef4bf](https://github.com/TokTok/c-toxcore/commit/3acef4bf0441214e232d2bd55126d6268b079f33)) +- `friend_connections` leak on allocation failure clean up when it only contains connections in the NONE state ([5f88a084](https://github.com/TokTok/c-toxcore/commit/5f88a084e8c67ea8d8aa733cbb57aabb5082e6d3)) +- wrong comment for closelist ([6d27a1ae](https://github.com/TokTok/c-toxcore/commit/6d27a1ae178edc4c2ebb8768bb3c455a6baac467)) +- events leak that can occur if allocation fails rare in practice, found by fuzzing ([40676284](https://github.com/TokTok/c-toxcore/commit/4067628450744bb17b8ada1a11ad35480a386012)) +- Return an error instead of crashing on nullptr args in NGC. ([9610ac31](https://github.com/TokTok/c-toxcore/commit/9610ac31c5f00f24f137478819d67e3eda832bec)) +- Use Opus in the CBR mode ([03e9fbf3](https://github.com/TokTok/c-toxcore/commit/03e9fbf3703e430d21138c4f69e9ac7dbefb7564)) +- toxav rtp temp buffer allocation size was too large and cast from 32bit to 16bit, causing a overflow and making the allocated size too small ([671b1f92](https://github.com/TokTok/c-toxcore/commit/671b1f92332a8314dccf76d5df93c0b6c1230636)) +- Memory leak in the bootstrap daemon ([5344d7f8](https://github.com/TokTok/c-toxcore/commit/5344d7f84d060311f2147b343cdd3fd4c433d7dd)) +- **toxav:** pass video bit rate as kbit Previously we unintentionally made it Mbit. ([55752a2e](https://github.com/TokTok/c-toxcore/commit/55752a2e2ef894bfa6d7a2a21a0278e3f2bede7d)) + + + +## v0.2.19 (2024-03-27) ### Merged PRs: @@ -296,7 +345,76 @@ - [#2014](https://github.com/TokTok/c-toxcore/issues/2014) Add sodium autotools CI build - [#1144](https://github.com/TokTok/c-toxcore/issues/1144) DHT_bootstrap should not link against misc_tools -## v0.2.18 +#### Bug Fixes + +- flaky tcp test This only fixes the symptoms, not the real problem. Sometimes or consistently on some platforms a socket might need a moment before it can be written to. ([b03b5712](https://github.com/TokTok/c-toxcore/commit/b03b5712720de9a9901ea12fd741f177327a7021)) +- Disable IPv6 in Windows cross-compilation tests ([b3c3c49d](https://github.com/TokTok/c-toxcore/commit/b3c3c49d26c0cf2b91b9ec69f9a3f932ab9f2d6d)) +- Test the current Windows Dockerfile, not an old Dockerhub image ([dfb9a0b0](https://github.com/TokTok/c-toxcore/commit/dfb9a0b02bd16db24cdae2c0af799129cadb1024)) +- Remove unnecessary wsock32 dependency on Windows ([e519f799](https://github.com/TokTok/c-toxcore/commit/e519f7998b75ed3701f6b9d6d9cc7cadc428686c)) +- Correct type for conference offline peer numbers. ([be82a3ea](https://github.com/TokTok/c-toxcore/commit/be82a3ea303466797c63018e7a1fb04891e59fee)) +- `save_compatibility_test` failing on big-endian systems ([9a8dfa06](https://github.com/TokTok/c-toxcore/commit/9a8dfa06abafdac2c478e5c7339d9f9fbb1ab4a2)) +- Don't serve files from websockify. ([86f5e555](https://github.com/TokTok/c-toxcore/commit/86f5e55578b13fe44b6822b97a63e9ecd2b63db0)) +- Correctly pass extended public keys to group moderation code. ([710eb674](https://github.com/TokTok/c-toxcore/commit/710eb674a50f17201bb7556d389d82d2133d98de)) +- Pass array, not array pointer, to `memcmp`. ([c71567dc](https://github.com/TokTok/c-toxcore/commit/c71567dc18515f69111c5af7902bc0357f0cd9ea)) +- Correct a few potential null derefs in bootstrap daemon. ([08d3393d](https://github.com/TokTok/c-toxcore/commit/08d3393def4578fc94076e3a25258a809e4b87e7)) +- Add missing memunlock of local variable when it goes out of scope. ([b9877b32](https://github.com/TokTok/c-toxcore/commit/b9877b32b0bda719eea19e931f04bac2c96a9ab4)) +- Zero out stack-allocated secret key before return. ([dab5fe44](https://github.com/TokTok/c-toxcore/commit/dab5fe44b9070a406a36011df12840fe9e295ff0)) +- Fix some false positive from PVS Studio. ([9fe18b17](https://github.com/TokTok/c-toxcore/commit/9fe18b176fb661142c8565d691c5ad9e60125873)) +- Don't use `memcmp` to compare `IP_Port`s. ([39aadf89](https://github.com/TokTok/c-toxcore/commit/39aadf8922cc9276cf7f612cb2eb9b243b363210)) +- partially fix a bug that prevented group part messages from sending. ([d94246a9](https://github.com/TokTok/c-toxcore/commit/d94246a9061e2af7c02c4edc94156f5e8148bd9a)) +- a few off by one errors in group autotests ([203e1af8](https://github.com/TokTok/c-toxcore/commit/203e1af81e48909f0a6647fcbe6fc5d4764187bd)) +- dont resolve to ipv6 addresses when its disabled ([001d00ab](https://github.com/TokTok/c-toxcore/commit/001d00ab30a7ec3771babb82bdbf90401a468497)) +- Make all the fuzzers work again, and add a test for protodump. ([4cea4f9c](https://github.com/TokTok/c-toxcore/commit/4cea4f9ca457f4122db2c0912b155d8b451f7aa5)) +- Remove fatal error for non-erroneous case ([87bcc432](https://github.com/TokTok/c-toxcore/commit/87bcc4322d50d2ae7714e734b6468ef43dd818a7)) +- Make sure there's enough space for CONSUME1 in fuzzers. ([812f931d](https://github.com/TokTok/c-toxcore/commit/812f931d5f082f1dd58d4ced54ac088dd5da40cf)) +- issues with packet broadcast error reporting ([072e3beb](https://github.com/TokTok/c-toxcore/commit/072e3beb3f41ab9ed7c26a7eb2c44fa1c509db48)) +- don't pass garbage data buffer to packet send functions ([ebc96438](https://github.com/TokTok/c-toxcore/commit/ebc964386285f44ab3e0284c4192a5d8e2fe252c)) +- Use QueryPerformanceCounter on windows for monotonic time. ([82d82656](https://github.com/TokTok/c-toxcore/commit/82d8265688a3eb13aa045b5d15723ff0ae84461e)) +- unpack enum function names in event impl generator ([41dfb1c1](https://github.com/TokTok/c-toxcore/commit/41dfb1c1c050d9f31ae616af68960fbcce576c13)) +- Correct a use-after-free and fix some memory leaks. ([425216d9](https://github.com/TokTok/c-toxcore/commit/425216d9eca8b3c2afd48e52c04c6226b920303a)) +- also Install header for private/experimental API functions with autotools ([66453439](https://github.com/TokTok/c-toxcore/commit/66453439acf79a35eb46fe66a1c72595e7d0c9ca)) +- Enable debug flag for ubsan. ([39833691](https://github.com/TokTok/c-toxcore/commit/3983369103d3dc13ced13803a97783b6376459bf)) +- Add missing `htons` call when adding configured TCP relay. ([d1e850c5](https://github.com/TokTok/c-toxcore/commit/d1e850c56c71d6b592a6b28d9319b59d3ed5cc1d)) +- Fix memory leak in the error path of loading savedata. ([94cf9d1f](https://github.com/TokTok/c-toxcore/commit/94cf9d1f360ad6339cb8ed87cef651d7ff02e3be)) +- always respond to version packets with toxcore version ([06d949a7](https://github.com/TokTok/c-toxcore/commit/06d949a70196e6add3d3dd29de27072b6d048908)) +- Ensure we have allocators available for the error paths. ([24b54722](https://github.com/TokTok/c-toxcore/commit/24b54722aed65b02f1e921f08f8d31d68f92a45a)) +- Add missing `#include `. ([7469a529](https://github.com/TokTok/c-toxcore/commit/7469a529b126995199ef819d23e484b25895b7f8)) +- `resolve_bootstrap_node()` not checking `net_getipport()` returned count correctly doc: improve inline docu of return of `net_getipport` ([88ffd1a6](https://github.com/TokTok/c-toxcore/commit/88ffd1a6495aa59dcd7144b552a91df0bdb5b6d9)) +- expand asserts in `fuzz_support.cc` ([d222d708](https://github.com/TokTok/c-toxcore/commit/d222d708b5756a496917f9b7e713a8bc678334f3)) +- #1144 by forcing `misc_tools` to be a static lib ([e1c38b40](https://github.com/TokTok/c-toxcore/commit/e1c38b40d6133c22eea8eba8d79d91f8705a6b3a), closes [#1144](https://github.com/TokTok/c-toxcore/issues/1144)) +- TCC doesn't now that abort() never returns ([ce36741c](https://github.com/TokTok/c-toxcore/commit/ce36741c65585c91bb718cbfad8fccf177bb6110)) +- tcc needs integer as VLA size ([d5de4dc8](https://github.com/TokTok/c-toxcore/commit/d5de4dc8788e1db136fea7f11e56b08a1cd7e09b)) +- missmatch between declaration and definition ([26ce30d8](https://github.com/TokTok/c-toxcore/commit/26ce30d8524c178797babaae42e16da4a20c338d)) +- potential endless loop under extremely high load ([ad2375ff](https://github.com/TokTok/c-toxcore/commit/ad2375ffe9cfcf5a7bd50bd15deeb598b14f45aa)) +- update Python path for AppVeyor ([de975320](https://github.com/TokTok/c-toxcore/commit/de97532064354fb4d24ad74957046c5a6c56d3c5)) +- missing net to host conversion of port in logging in `group_chat.c` ([7dfa935a](https://github.com/TokTok/c-toxcore/commit/7dfa935ac8f1c176d9b14c52064a9c9191137981)) +- missing net to host conversion of port in logging ([8054854b](https://github.com/TokTok/c-toxcore/commit/8054854b583c4c11c7ceafae4ab2e0e0150c8115)) +- unlock correct `dht_friend` ([306693ab](https://github.com/TokTok/c-toxcore/commit/306693aba33505438e4379a27b94607427d23cd3)) +- **ci:** window builds now build in parallel ([acdc6738](https://github.com/TokTok/c-toxcore/commit/acdc67387b3dc25de8b618430374d0336feabc2f)) +- **test:** tests use ipv6 by default, even with `USE_IPV6` set to 0 ([d3b935f6](https://github.com/TokTok/c-toxcore/commit/d3b935f63f43f9136c7dfa5b11f724a52ae7a4d2)) + +#### Features + +- add message IDs to private group messages ([7b1db6ad](https://github.com/TokTok/c-toxcore/commit/7b1db6adc1d4244aa1ed02b51609d20fba13b90e)) +- Check hashes of Windows dependencies when cross-compiling ([e742dedd](https://github.com/TokTok/c-toxcore/commit/e742deddfff13485d2ac3456c26802dc5ac0d2e7)) +- Build the fun utils when cross-compiling to Windows ([1be311e5](https://github.com/TokTok/c-toxcore/commit/1be311e51fda9d7b8c8b4d64aec20a38b3d38313)) +- Generate .def, .exp and .lib files when building for Windows ([c4fa8f7f](https://github.com/TokTok/c-toxcore/commit/c4fa8f7fb14a45203731f01d46c91d7c20d194d6)) +- Let CMake create the dll instead of doing so ourselves ([74bbac53](https://github.com/TokTok/c-toxcore/commit/74bbac5363172c21fd0e60aa74947aecc2a4df22)) +- Harden Windows cross-compilation ([246642e9](https://github.com/TokTok/c-toxcore/commit/246642e9aec5b26ca4ea6c28af5e8bb9237fa6d3)) +- Add `dht_get_nodes_response` event to the events system. ([16809dc3](https://github.com/TokTok/c-toxcore/commit/16809dc36e82e9fb01f83ecdbff0331386cc13ad)) +- add ngc events ([8c35e0fe](https://github.com/TokTok/c-toxcore/commit/8c35e0fefbe84858f4d1ec63ecb451d830dea025)) +- Add `to_string` functions for all public enums. ([5f863a54](https://github.com/TokTok/c-toxcore/commit/5f863a54928cee153f2d2f1acfa79dcf6ac0bcd4)) +- Enable ubsan on bootstrap nodes. ([90f74968](https://github.com/TokTok/c-toxcore/commit/90f749681954fca1cc17097593eb274ec383ef4b)) +- allow for larger incoming NGC packets ([cd34b60f](https://github.com/TokTok/c-toxcore/commit/cd34b60f0fdd648a0c813d20aee731ef1d98779f)) + +#### Performance + +- Slightly reduce bandwidth usage when there are few nodes. ([028b017d](https://github.com/TokTok/c-toxcore/commit/028b017d7920a7b0ebe738cb72f163989cc284c8)) +- Add a KVM FreeBSD build on cirrus ci. ([83efb173](https://github.com/TokTok/c-toxcore/commit/83efb17367a852c56f8525c9e0275f05dbe896fa)) + + + +## v0.2.18 (2022-04-18) ### Merged PRs: @@ -410,7 +528,33 @@ - [#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 +#### Bug Fixes + +- remove the assert because buffer can be larger than `UINT16_MAX.` ([6b0d1151](https://github.com/TokTok/c-toxcore/commit/6b0d1151ac813170fe9aba1f90e0791c05e53399)) +- Fix potential array out-of-bounds in DHT random node retrieval. ([d78ee9b1](https://github.com/TokTok/c-toxcore/commit/d78ee9b12e876604712db68746fc6ddf0a4691e0)) +- Allow onion paths to be built from more random nodes. ([5073882e](https://github.com/TokTok/c-toxcore/commit/5073882e0f0ea114e4f0efe719a72ecf7b168926)) +- really fix overrun added in e49a477a ([417d28d4](https://github.com/TokTok/c-toxcore/commit/417d28d439e344a21e1e7fbad55354c4c8bcb05b)) +- Format IP as string again in error log. ([d0728560](https://github.com/TokTok/c-toxcore/commit/d0728560bc308fe2ef5320d12c3e6021f13cc5d7)) +- Fix a stack overflow triggered by small DHT packets. ([7a4cc107](https://github.com/TokTok/c-toxcore/commit/7a4cc107c0d9a30b97a53d584c3ab5e3d84a3b47)) +- Don't crash if RNG init failed. ([ddda6055](https://github.com/TokTok/c-toxcore/commit/ddda605509091bb0c0a8e79680f42d80ae91a2b8)) +- fix typo in git command in INSTALL.md ([3cc72f5f](https://github.com/TokTok/c-toxcore/commit/3cc72f5f577c7a4bbe1ea913ae4ec82a758bf18c)) +- Correct calculation of packet sent time ([c38f21f8](https://github.com/TokTok/c-toxcore/commit/c38f21f8884f1ddcd0e93168918c27a08fca8659)) +- Eliminate memory leak in toxav. ([28623dcf](https://github.com/TokTok/c-toxcore/commit/28623dcfa979bacbbf338eb5ac32ae71fd9c4984)) +- Allow port range in `DHT_bootstrap.c.` ([001aa634](https://github.com/TokTok/c-toxcore/commit/001aa63401821920695e03a69141587c5067082b)) + +#### Features + +- add forwarding and announce request handling ([e49a477a](https://github.com/TokTok/c-toxcore/commit/e49a477a845bfa5fa5dacc7c65f8e0bd38098cb2)) +- Add support for custom random number generator. ([cc31ff07](https://github.com/TokTok/c-toxcore/commit/cc31ff07fabda4dde59c201c0a5bd47b8af00498)) +- Allow custom network functions. ([f39aac09](https://github.com/TokTok/c-toxcore/commit/f39aac09e614f9b3dfcdbcc2b217ede99bff846f)) + +#### Performance + +- Make time move a lot faster in fuzzing runs. ([e4558a28](https://github.com/TokTok/c-toxcore/commit/e4558a287cd7c8dd3215204aeb25e3df4142cd91)) + + + +## v0.2.17 (2022-03-06) ### Merged PRs: @@ -473,7 +617,16 @@ - [#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 +#### Bug Fixes + +- Report failure to DHT bootstrap back to the client. ([2ce6f5b1](https://github.com/TokTok/c-toxcore/commit/2ce6f5b1694b12a34dea52bf90a7b2e691df4ded)) +- Null function pointer dereference. ([b8ce394e](https://github.com/TokTok/c-toxcore/commit/b8ce394e643dad38e067b44e1e8062eaf18b0e86)) +- out-of-memory condition by corrupted save file ([fff2b1c4](https://github.com/TokTok/c-toxcore/commit/fff2b1c4e7aae88b90dc26bf1cc71388243e5b62)) +- memory leak during conference load ([12dbafbd](https://github.com/TokTok/c-toxcore/commit/12dbafbd188a64356c07c97f7841016b5c300715)) + + + +## v0.2.16 (2022-02-18) ### Merged PRs: @@ -542,7 +695,28 @@ - [#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 +#### Bug Fixes + +- properly deallocate frozen peers ([fde2a7d1](https://github.com/TokTok/c-toxcore/commit/fde2a7d16d9b47d1dea7038080371edb486a608d)) +- Fix return type of functions returning `uint64_t.` ([598a365e](https://github.com/TokTok/c-toxcore/commit/598a365e1f8334b909734e8e2281e2b63dcda023)) +- remove bogus asserts in fuzzer harness ([acf85eee](https://github.com/TokTok/c-toxcore/commit/acf85eee465e44dde6d9dab746d02a721cc5268f)) +- syntax error introduced in 8bf37994fd12acec9e3010437502f478399b99b4 ([d429d357](https://github.com/TokTok/c-toxcore/commit/d429d35756c4552a7087b963832a6f6b80bf5af7)) +- add msgpack dependency to fuzzer build ([7e1aa442](https://github.com/TokTok/c-toxcore/commit/7e1aa442ef3a965afafee799551755f9b43589ed)) +- Fix Conan build link failures ([b64825b3](https://github.com/TokTok/c-toxcore/commit/b64825b3894cd11f8d6be25792c92b75144f4b9a)) + +#### Performance + +- Reduce minimal encoding size of packed events. ([a3cd1102](https://github.com/TokTok/c-toxcore/commit/a3cd1102f77884f3e384715a5d4efd38d48aaac7)) + +#### Features + +- Add unpacker functions for events structures. ([cb8b9bba](https://github.com/TokTok/c-toxcore/commit/cb8b9bbabfc8b669226cddcbe985b82909fdad22)) +- Add binary packing functions for tox events. ([0a2190f2](https://github.com/TokTok/c-toxcore/commit/0a2190f28cad0beadb9d9b4b1da2d7f538ca9d7d)) +- Add async event handling (callbacks) code. ([de4af4c2](https://github.com/TokTok/c-toxcore/commit/de4af4c2703228bdeb5468be1d9d6771092b2dad)) + + + +## v0.2.15 (2022-02-06) ### Merged PRs: @@ -550,7 +724,14 @@ - [#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 +#### Bug Fixes + +- Reduce logging verbosity even more. ([79eb17ae](https://github.com/TokTok/c-toxcore/commit/79eb17aeac5f55ec866e2c52b3023fa5a971bfc4)) +- Reduce logging verbosity in TCP server. ([fedcdea9](https://github.com/TokTok/c-toxcore/commit/fedcdea95a2d1b97ee99d19c67cac4174f1dc945)) + + + +## v0.2.14 (2022-02-05) ### Merged PRs: @@ -727,7 +908,26 @@ - [#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 +#### Features + +- Add WASM build for toxcore and websocket bootstrap node. ([71965a0f](https://github.com/TokTok/c-toxcore/commit/71965a0f3b52b4e26a52128a0c98947c2276f15b)) + +#### Bug Fixes + +- Fix bootstrap on emscripten/wasm. ([727982d2](https://github.com/TokTok/c-toxcore/commit/727982d2f953ae4aa91c0b0a5cc9369ccde1bfbb)) +- Fix `toxav_basic_test` buffer overflow. ([28b5e512](https://github.com/TokTok/c-toxcore/commit/28b5e512a2487f215aac215a43d542c601c2022d)) +- don't count filetransfer as sending until accepted ([2073d02c](https://github.com/TokTok/c-toxcore/commit/2073d02c33a2bc8478099c66985f2a69854ecaf5)) +- Fix some uninitialised memory errors found by valgrind and msan. ([4a2cb37e](https://github.com/TokTok/c-toxcore/commit/4a2cb37e4bc2749d275da7a7516905d93bd61fd6)) +- use correct sample size in `toxav_basic_test` ([d2bf7247](https://github.com/TokTok/c-toxcore/commit/d2bf72479cad275cf2b685304483a0bdde7b2385)) +- Fixed uninitialised value copy. ([e30266f1](https://github.com/TokTok/c-toxcore/commit/e30266f1ce7538d932a92514f29e1233d68ee337)) + +#### Performance + +- improve speed of cracker.c ([828312c2](https://github.com/TokTok/c-toxcore/commit/828312c2f9bbbbfb7084aa63374d573f2ac87e00)) + + + +## v0.2.13 (2021-12-06) ### Merged PRs: @@ -788,7 +988,13 @@ - [#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 +#### Performance + +- reduce calling into `Mono_Time` in DHT ([0c320462](https://github.com/TokTok/c-toxcore/commit/0c320462d713b2741045e56df4487cfad559c05e)) + + + +## v0.2.12 (2020-05-01) ### Merged PRs: @@ -834,7 +1040,9 @@ - [#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 + + +## v0.2.11 (2020-03-22) ### Merged PRs: @@ -894,7 +1102,9 @@ - [#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 + + +## v0.2.10 (2019-05-30) ### Merged PRs: @@ -918,7 +1128,9 @@ - [#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 + + +## v0.2.9 (2019-01-12) ### Merged PRs: @@ -987,7 +1199,9 @@ - [#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 + + +## v0.2.8 (2018-10-07) ### Merged PRs: @@ -1042,7 +1256,9 @@ - [#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 + + +## v0.2.7 (2018-08-30) ### Merged PRs: @@ -1091,7 +1307,9 @@ - [#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 + + +## v0.2.6 (2018-08-16) ### Merged PRs: @@ -1130,7 +1348,9 @@ - [#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 + + +## v0.2.5 (2018-08-08) ### Merged PRs: @@ -1159,7 +1379,9 @@ - [#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 + + +## v0.2.4 (2018-07-20) ### Merged PRs: @@ -1231,7 +1453,9 @@ - [#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 + + +## v0.2.3 (2018-06-25) ### Merged PRs: @@ -1287,7 +1511,9 @@ - [#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 + + +## v0.2.2 (2018-04-17) ### Merged PRs: @@ -1312,7 +1538,9 @@ - [#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 + + +## v0.2.1 (2018-03-10) ### Merged PRs: @@ -1323,7 +1551,9 @@ - [#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 + + +## v0.2.0 (2018-02-28) ### Merged PRs: @@ -1478,7 +1708,9 @@ - [#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 + + +## v0.1.11 (2017-12-27) ### Merged PRs: @@ -1509,7 +1741,9 @@ - [#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 + + +## v0.1.10 (2017-08-16) ### Merged PRs: @@ -1517,7 +1751,9 @@ - [#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 + + +## v0.1.9 (2017-06-06) ### Merged PRs: @@ -1548,7 +1784,9 @@ - [#482](https://github.com/TokTok/c-toxcore/issues/482) CMake can't detect and compile ToxAV on OSX -## v0.1.8 + + +## v0.1.8 (2017-04-28) ### Merged PRs: @@ -1570,7 +1808,9 @@ - [#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 + + +## v0.1.7 (2017-03-26) ### Merged PRs: @@ -1597,7 +1837,9 @@ - [#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 + + +## v0.1.6 (2017-01-27) ### Merged PRs: @@ -1614,7 +1856,9 @@ - [#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 + + +## v0.1.5 (2017-01-19) ### Merged PRs: @@ -1633,7 +1877,9 @@ - [#413](https://github.com/TokTok/c-toxcore/issues/413) Support C compilation with `-std=c99` in autotools -## v0.1.4 + + +## v0.1.4 (2017-01-13) ### Merged PRs: @@ -1664,7 +1910,9 @@ - [#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 + + +## v0.1.3 (2017-01-06) ### Merged PRs: @@ -1686,7 +1934,9 @@ - [#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 + + +## v0.1.2 (2016-12-23) ### Merged PRs: @@ -1705,7 +1955,9 @@ - [#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 + + +## v0.1.1 (2016-12-17) ### Merged PRs: @@ -1722,7 +1974,9 @@ - [#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 + + +## v0.1.0 (2016-12-14) ### Merged PRs: @@ -1753,7 +2007,9 @@ - [#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 + + +## v0.0.5 (2016-11-25) ### Merged PRs: @@ -1776,7 +2032,9 @@ - [#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 + + +## v0.0.4 (2016-11-14) ### Merged PRs: @@ -1791,7 +2049,9 @@ - [#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 + + +## v0.0.3 (2016-11-07) ### Merged PRs: @@ -1816,7 +2076,9 @@ - [#40](https://github.com/TokTok/c-toxcore/issues/40) Stateless callbacks in toxcore's public API -## v0.0.2 + + +## v0.0.2 (2016-10-30) ### Merged PRs: @@ -1843,7 +2105,9 @@ - [#201](https://github.com/TokTok/c-toxcore/issues/201) Logging callback was broken -## v0.0.1 + + +## v0.0.1 (2016-10-01) ### Merged PRs: @@ -1965,3 +2229,9 @@ - [#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 + +#### Bug Fixes + +- replace memset with `sodium_memzero` for sensitive data ([23b0c9cd](https://github.com/TokTok/c-toxcore/commit/23b0c9cdedae01b09055a0476823e225680d3930)) +- compare sensitive data with `sodium_memcmp` fix: make `increment_nonce` & `increment_nonce_number` independent of user-controlled input fix: make `crypto_core` more stable agains null ptr dereference ([ed3a794c](https://github.com/TokTok/c-toxcore/commit/ed3a794c9bf6380801ee21c816505f457b6a1348)) +- bad memset length in `ip_init()` ([f267266b](https://github.com/TokTok/c-toxcore/commit/f267266bf611570c6e79dfb800e97396151ff870)) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9237d21..337ad71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,7 @@ set_source_files_properties( # versions in a synchronised way. set(PROJECT_VERSION_MAJOR "0") set(PROJECT_VERSION_MINOR "2") -set(PROJECT_VERSION_PATCH "20") +set(PROJECT_VERSION_PATCH "21") set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") # set .so library version / following libtool scheme @@ -238,7 +238,7 @@ set(toxcore_SOURCES toxcore/events/conference_peer_list_changed.c toxcore/events/conference_peer_name.c toxcore/events/conference_title.c - toxcore/events/dht_get_nodes_response.c + toxcore/events/dht_nodes_response.c toxcore/events/events_alloc.c toxcore/events/events_alloc.h toxcore/events/file_chunk_request.c @@ -341,13 +341,17 @@ set(toxcore_SOURCES toxcore/timed_auth.h toxcore/tox_api.c toxcore/tox.c + toxcore/tox.h toxcore/tox_dispatch.c toxcore/tox_dispatch.h toxcore/tox_event.c toxcore/tox_event.h toxcore/tox_events.c toxcore/tox_events.h - toxcore/tox.h + toxcore/tox_log_level.c + toxcore/tox_log_level.h + toxcore/tox_options.c + toxcore/tox_options.h toxcore/tox_private.c toxcore/tox_private.h toxcore/tox_pack.c @@ -369,10 +373,12 @@ endif() 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) + ${toxcore_SOURCE_DIR}/toxcore/tox_log_level.h^tox + ${toxcore_SOURCE_DIR}/toxcore/tox_options.h^tox) if(EXPERIMENTAL_API) set(toxcore_API_HEADERS ${toxcore_API_HEADERS} + ${toxcore_SOURCE_DIR}/toxcore/tox_dispatch.h^tox + ${toxcore_SOURCE_DIR}/toxcore/tox_events.h^tox ${toxcore_SOURCE_DIR}/toxcore/tox_private.h^tox) endif() diff --git a/auto_tests/CMakeLists.txt b/auto_tests/CMakeLists.txt index 996846b..41f8b79 100644 --- a/auto_tests/CMakeLists.txt +++ b/auto_tests/CMakeLists.txt @@ -48,7 +48,7 @@ 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(dht_nodes_response_api) auto_test(encryptsave) auto_test(file_saving) auto_test(file_streaming) diff --git a/auto_tests/TCP_test.c b/auto_tests/TCP_test.c index 1cf7748..1cfa474 100644 --- a/auto_tests/TCP_test.c +++ b/auto_tests/TCP_test.c @@ -271,7 +271,7 @@ static void kill_tcp_con(struct sec_TCP_con *con) free(con); } -static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP_con *con, const uint8_t *data, +static int write_packet_tcp_test_connection(const Logger *logger, const Memory *mem, struct sec_TCP_con *con, const uint8_t *data, uint16_t length) { const uint16_t packet_size = sizeof(uint16_t) + length + CRYPTO_MAC_SIZE; @@ -338,9 +338,9 @@ static void test_some(void) // 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)); + write_packet_tcp_test_connection(logger, mem, 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)); + write_packet_tcp_test_connection(logger, mem, con3, requ_p, sizeof(requ_p)); do_tcp_server_delay(tcp_s, mono_time, 50); @@ -362,9 +362,9 @@ static void test_some(void) const uint8_t test_packet[512] = {16, 17, 16, 86, 99, 127, 255, 189, 78}; // What is this packet???? - write_packet_tcp_test_connection(logger, con3, test_packet, sizeof(test_packet)); - write_packet_tcp_test_connection(logger, con3, test_packet, sizeof(test_packet)); - write_packet_tcp_test_connection(logger, con3, test_packet, sizeof(test_packet)); + write_packet_tcp_test_connection(logger, mem, con3, test_packet, sizeof(test_packet)); + write_packet_tcp_test_connection(logger, mem, con3, test_packet, sizeof(test_packet)); + write_packet_tcp_test_connection(logger, mem, con3, test_packet, sizeof(test_packet)); do_tcp_server_delay(tcp_s, mono_time, 50); @@ -388,9 +388,9 @@ static void test_some(void) 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)); + write_packet_tcp_test_connection(logger, mem, con1, test_packet, sizeof(test_packet)); + write_packet_tcp_test_connection(logger, mem, con1, test_packet, sizeof(test_packet)); + write_packet_tcp_test_connection(logger, mem, 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); @@ -405,8 +405,8 @@ static void test_some(void) 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)); + const uint8_t ping_packet[1 + sizeof(uint64_t)] = {TCP_PACKET_PING, 8, 6, 9, 67}; + write_packet_tcp_test_connection(logger, mem, con1, ping_packet, sizeof(ping_packet)); do_tcp_server_delay(tcp_s, mono_time, 50); diff --git a/auto_tests/dht_getnodes_api_test.c b/auto_tests/dht_nodes_response_api_test.c similarity index 84% rename from auto_tests/dht_getnodes_api_test.c rename to auto_tests/dht_nodes_response_api_test.c index 3a11808..5f6e80b 100644 --- a/auto_tests/dht_getnodes_api_test.c +++ b/auto_tests/dht_nodes_response_api_test.c @@ -1,12 +1,11 @@ /** * This autotest creates a small local DHT and makes sure that each peer can crawl - * the entire DHT using the DHT getnodes api functions. + * the entire DHT using the DHT nodes request/response api functions. */ #include #include #include -#include #include "../toxcore/tox.h" #include "../toxcore/tox_private.h" @@ -72,16 +71,16 @@ static bool all_nodes_crawled(const AutoTox *autotoxes, uint32_t num_toxes, uint return true; } -static void getnodes_response_cb(const Tox_Event_Dht_Get_Nodes_Response *event, void *user_data) +static void nodes_response_cb(const Tox_Event_Dht_Nodes_Response *event, void *user_data) { ck_assert(user_data != nullptr); AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; - const uint8_t *public_key = tox_event_dht_get_nodes_response_get_public_key(event); - const char *ip = (const char *)tox_event_dht_get_nodes_response_get_ip(event); - const uint16_t port = tox_event_dht_get_nodes_response_get_port(event); + const uint8_t *public_key = tox_event_dht_nodes_response_get_public_key(event); + const char *ip = (const char *)tox_event_dht_nodes_response_get_ip(event); + const uint16_t port = tox_event_dht_nodes_response_get_port(event); if (node_crawled(state->nodes, state->num_nodes, public_key)) { return; @@ -101,11 +100,11 @@ static void getnodes_response_cb(const Tox_Event_Dht_Get_Nodes_Response *event, // 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(autotox->tox, public_key, ip, port, state->public_key_list[i], nullptr); + tox_dht_send_nodes_request(autotox->tox, public_key, ip, port, state->public_key_list[i], nullptr); } } -static void test_dht_getnodes(AutoTox *autotoxes) +static void test_dht_nodes_request(AutoTox *autotoxes) { ck_assert(NUM_TOXES >= 2); @@ -125,7 +124,7 @@ static void test_dht_getnodes(AutoTox *autotoxes) ck_assert(public_key_list[i] != nullptr); tox_self_get_dht_id(autotoxes[i].tox, public_key_list[i]); - tox_events_callback_dht_get_nodes_response(autotoxes[i].dispatch, getnodes_response_cb); + tox_events_callback_dht_nodes_response(autotoxes[i].dispatch, nodes_response_cb); printf("Peer %zu dht closenode count total/announce-capable: %d/%d\n", i, @@ -153,7 +152,7 @@ int main(void) Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; - run_auto_test(nullptr, NUM_TOXES, test_dht_getnodes, sizeof(State), &options); + run_auto_test(nullptr, NUM_TOXES, test_dht_nodes_request, sizeof(State), &options); return 0; } diff --git a/auto_tests/file_saving_test.c b/auto_tests/file_saving_test.c index 9198920..e90aeff 100644 --- a/auto_tests/file_saving_test.c +++ b/auto_tests/file_saving_test.c @@ -13,11 +13,13 @@ #include #include -#include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" +#include "../toxcore/tox.h" #include "auto_test_support.h" #include "check_compat.h" +#include "../toxcore/ccompat.h" +#include "../toxcore/tox.h" #include "../toxencryptsave/toxencryptsave.h" static const char *pphrase = "bar"; @@ -27,21 +29,26 @@ static const char *savefile = "./save"; static void save_data_encrypted(void) { struct Tox_Options *options = tox_options_new(nullptr); + ck_assert(options != nullptr); Tox *t = tox_new_log(options, nullptr, nullptr); + ck_assert(t != nullptr); tox_options_free(options); tox_self_set_name(t, (const uint8_t *)name, strlen(name), nullptr); FILE *f = fopen(savefile, "wb"); + ck_assert(f != nullptr); size_t size = tox_get_savedata_size(t); uint8_t *clear = (uint8_t *)malloc(size); + ck_assert(clear != nullptr); /*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); + ck_assert(cipher != nullptr); Tox_Err_Encryption eerr; @@ -66,11 +73,12 @@ static void load_data_decrypted(void) int64_t size = ftell(f); fseek(f, 0, SEEK_SET); - ck_assert_msg(0 <= size && size <= UINT_MAX, "file size out of range"); + ck_assert_msg(TOX_PASS_ENCRYPTION_EXTRA_LENGTH <= 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); + const size_t clear_size = size - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; + uint8_t *clear = (uint8_t *)malloc(clear_size); 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); @@ -78,23 +86,23 @@ static void load_data_decrypted(void) 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); + "Could not decrypt, error code %s.", tox_err_decryption_to_string(derr)); struct Tox_Options *options = tox_options_new(nullptr); ck_assert(options != nullptr); + tox_options_set_experimental_owned_data(options, true); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); - - tox_options_set_savedata_data(options, clear, size); + ck_assert(tox_options_set_savedata_data(options, clear, clear_size)); + free(clear); Tox_Err_New err; Tox *t = tox_new_log(options, &err, nullptr); + ck_assert_msg(t != nullptr, "tox_new returned the error value %s", tox_err_new_to_string(err)); 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); @@ -103,7 +111,6 @@ static void load_data_decrypted(void) "name returned by tox_self_get_name does not match expected result"); tox_kill(t); - free(clear); free(cipher); free(readname); fclose(f); diff --git a/auto_tests/network_test.c b/auto_tests/network_test.c index a2bc301..72a9408 100644 --- a/auto_tests/network_test.c +++ b/auto_tests/network_test.c @@ -1,7 +1,5 @@ -#include #include -#include "../testing/misc_tools.h" #include "../toxcore/network.h" #include "check_compat.h" @@ -34,9 +32,8 @@ static void test_addr_resolv_localhost(void) bool res = addr_resolve_or_parse_ip(ns, mem, localhost, &ip, nullptr, true); int error = net_error(); - char *strerror = net_new_strerror(error); - ck_assert_msg(res, "Resolver failed: %d, %s", error, strerror); - net_kill_strerror(strerror); + Net_Strerror error_str; + ck_assert_msg(res, "Resolver failed: %d, %s", error, net_strerror(error, &error_str)); Ip_Ntoa ip_str; ck_assert_msg(net_family_is_ipv4(ip.family), "Expected family TOX_AF_INET, got %u.", ip.family.value); @@ -57,9 +54,7 @@ static void test_addr_resolv_localhost(void) } 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(res, "Resolver failed: %d, %s", error, net_strerror(error, &error_str)); ck_assert_msg(net_family_is_ipv6(ip.family), "Expected family TOX_AF_INET6 (%d), got %u.", TOX_AF_INET6, ip.family.value); @@ -80,9 +75,7 @@ static void test_addr_resolv_localhost(void) ip_reset(&extra); res = addr_resolve_or_parse_ip(ns, mem, localhost, &ip, &extra, true); 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(res, "Resolver failed: %d, %s", error, net_strerror(error, &error_str)); #if USE_IPV6 ck_assert_msg(net_family_is_ipv6(ip.family), "Expected family TOX_AF_INET6 (%d), got %u.", TOX_AF_INET6, diff --git a/auto_tests/proxy_test.c b/auto_tests/proxy_test.c index 66d6bc9..79e3997 100644 --- a/auto_tests/proxy_test.c +++ b/auto_tests/proxy_test.c @@ -60,7 +60,7 @@ int main(int argc, char **argv) c_sleep(100); } - const uint16_t tcp_port = 8082; + const uint16_t tcp_port = 7082; uint32_t index[] = { 1, 2, 3, 4 }; struct Tox_Options *tox_options = tox_options_new(nullptr); @@ -92,7 +92,7 @@ int main(int argc, char **argv) // 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_port(tox_options, 7080); tox_options_set_proxy_type(tox_options, TOX_PROXY_TYPE_HTTP); Tox *tox3 = tox_new_log(tox_options, nullptr, &index[2]); @@ -101,7 +101,7 @@ int main(int argc, char **argv) // 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_port(tox_options, 7081); tox_options_set_proxy_type(tox_options, TOX_PROXY_TYPE_SOCKS5); Tox *tox4 = tox_new_log(tox_options, nullptr, &index[3]); diff --git a/cmake/StrictAbi.cmake b/cmake/StrictAbi.cmake index ec57921..d0be04c 100644 --- a/cmake/StrictAbi.cmake +++ b/cmake/StrictAbi.cmake @@ -20,8 +20,10 @@ endmacro() function(_make_version_script target) set(${target}_VERSION_SCRIPT "${CMAKE_BINARY_DIR}/${target}.ld") - file(WRITE ${${target}_VERSION_SCRIPT} - "{ global:\n") + if(NOT APPLE) + file(WRITE ${${target}_VERSION_SCRIPT} + "{ global:\n") + endif() foreach(sublib ${ARGN}) string(REPLACE "^" ";" sublib ${sublib}) @@ -32,24 +34,40 @@ function(_make_version_script target) COMMAND ${SHELL} -c "egrep '^\\w' ${header} | grep '${ns}_[a-z0-9_]*(' | grep -v '^typedef' | grep -o '${ns}_[a-z0-9_]*(' | egrep -o '[a-z0-9_]+' | sort -u" OUTPUT_VARIABLE sublib_SYMS OUTPUT_STRIP_TRAILING_WHITESPACE) + if("${sublib_SYMS}" STREQUAL "") + continue() + endif() string(REPLACE "\n" ";" sublib_SYMS ${sublib_SYMS}) foreach(sym ${sublib_SYMS}) - file(APPEND ${${target}_VERSION_SCRIPT} - "${sym};\n") + if(APPLE) + file(APPEND ${${target}_VERSION_SCRIPT} "_") + endif() + file(APPEND ${${target}_VERSION_SCRIPT} "${sym}") + if(NOT APPLE) + file(APPEND ${${target}_VERSION_SCRIPT} ";") + endif() + file(APPEND ${${target}_VERSION_SCRIPT} "\n") endforeach(sym) endforeach(sublib) - file(APPEND ${${target}_VERSION_SCRIPT} - "local: *; };\n") + if(NOT APPLE) + file(APPEND ${${target}_VERSION_SCRIPT} + "local: *; };\n") + endif() - set_target_properties(${target}_shared PROPERTIES - LINK_FLAGS -Wl,--version-script,${${target}_VERSION_SCRIPT}) + if(APPLE) + set_target_properties(${target}_shared PROPERTIES + LINK_FLAGS -Wl,-exported_symbols_list,${${target}_VERSION_SCRIPT}) + else() + set_target_properties(${target}_shared PROPERTIES + LINK_FLAGS -Wl,--version-script,${${target}_VERSION_SCRIPT}) + endif() endfunction() option(STRICT_ABI "Enforce strict ABI export in dynamic libraries" OFF) -if((WIN32 AND NOT MINGW) OR APPLE) - # Windows and macOS don't have this linker functionality. +if(WIN32 AND NOT MINGW) + # Windows doesn't have this linker functionality. set(STRICT_ABI OFF) endif() diff --git a/configure.ac b/configure.ac index b2869a9..ee095b1 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.65]) -AC_INIT([tox], [0.2.20]) +AC_INIT([tox], [0.2.21]) 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]) diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index 629ec60..0d1d6fb 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -262,6 +262,8 @@ int main(int argc, char *argv[]) last_lan_discovery = mono_time_get(mono_time); } + do_gca(mono_time, gc_announces_list); + #ifdef TCP_RELAY_ENABLED do_tcp_server(tcp_s, mono_time); #endif diff --git a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 index 33ace21..74d18c4 100644 --- a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 +++ b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 @@ -1 +1 @@ -9ec2993a28988bd147bf8f4f21a824c2fc5dbf7255e391b3ce517d337ebce5c1 /usr/local/bin/tox-bootstrapd +abd103553021d86f54c874fe582001f28372b4e56502421955552117ac5f7b3b /usr/local/bin/tox-bootstrapd diff --git a/other/bootstrap_daemon/src/tox-bootstrapd.c b/other/bootstrap_daemon/src/tox-bootstrapd.c index 09a54df..6f80e9d 100644 --- a/other/bootstrap_daemon/src/tox-bootstrapd.c +++ b/other/bootstrap_daemon/src/tox-bootstrapd.c @@ -595,6 +595,8 @@ int main(int argc, char *argv[]) last_lan_discovery = mono_time_get(mono_time); } + do_gca(mono_time, group_announce); + if (enable_tcp_relay) { do_tcp_server(tcp_server, mono_time); } diff --git a/other/bootstrap_daemon/websocket/websockify/go.sum b/other/bootstrap_daemon/websocket/websockify/go.sum index b147484..ce07499 100644 --- a/other/bootstrap_daemon/websocket/websockify/go.sum +++ b/other/bootstrap_daemon/websocket/websockify/go.sum @@ -1,5 +1,7 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -17,6 +19,7 @@ golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/other/bootstrap_daemon/websocket/websockify/websockify.go b/other/bootstrap_daemon/websocket/websockify/websockify.go index fb3c9c5..145df8d 100644 --- a/other/bootstrap_daemon/websocket/websockify/websockify.go +++ b/other/bootstrap_daemon/websocket/websockify/websockify.go @@ -8,6 +8,7 @@ // - Proper logging. // - Proper error handling in general. // - Support both websocket and regular GET requests on /. +// - Write logs in the standard Tox format. // // Copyright 2022-2025 The TokTok team. // Copyright 2021 Michael.liu. @@ -22,6 +23,9 @@ import ( "log" "net" "net/http" + "os" + "regexp" + "strings" "github.com/gorilla/websocket" ) @@ -31,10 +35,12 @@ var ( targetAddr = flag.String("t", "127.0.0.1:5900", "tcp service address") ) +// Should be enough to fit any Tox TCP packets. +const bufferSize = 2048 + var upgrader = websocket.Upgrader{ - // Should be enough to fit any Tox TCP packets. - ReadBufferSize: 2048, - WriteBufferSize: 2048, + ReadBufferSize: bufferSize, + WriteBufferSize: bufferSize, Subprotocols: []string{"binary"}, CheckOrigin: func(r *http.Request) bool { return true @@ -42,7 +48,7 @@ var upgrader = websocket.Upgrader{ } func forwardTCP(wsconn *websocket.Conn, conn net.Conn) { - var tcpbuffer [2048]byte + var tcpbuffer [bufferSize]byte defer wsconn.Close() defer conn.Close() for { @@ -97,7 +103,52 @@ func serveWs(w http.ResponseWriter, r *http.Request) { } +type logEntry struct { + time string + file string + line string + message string +} + +type logWriter struct{} + +// Write implements the io.Writer interface. +// +// This parses the Go log format and outputs it as the standard Tox format. +// +// Go format: +// "15:02:46.433968 websockify.go:106: Starting up websockify endpoint\n" +// +// Standard Tox format: +// "[15:02:46.433 UTC] (websockify) websockify.go:106 : Debug: Starting up websockify endpoint" +func (writer *logWriter) Write(bytes []byte) (int, error) { + // Parse the Go log format (skipping the last 3 digits of the microseconds). + re := regexp.MustCompile(`^(\d{2}:\d{2}:\d{2}\.\d{3})\d{3} ([^:]+):(\d+): (.*)$`) + matches := re.FindStringSubmatch(strings.TrimSuffix(string(bytes), "\n")) + if len(matches) != 5 { + // If the log format doesn't match, just print it as is. + fmt.Fprintf(os.Stderr, "%s (unparsed)", string(bytes)) + return len(bytes), nil + } + + // Extract the log fields. + entry := logEntry{ + time: matches[1], + file: matches[2], + line: matches[3], + message: matches[4], + } + + // Print the Go log format in the standard Tox format to stderr. + fmt.Fprintf(os.Stderr, "[%s UTC] (websockify) %s:%s : Debug: %s\n", entry.time, entry.file, entry.line, entry.message) + + return len(bytes), nil +} + func main() { + log.SetFlags(log.Ltime | log.Lshortfile | log.LUTC | log.Lmicroseconds) + log.SetOutput(new(logWriter)) + flag.Parse() log.Println("Starting up websockify endpoint") diff --git a/other/deploy/android.sh b/other/deploy/android.sh new file mode 100755 index 0000000..ca5e0e9 --- /dev/null +++ b/other/deploy/android.sh @@ -0,0 +1,102 @@ +#!/bin/bash + +set -eu + +if [ -n "${CI-}" ]; then + sudo apt-get install -y --no-install-recommends ninja-build yasm +fi + +# Set up environment +NDK=$ANDROID_NDK_HOME + +ABI=${1:-"armeabi-v7a"} + +case $ABI in + armeabi-v7a) + TARGET=armv7a-linux-androideabi + NDK_API=21 + ANDROID_VPX_ABI=armv7-android-gcc + ;; + arm64-v8a) + TARGET=aarch64-linux-android + NDK_API=21 + ANDROID_VPX_ABI=arm64-android-gcc + ;; + x86) + TARGET=i686-linux-android + NDK_API=21 + ANDROID_VPX_ABI=x86-android-gcc + ;; + x86_64) + TARGET=x86_64-linux-android + NDK_API=21 + ANDROID_VPX_ABI=x86_64-android-gcc + ;; + *) + exit 1 + ;; +esac + +PREFIX="$PWD/deps-prefix-android-$ABI" + +TOOLCHAIN="$NDK/toolchains/llvm/prebuilt/linux-x86_64" +SYSROOT="$TOOLCHAIN/sysroot" + +export CC="$TOOLCHAIN/bin/$TARGET$NDK_API-clang" +export CXX="$TOOLCHAIN/bin/$TARGET$NDK_API-clang++" +export LDFLAGS=-static-libstdc++ +export PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig" + +# Build libsodium +if [ ! -f "$PREFIX/lib/libsodium.a" ]; then + tar zxf <(wget -O- https://github.com/jedisct1/libsodium/releases/download/1.0.20-RELEASE/libsodium-1.0.20.tar.gz) + pushd libsodium-1.0.20 + ./configure --prefix="$PREFIX" --host="$TARGET" --with-sysroot="$SYSROOT" --disable-shared --disable-pie + make -j"$(nproc)" install + popd + rm -rf libsodium-1.0.20 +fi + +# Build opus +if [ ! -f "$PREFIX/lib/libopus.a" ]; then + tar zxf <(wget -O- https://github.com/xiph/opus/releases/download/v1.5.2/opus-1.5.2.tar.gz) + pushd opus-1.5.2 + CFLAGS="-fPIC" ./configure --prefix="$PREFIX" --host="$TARGET" --with-sysroot="$SYSROOT" --disable-shared + make "-j$(nproc)" + make install + popd + rm -rf opus-1.5.2 +fi + +# Build libvpx +if [ ! -f "$PREFIX/lib/libvpx.a" ]; then + tar zxf <(wget -O- https://github.com/webmproject/libvpx/archive/refs/tags/v1.15.0.tar.gz) + pushd libvpx-1.15.0 + ./configure --prefix="$PREFIX" --libc="$SYSROOT" --target="$ANDROID_VPX_ABI" --disable-examples --disable-unit-tests --enable-pic || + (cat config.log && exit 1) + sed -i -e "s!^AS=as!AS=$CC -c!" ./*.mk + sed -i -e "s!^STRIP=strip!STRIP=$TOOLCHAIN/bin/llvm-strip!" ./*.mk + make "-j$(nproc)" + make install + popd + rm -rf libvpx-1.15.0 +fi + +# Build c-toxcore +rm -rf _build +cmake -B _build -G Ninja \ + -DANDROID_ABI="$ABI" \ + -DCMAKE_TOOLCHAIN_FILE="$NDK/build/cmake/android.toolchain.cmake" \ + -DCMAKE_INSTALL_PREFIX="$PWD/toxcore-android-$ABI" \ + -DCMAKE_PREFIX_PATH="$PREFIX" \ + -DENABLE_STATIC=OFF \ + -DENABLE_SHARED=ON \ + -DMUST_BUILD_TOXAV=ON \ + -DDHT_BOOTSTRAP=OFF \ + -DBOOTSTRAP_DAEMON=OFF \ + -DUNITTEST=OFF \ + -DSTRICT_ABI=ON \ + -DMIN_LOGGER_LEVEL=TRACE \ + -DEXPERIMENTAL_API=ON +cmake --build _build +cmake --install _build diff --git a/other/deploy/apple/.gitignore b/other/deploy/apple/.gitignore new file mode 100644 index 0000000..e7c7f64 --- /dev/null +++ b/other/deploy/apple/.gitignore @@ -0,0 +1,5 @@ +/Tox.xcframework +/toxcore-ios* +/toxcore-iphonesimulator* +/toxcore-macos* +/smoke-test.c diff --git a/other/deploy/apple/Info.plist b/other/deploy/apple/Info.plist new file mode 100644 index 0000000..fcee5dc --- /dev/null +++ b/other/deploy/apple/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + Tox + CFBundleName + Tox + CFBundleIconFile + + CFBundleIdentifier + chat.tox.toxcore + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleSignature + ???? + CFBundleVersion + 0.2.20 + CFBundleShortVersionString + 0.2.20 + CFBundleGetInfoString + Tox Framework + + diff --git a/other/deploy/apple/LICENSE b/other/deploy/apple/LICENSE new file mode 120000 index 0000000..5853aae --- /dev/null +++ b/other/deploy/apple/LICENSE @@ -0,0 +1 @@ +../../../LICENSE \ No newline at end of file diff --git a/other/deploy/apple/download-nightly.sh b/other/deploy/apple/download-nightly.sh new file mode 100755 index 0000000..30ffdcb --- /dev/null +++ b/other/deploy/apple/download-nightly.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Download the nightly builds of Tox for iOS, iPhone simulator, and macOS. + +set -eux -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +cd "$SCRIPT_DIR" + +for arch in arm64 armv7 armv7s; do + if [ ! -d "toxcore-ios-$arch" ]; then + tar -zxf \ + <(curl -L "https://github.com/TokTok/c-toxcore/releases/download/nightly/toxcore-nightly-ios-$arch.tar.gz") + fi +done + +for arch in arm64 x86_64; do + if [ ! -d "toxcore-iphonesimulator-$arch" ]; then + tar -zxf \ + <(curl -L "https://github.com/TokTok/c-toxcore/releases/download/nightly/toxcore-nightly-iphonesimulator-$arch.tar.gz") + fi +done + +for arch in arm64 x86_64; do + if [ ! -d "toxcore-macos-$arch" ]; then + tar -zxf \ + <(curl -L "https://github.com/TokTok/c-toxcore/releases/download/nightly/toxcore-nightly-macos-$arch.tar.gz") + fi +done diff --git a/other/deploy/apple/make-framework.sh b/other/deploy/apple/make-framework.sh new file mode 100755 index 0000000..9989b8a --- /dev/null +++ b/other/deploy/apple/make-framework.sh @@ -0,0 +1,71 @@ +#!/bin/bash +# Make a Tox.xcframework for iOS, iPhone simulator, and macOS from the nightly builds. +# +# Run download-nightly.sh before running this script if you run it locally. + +set -eux -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +cd "$SCRIPT_DIR" + +# Make a Tox.framework for iOS. +rm -rf toxcore-ios/Tox.framework +mkdir -p toxcore-ios/Tox.framework +cp Info.plist toxcore-ios/Tox.framework +cp -r toxcore-ios-arm64/include/tox toxcore-ios/Tox.framework/Headers +lipo -create -output toxcore-ios/Tox.framework/Tox \ + toxcore-ios-arm64/lib/libtoxcore.dylib \ + toxcore-ios-armv7/lib/libtoxcore.dylib \ + toxcore-ios-armv7s/lib/libtoxcore.dylib +install_name_tool -id @rpath/Tox.framework/Tox toxcore-ios/Tox.framework/Tox + +# Make a Tox.framework for iPhone simulator. +rm -rf toxcore-iphonesimulator/Tox.framework +mkdir -p toxcore-iphonesimulator/Tox.framework +cp Info.plist toxcore-iphonesimulator/Tox.framework +cp -r toxcore-iphonesimulator-arm64/include/tox toxcore-iphonesimulator/Tox.framework/Headers +lipo -create -output toxcore-iphonesimulator/Tox.framework/Tox \ + toxcore-iphonesimulator-arm64/lib/libtoxcore.dylib \ + toxcore-iphonesimulator-x86_64/lib/libtoxcore.dylib +install_name_tool -id @rpath/Tox.framework/Tox toxcore-iphonesimulator/Tox.framework/Tox + +# Make a Tox.framework for macOS. +rm -rf toxcore-macos/Tox.framework +mkdir -p toxcore-macos/Tox.framework +cp Info.plist toxcore-macos/Tox.framework +cp -r toxcore-macos-arm64/include/tox toxcore-macos/Tox.framework/Headers +lipo -create -output toxcore-macos/Tox.framework/Tox \ + toxcore-macos-arm64/lib/libtoxcore.dylib \ + toxcore-macos-x86_64/lib/libtoxcore.dylib +install_name_tool -id @rpath/Tox.framework/Tox toxcore-macos/Tox.framework/Tox + +# Make a Tox.xcframework for iOS, iPhone simulator, and macOS. +rm -rf Tox.xcframework +xcodebuild -create-xcframework -output Tox.xcframework \ + -framework toxcore-ios/Tox.framework \ + -framework toxcore-iphonesimulator/Tox.framework \ + -framework toxcore-macos/Tox.framework + +# Test the Tox.xcframework. +cat >smoke-test.c <<'EOF' +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdocumentation-deprecated-sync" +#include +#pragma GCC diagnostic pop + +int main(void) { + Tox *tox = tox_new(NULL, NULL); + if (tox == NULL) { + fprintf(stderr, "tox_new failed\n"); + return 1; + } + tox_kill(tox); + return 0; +} +EOF +pod lib lint toxcore.podspec + +rm smoke-test.c diff --git a/other/deploy/apple/toxcore.podspec b/other/deploy/apple/toxcore.podspec new file mode 100644 index 0000000..764b1cb --- /dev/null +++ b/other/deploy/apple/toxcore.podspec @@ -0,0 +1,24 @@ +Pod::Spec.new do |s| + s.name = "toxcore" + s.version = "0.2.20" + s.summary = "Cocoapods wrapper for toxcore" + s.homepage = "https://github.com/TokTok/c-toxcore" + s.license = 'GPLv3' + s.author = { "Iphigenia Df" => "iphydf@gmail.com" } + s.source = { + :git => "https://github.com/TokTok/c-toxcore.git", + :tag => s.version.to_s, + :submodules => true + } + + s.requires_arc = false + + s.ios.deployment_target = '12.0' + s.osx.deployment_target = '10.15' + + s.vendored_frameworks = 'Tox.xcframework' + s.xcconfig = { 'FRAMEWORK_SEARCH_PATHS' => '"${PODS_ROOT}"' } + s.test_spec 'Tests' do |test_spec| + test_spec.source_files = 'smoke-test.c' + end +end diff --git a/other/deploy/deps.sh b/other/deploy/deps.sh new file mode 100755 index 0000000..3c3d1fc --- /dev/null +++ b/other/deploy/deps.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -eux -o pipefail + +SYSTEM="$1" +ARCH="$2" + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + +DEP_PREFIX="$PWD/deps-prefix-$SYSTEM-$ARCH" + +if [ -d "$DEP_PREFIX" ]; then + exit 0 +fi + +if [ -d ../dockerfiles ]; then + DOCKERFILES="$(realpath ../dockerfiles)" +else + git clone --depth=1 https://github.com/TokTok/dockerfiles "$SCRIPT_DIR/dockerfiles" + DOCKERFILES="$SCRIPT_DIR/dockerfiles" +fi + +for dep in sodium opus vpx; do + mkdir -p "external/$dep" + pushd "external/$dep" + SCRIPT="$DOCKERFILES/qtox/build_$dep.sh" + "$SCRIPT" --arch "$SYSTEM-$ARCH" --libtype "static" --buildtype "release" --prefix "$DEP_PREFIX" --macos "10.15" + popd + rm -rf "external/$dep" +done diff --git a/other/deploy/ios.sh b/other/deploy/ios.sh new file mode 100755 index 0000000..5d642cf --- /dev/null +++ b/other/deploy/ios.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +set -eux -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + +TARGET="$1" + +if [ -n "${CI-}" ]; then + brew install bash coreutils ninja yasm +fi + +SYSTEM="${TARGET%%-*}" +ARCH="${TARGET#*-}" + +"$SCRIPT_DIR/deps.sh" "$SYSTEM" "$ARCH" + +export PKG_CONFIG_PATH="$PWD/deps-prefix-$SYSTEM-$ARCH/lib/pkgconfig" + +if [ "$SYSTEM" = "ios" ]; then + XC_SDK="iphoneos" + TARGET_IPHONE_SIMULATOR=OFF + IOS_FLAGS="-miphoneos-version-min=10.0 -arch $ARCH" +elif [ "$SYSTEM" = "iphonesimulator" ]; then + XC_SDK="iphonesimulator" + TARGET_IPHONE_SIMULATOR=ON + IOS_FLAGS="-arch $ARCH" +else + echo "Unexpected system $SYSTEM" + exit 1 +fi + +BUILD_DIR="_build-$SYSTEM-$ARCH" + +# Build for iOS 10 +cmake \ + -B "$BUILD_DIR" \ + -G Ninja \ + -DCMAKE_INSTALL_PREFIX="$PWD/toxcore-$SYSTEM-$ARCH" \ + -DCMAKE_BUILD_TYPE=Release \ + -DENABLE_STATIC=OFF \ + -DENABLE_SHARED=ON \ + -DMUST_BUILD_TOXAV=ON \ + -DDHT_BOOTSTRAP=OFF \ + -DBOOTSTRAP_DAEMON=OFF \ + -DUNITTEST=OFF \ + -DSTRICT_ABI=ON \ + -DMIN_LOGGER_LEVEL=TRACE \ + -DEXPERIMENTAL_API=ON \ + -DCMAKE_C_FLAGS="$IOS_FLAGS" \ + -DCMAKE_CXX_FLAGS="$IOS_FLAGS" \ + -DCMAKE_EXE_LINKER_FLAGS="$IOS_FLAGS" \ + -DCMAKE_SHARED_LINKER_FLAGS="$IOS_FLAGS" \ + -DCMAKE_OSX_SYSROOT="$(xcrun --sdk "$XC_SDK" --show-sdk-path)" \ + -DCMAKE_OSX_ARCHITECTURES="$ARCH" + +cmake --build "$BUILD_DIR" +cmake --install "$BUILD_DIR" diff --git a/other/deploy/linux.sh b/other/deploy/linux.sh new file mode 100755 index 0000000..667abff --- /dev/null +++ b/other/deploy/linux.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -eux -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + +ARCH="$1" +"$SCRIPT_DIR/deps.sh" linux "$ARCH" + +export PKG_CONFIG_PATH="$PWD/deps-prefix-linux-$ARCH/lib/pkgconfig" + +# Build +cmake \ + -B _build \ + -G Ninja \ + -DCMAKE_INSTALL_PREFIX="$PWD/toxcore-linux-$ARCH" \ + -DCMAKE_BUILD_TYPE=Release \ + -DENABLE_STATIC=OFF \ + -DENABLE_SHARED=ON \ + -DMUST_BUILD_TOXAV=ON \ + -DDHT_BOOTSTRAP=OFF \ + -DBOOTSTRAP_DAEMON=OFF \ + -DUNITTEST=OFF \ + -DSTRICT_ABI=ON \ + -DMIN_LOGGER_LEVEL=TRACE \ + -DEXPERIMENTAL_API=ON + +cmake --build _build +cmake --install _build diff --git a/other/deploy/macos.sh b/other/deploy/macos.sh new file mode 100755 index 0000000..0241ced --- /dev/null +++ b/other/deploy/macos.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +set -eux -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + +ARCH="$1" + +if [ -n "${CI-}" ]; then + brew install bash coreutils ninja yasm +fi + +"$SCRIPT_DIR/deps.sh" macos "$ARCH" + +export PKG_CONFIG_PATH="$PWD/deps-prefix-macos-$ARCH/lib/pkgconfig" + +BUILD_DIR="_build-macos-$ARCH" + +# Build for macOS +cmake \ + -B "$BUILD_DIR" \ + -G Ninja \ + -DCMAKE_INSTALL_PREFIX="$PWD/toxcore-macos-$ARCH" \ + -DCMAKE_BUILD_TYPE=Release \ + -DENABLE_STATIC=OFF \ + -DENABLE_SHARED=ON \ + -DMUST_BUILD_TOXAV=ON \ + -DDHT_BOOTSTRAP=OFF \ + -DBOOTSTRAP_DAEMON=OFF \ + -DUNITTEST=OFF \ + -DSTRICT_ABI=ON \ + -DMIN_LOGGER_LEVEL=TRACE \ + -DEXPERIMENTAL_API=ON \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 + +cmake --build "$BUILD_DIR" +cmake --install "$BUILD_DIR" diff --git a/other/deploy/single-file/.gitignore b/other/deploy/single-file/.gitignore new file mode 100644 index 0000000..2526423 --- /dev/null +++ b/other/deploy/single-file/.gitignore @@ -0,0 +1 @@ +!/Makefile diff --git a/other/deploy/single-file/Makefile b/other/deploy/single-file/Makefile new file mode 100644 index 0000000..51810e3 --- /dev/null +++ b/other/deploy/single-file/Makefile @@ -0,0 +1,26 @@ +TARGETS = libtoxcore.a libtoxcore-minimal.a + +all: $(TARGETS) + +libtoxcore.o: $(wildcard toxcore-*av.c) + $(CC) -c -o $@ $< \ + -O2 \ + -Wno-discarded-qualifiers \ + -fPIC \ + -Wl,-Bstatic \ + $(shell pkg-config --cflags --libs libsodium) \ + -Wl,-Bdynamic \ + $(shell pkg-config --cflags --libs opus vpx) \ + -pthread + +libtoxcore-minimal.o: $(wildcard toxcore-*core.c) + $(CC) -c -o $@ $< \ + -O2 \ + -Wno-discarded-qualifiers \ + -fPIC \ + -Wl,-Bstatic \ + $(shell pkg-config --cflags --libs libsodium) \ + -pthread + +%.a: %.o + $(AR) rcs $@ $^ diff --git a/other/make_single_file b/other/deploy/single-file/make_single_file similarity index 66% rename from other/make_single_file rename to other/deploy/single-file/make_single_file index 7487ca5..7143da4 100755 --- a/other/make_single_file +++ b/other/deploy/single-file/make_single_file @@ -6,10 +6,10 @@ # # Example: # -# other/make_single_file auto_tests/toxav_basic_test.c auto_tests/auto_test_support.c testing/misc_tools.c | \ +# other/deploy/single-file/make_single_file auto_tests/toxav_basic_test.c auto_tests/auto_test_support.c testing/misc_tools.c | \ # tcc -o toxav_basic_test - $(pkg-config --cflags --libs libsodium opus vpx) # -# other/make_single_file -core auto_tests/send_message_test.c auto_tests/auto_test_support.c testing/misc_tools.c | \ +# other/deploy/single-file/make_single_file -core auto_tests/send_message_test.c auto_tests/auto_test_support.c testing/misc_tools.c | \ # tcc -o send_message_test - $(pkg-config --cflags --libs libsodium) use strict; @@ -45,15 +45,16 @@ sub emit { } } +my @core = (, , , ); if (@ARGV and $ARGV[0] eq "-core") { shift @ARGV; - for my $fn (, , ) { - emit(abs_path $fn); - } + emit(abs_path $_) for @core; } else { - for my $fn (, , , , ) { - emit(abs_path $fn); + if (@ARGV and $ARGV[0] eq "-av") { + # Ignore -av, it's the default. + shift @ARGV; } + emit(abs_path $_) for (, @core); } emit(abs_path $_) for @ARGV; diff --git a/other/docker/alpine-s390x/Dockerfile b/other/docker/alpine-s390x/alpine-s390x.Dockerfile similarity index 100% rename from other/docker/alpine-s390x/Dockerfile rename to other/docker/alpine-s390x/alpine-s390x.Dockerfile diff --git a/other/docker/alpine-s390x/alpine-s390x.Dockerfile.dockerignore b/other/docker/alpine-s390x/alpine-s390x.Dockerfile.dockerignore new file mode 100644 index 0000000..77bc011 --- /dev/null +++ b/other/docker/alpine-s390x/alpine-s390x.Dockerfile.dockerignore @@ -0,0 +1,24 @@ +# ===== common ===== +# Ignore everything ... +**/* +# ... except sources +!**/*.[ch] +!**/*.cc +!**/*.hh +!CHANGELOG.md +!LICENSE +!README.md +!auto_tests/data/* +!other/bootstrap_daemon/bash-completion/** +!other/bootstrap_daemon/tox-bootstrapd.* +!other/proxy/*.mod +!other/proxy/*.sum +!other/proxy/*.go +# ... and CMake build files (used by most builds). +!**/CMakeLists.txt +!.github/scripts/flags*.sh +!cmake/*.cmake +!other/pkgconfig/* +!other/rpm/* +!so.version +!.github/scripts/cmake-alpine-s390x diff --git a/other/docker/alpine-s390x/dockerignore b/other/docker/alpine-s390x/dockerignore new file mode 100644 index 0000000..8e9bb99 --- /dev/null +++ b/other/docker/alpine-s390x/dockerignore @@ -0,0 +1 @@ +!.github/scripts/cmake-alpine-s390x diff --git a/other/docker/alpine-s390x/run b/other/docker/alpine-s390x/run index f77eede..5a0f34b 100755 --- a/other/docker/alpine-s390x/run +++ b/other/docker/alpine-s390x/run @@ -1,5 +1,3 @@ -#!/bin/sh +#!/usr/bin/env bash -set -eux -BUILD=alpine-s390x -docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/Dockerfile" . +. "$(cd "$(dirname "${BASH_SOURCE[0]}")/../sources" && pwd)/run.sh" diff --git a/other/docker/cppcheck/toxcore.cfg b/other/docker/cppcheck/toxcore.cfg index b497f9e..f120246 100644 --- a/other/docker/cppcheck/toxcore.cfg +++ b/other/docker/cppcheck/toxcore.cfg @@ -92,10 +92,6 @@ new_networking_no_udp kill_networking - - net_new_strerror - net_kill_strerror - new_onion kill_onion diff --git a/other/docker/goblint/goblint.Dockerfile b/other/docker/goblint/goblint.Dockerfile index eb62751..77713f4 100644 --- a/other/docker/goblint/goblint.Dockerfile +++ b/other/docker/goblint/goblint.Dockerfile @@ -11,9 +11,9 @@ RUN apt-get update && \ WORKDIR /work COPY --from=sources /src/ /work/ -COPY other/make_single_file /work/other/ +COPY other/deploy/single-file/make_single_file /work/ -RUN other/make_single_file -core auto_tests/tox_new_test.c other/docker/goblint/sodium.c > analysis.c +RUN ./make_single_file -core auto_tests/tox_new_test.c other/docker/goblint/sodium.c > analysis.c # Try compiling+linking just to make sure we have all the fake functions. RUN tcc analysis.c diff --git a/other/docker/goblint/sodium.c b/other/docker/goblint/sodium.c index eb70c27..c0c45d4 100644 --- a/other/docker/goblint/sodium.c +++ b/other/docker/goblint/sodium.c @@ -98,6 +98,17 @@ int crypto_hash_sha512(unsigned char *out, const unsigned char *in, { return 0; } +int crypto_pwhash_scryptsalsa208sha256(unsigned char *const out, + unsigned long long outlen, + const char *const passwd, + unsigned long long passwdlen, + const unsigned char *const salt, + unsigned long long opslimit, + size_t memlimit) +{ + memset(out, 0, outlen); + return 0; +} void randombytes(unsigned char *const buf, const unsigned long long buf_len) { memset(buf, 0, buf_len); diff --git a/other/docker/modules/check b/other/docker/modules/check index e62be62..703ecb5 100755 --- a/other/docker/modules/check +++ b/other/docker/modules/check @@ -12,24 +12,24 @@ MODS = {} STD_MODULE = """module std [system] { textual header "/usr/include/alloca.h" textual header "/usr/include/assert.h" - textual header "/usr/include/c++/13.2.1/algorithm" - textual header "/usr/include/c++/13.2.1/array" - textual header "/usr/include/c++/13.2.1/chrono" - textual header "/usr/include/c++/13.2.1/cstddef" - textual header "/usr/include/c++/13.2.1/cstdint" - textual header "/usr/include/c++/13.2.1/cstdio" - textual header "/usr/include/c++/13.2.1/cstdlib" - textual header "/usr/include/c++/13.2.1/cstring" - textual header "/usr/include/c++/13.2.1/iomanip" - textual header "/usr/include/c++/13.2.1/iosfwd" - textual header "/usr/include/c++/13.2.1/limits" - textual header "/usr/include/c++/13.2.1/memory" - textual header "/usr/include/c++/13.2.1/ostream" - textual header "/usr/include/c++/13.2.1/random" - textual header "/usr/include/c++/13.2.1/stdlib.h" - textual header "/usr/include/c++/13.2.1/thread" - textual header "/usr/include/c++/13.2.1/type_traits" - textual header "/usr/include/c++/13.2.1/vector" + textual header "/usr/include/c++/14.2.0/algorithm" + textual header "/usr/include/c++/14.2.0/array" + textual header "/usr/include/c++/14.2.0/chrono" + textual header "/usr/include/c++/14.2.0/cstddef" + textual header "/usr/include/c++/14.2.0/cstdint" + textual header "/usr/include/c++/14.2.0/cstdio" + textual header "/usr/include/c++/14.2.0/cstdlib" + textual header "/usr/include/c++/14.2.0/cstring" + textual header "/usr/include/c++/14.2.0/iomanip" + textual header "/usr/include/c++/14.2.0/iosfwd" + textual header "/usr/include/c++/14.2.0/limits" + textual header "/usr/include/c++/14.2.0/memory" + textual header "/usr/include/c++/14.2.0/ostream" + textual header "/usr/include/c++/14.2.0/random" + textual header "/usr/include/c++/14.2.0/stdlib.h" + textual header "/usr/include/c++/14.2.0/thread" + textual header "/usr/include/c++/14.2.0/type_traits" + textual header "/usr/include/c++/14.2.0/vector" textual header "/usr/include/errno.h" textual header "/usr/include/fortify/stdio.h" textual header "/usr/include/fortify/string.h" diff --git a/other/docker/modules/dockerignore b/other/docker/modules/dockerignore new file mode 100644 index 0000000..6981606 --- /dev/null +++ b/other/docker/modules/dockerignore @@ -0,0 +1,2 @@ +!other/docker/modules/check +!**/BUILD.bazel diff --git a/other/docker/modules/modules.Dockerfile b/other/docker/modules/modules.Dockerfile index ca4a705..8bc8af5 100644 --- a/other/docker/modules/modules.Dockerfile +++ b/other/docker/modules/modules.Dockerfile @@ -1,5 +1,4 @@ -FROM toxchat/c-toxcore:sources AS sources -FROM alpine:3.19.0 +FROM alpine:3.21.0 RUN ["apk", "add", "--no-cache", \ "bash", \ @@ -15,7 +14,7 @@ RUN ["apk", "add", "--no-cache", \ "python3"] WORKDIR /work -COPY --from=sources /src/ /work/ +COPY . /work/ COPY toxcore/BUILD.bazel /work/toxcore/ COPY other/docker/modules/check /work/other/docker/modules/ diff --git a/other/docker/modules/modules.Dockerfile.dockerignore b/other/docker/modules/modules.Dockerfile.dockerignore new file mode 100644 index 0000000..cef84a4 --- /dev/null +++ b/other/docker/modules/modules.Dockerfile.dockerignore @@ -0,0 +1,25 @@ +# ===== common ===== +# Ignore everything ... +**/* +# ... except sources +!**/*.[ch] +!**/*.cc +!**/*.hh +!CHANGELOG.md +!LICENSE +!README.md +!auto_tests/data/* +!other/bootstrap_daemon/bash-completion/** +!other/bootstrap_daemon/tox-bootstrapd.* +!other/proxy/*.mod +!other/proxy/*.sum +!other/proxy/*.go +# ... and CMake build files (used by most builds). +!**/CMakeLists.txt +!.github/scripts/flags*.sh +!cmake/*.cmake +!other/pkgconfig/* +!other/rpm/* +!so.version +!other/docker/modules/check +!**/BUILD.bazel diff --git a/other/docker/modules/run b/other/docker/modules/run index cfe53a1..5a0f34b 100755 --- a/other/docker/modules/run +++ b/other/docker/modules/run @@ -1,6 +1,3 @@ -#!/bin/sh +#!/usr/bin/env bash -set -eux -BUILD=modules -other/docker/sources/build -docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . +. "$(cd "$(dirname "${BASH_SOURCE[0]}")/../sources" && pwd)/run.sh" diff --git a/other/docker/pkgsrc/dockerignore b/other/docker/pkgsrc/dockerignore new file mode 100644 index 0000000..67d10a9 --- /dev/null +++ b/other/docker/pkgsrc/dockerignore @@ -0,0 +1 @@ +!other/docker/pkgsrc/pkgsrc.patch diff --git a/other/docker/pkgsrc/pkgsrc.Dockerfile b/other/docker/pkgsrc/pkgsrc.Dockerfile index 3483bdf..2c1c2df 100644 --- a/other/docker/pkgsrc/pkgsrc.Dockerfile +++ b/other/docker/pkgsrc/pkgsrc.Dockerfile @@ -1,11 +1,14 @@ FROM toxchat/pkgsrc:latest WORKDIR /work -COPY . /work/c-toxcore-0.2.18 -RUN ["tar", "zcf", "c-toxcore.tar.gz", "c-toxcore-0.2.18"] +COPY . /work/c-toxcore-0.2.21 +RUN ["tar", "zcf", "c-toxcore.tar.gz", "c-toxcore-0.2.21"] + +WORKDIR /work/pkgsrc +COPY other/docker/pkgsrc/pkgsrc.patch /tmp/pkgsrc.patch +RUN ["patch", "-p1", "-i", "/tmp/pkgsrc.patch"] WORKDIR /work/pkgsrc/chat/toxcore -RUN ["sed", "-i", "-e", "s/libtoxcore.so.2.18.0/libtoxcore.so.2.20.0/g", "PLIST"] RUN ["bmake", "clean"] RUN ["bmake", "DISTFILES=c-toxcore.tar.gz", "DISTDIR=/work", "NO_CHECKSUM=yes"] -RUN ["bmake", "install"] +RUN ["bmake", "DISTFILES=c-toxcore.tar.gz", "DISTDIR=/work", "NO_CHECKSUM=yes", "install"] diff --git a/other/docker/pkgsrc/pkgsrc.Dockerfile.dockerignore b/other/docker/pkgsrc/pkgsrc.Dockerfile.dockerignore index 3a3643c..8d70daf 100644 --- a/other/docker/pkgsrc/pkgsrc.Dockerfile.dockerignore +++ b/other/docker/pkgsrc/pkgsrc.Dockerfile.dockerignore @@ -21,3 +21,4 @@ !other/pkgconfig/* !other/rpm/* !so.version +!other/docker/pkgsrc/pkgsrc.patch diff --git a/other/docker/pkgsrc/pkgsrc.patch b/other/docker/pkgsrc/pkgsrc.patch new file mode 100644 index 0000000..be2b297 --- /dev/null +++ b/other/docker/pkgsrc/pkgsrc.patch @@ -0,0 +1,31 @@ +diff --git a/chat/toxcore/Makefile b/chat/toxcore/Makefile +index 70466704d..53a08ad08 100644 +--- a/chat/toxcore/Makefile ++++ b/chat/toxcore/Makefile +@@ -1,6 +1,6 @@ + # $NetBSD: Makefile,v 1.6 2024/01/22 13:16:56 ryoon Exp $ + +-DISTNAME= toxcore-0.2.18 ++DISTNAME= toxcore-0.2.21 + PKGREVISION= 2 + CATEGORIES= chat + MASTER_SITES= ${MASTER_SITE_GITHUB:=TokTok/} +diff --git a/chat/toxcore/PLIST b/chat/toxcore/PLIST +index f0a5e4f04..4122b0867 100644 +--- a/chat/toxcore/PLIST ++++ b/chat/toxcore/PLIST +@@ -4,11 +4,11 @@ bin/tox-bootstrapd + include/tox/tox.h +-include/tox/tox_dispatch.h +-include/tox/tox_events.h ++include/tox/tox_log_level.h ++include/tox/tox_options.h + include/tox/toxav.h + include/tox/toxencryptsave.h + lib/libtoxcore.a + lib/libtoxcore.so + lib/libtoxcore.so.2 +-lib/libtoxcore.so.2.18.0 ++lib/libtoxcore.so.2.21.0 + lib/pkgconfig/toxcore.pc + share/bash-completion/completions/tox-bootstrapd diff --git a/other/docker/sparse/sparse.Dockerfile b/other/docker/sparse/sparse.Dockerfile index e4e185a..3b7bca1 100644 --- a/other/docker/sparse/sparse.Dockerfile +++ b/other/docker/sparse/sparse.Dockerfile @@ -27,8 +27,8 @@ RUN make install -j4 PREFIX=/usr/local WORKDIR /work/c-toxcore COPY --from=sources /src/ /work/c-toxcore -#COPY other/make_single_file /work/c-toxcore/other/ -#RUN other/make_single_file auto_tests/tox_new_test.c > crash.c +#COPY other/deploy/single-file/make_single_file /work/c-toxcore/ +#RUN ./make_single_file auto_tests/tox_new_test.c > crash.c #RUN sparsec $(pkg-config --cflags --libs libsodium opus vpx) crash.c COPY other/docker/sparse/Makefile /work/c-toxcore/ diff --git a/other/docker/tcc/tcc.Dockerfile b/other/docker/tcc/tcc.Dockerfile index 425256b..68ed2b5 100644 --- a/other/docker/tcc/tcc.Dockerfile +++ b/other/docker/tcc/tcc.Dockerfile @@ -33,9 +33,9 @@ RUN tcc \ $(pkg-config --cflags --libs libsodium opus vpx) \ && ./send_message_test | grep 'tox clients connected' -COPY other/make_single_file /work/other/ +COPY other/deploy/single-file/make_single_file /work/ RUN \ - other/make_single_file -core \ + ./make_single_file -core \ auto_tests/auto_test_support.c \ auto_tests/send_message_test.c \ testing/misc_tools.c | \ @@ -47,7 +47,7 @@ RUN \ && ./send_message_test | grep 'tox clients connected' RUN \ - other/make_single_file \ + ./make_single_file \ auto_tests/auto_test_support.c \ auto_tests/toxav_basic_test.c \ testing/misc_tools.c | \ diff --git a/other/docker/wasm/run b/other/docker/wasm/run new file mode 100755 index 0000000..5a0f34b --- /dev/null +++ b/other/docker/wasm/run @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +. "$(cd "$(dirname "${BASH_SOURCE[0]}")/../sources" && pwd)/run.sh" diff --git a/other/docker/wasm/wasm.Dockerfile b/other/docker/wasm/wasm.Dockerfile new file mode 100644 index 0000000..ef74770 --- /dev/null +++ b/other/docker/wasm/wasm.Dockerfile @@ -0,0 +1,136 @@ +FROM ubuntu:20.04 + +ENV DEBIAN_FRONTEND="noninteractive" + +# Install dependencies. +RUN apt-get update && apt-get install --no-install-recommends -y \ + autoconf \ + automake \ + ca-certificates \ + cmake \ + curl \ + git \ + libtool \ + make \ + ninja-build \ + pkg-config \ + python3 \ + unzip \ + wget \ + xz-utils \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /work/emsdk +RUN git clone --depth=1 https://github.com/emscripten-core/emsdk /work/emsdk \ + && ./emsdk install 4.0.3 \ + && ./emsdk activate 4.0.3 + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] +WORKDIR /work + +# Build libsodium. +RUN . "/work/emsdk/emsdk_env.sh" \ + && tar zxf <(curl -L https://github.com/jedisct1/libsodium/releases/download/1.0.20-RELEASE/libsodium-1.0.20.tar.gz) \ + && cd /work/libsodium-* \ + && emconfigure ./configure \ + --prefix=/wasm \ + --enable-static \ + --disable-shared \ + --without-pthreads \ + --disable-ssp \ + --disable-asm \ + --disable-pie \ + && emmake make -j"$(nproc)" \ + && emmake make install \ + && rm -rf /work/libsodium-* + +# Build libvpx. +RUN . "/work/emsdk/emsdk_env.sh" \ + && tar zxf <(curl -L https://github.com/webmproject/libvpx/archive/v1.15.0.tar.gz) \ + && cd /work/libvpx-* \ + && emconfigure ./configure \ + --prefix=/wasm \ + --enable-static \ + --disable-shared \ + --target=generic-gnu \ + --disable-examples \ + --disable-tools \ + --disable-docs \ + --disable-unit-tests \ + --enable-pic \ + && emmake make -j"$(nproc)" \ + && emmake make install \ + && rm -rf /work/libvpx-* + +# Build opus. +RUN . "/work/emsdk/emsdk_env.sh" \ + && tar zxf <(curl -L https://github.com/xiph/opus/releases/download/v1.5.2/opus-1.5.2.tar.gz) \ + && cd /work/opus-* \ + && emconfigure ./configure \ + --prefix=/wasm \ + --enable-static \ + --disable-shared \ + --host wasm32-unknown-emscripten \ + --disable-extra-programs \ + --disable-doc \ + CFLAGS="-O3 -flto -fPIC" \ + && emmake make -j"$(nproc)" \ + && emmake make install \ + && rm -rf /work/opus-* + +# Build an unused binding without toxcore first so emcc caches all the system +# libraries. This makes rebuilds of toxcore below much faster. +RUN . "/work/emsdk/emsdk_env.sh" \ + && mkdir -p /wasm/bin \ + && emcc -O3 -flto \ + -s EXPORT_NAME=libtoxcore \ + -s MAIN_MODULE=1 \ + -s MALLOC=emmalloc \ + -s MODULARIZE=1 \ + -s STRICT=1 \ + -s WEBSOCKET_URL=ws:// \ + --no-entry \ + /wasm/lib/libopus.a \ + /wasm/lib/libsodium.a \ + /wasm/lib/libvpx.a \ + -o /wasm/bin/libtoxcore.js + +ENV PKG_CONFIG_PATH="/wasm/lib/pkgconfig" + +# Build c-toxcore. +COPY . /work/c-toxcore +RUN . "/work/emsdk/emsdk_env.sh" \ + && cd /work/c-toxcore \ + && emcmake cmake \ + -B_build \ + -GNinja \ + -DCMAKE_INSTALL_PREFIX="/wasm" \ + -DCMAKE_C_FLAGS="-O3 -flto -fPIC" \ + -DCMAKE_UNITY_BUILD=ON \ + -DMUST_BUILD_TOXAV=ON \ + -DENABLE_SHARED=OFF \ + -DBOOTSTRAP_DAEMON=OFF \ + -DMIN_LOGGER_LEVEL=TRACE \ + . \ + && emmake cmake --build _build \ + && emmake cmake --install _build + +# Link together all the libraries. +RUN . "/work/emsdk/emsdk_env.sh" \ + && mkdir -p /wasm/bin \ + && emcc -O3 -flto \ + -s EXPORT_NAME=libtoxcore \ + -s EXPORTED_RUNTIME_METHODS='["HEAPU8", "wasmExports"]' \ + -s MAIN_MODULE=1 \ + -s MALLOC=emmalloc \ + -s MODULARIZE=1 \ + -s STRICT=1 \ + -s WEBSOCKET_URL=ws:// \ + --no-entry \ + /wasm/lib/libopus.a \ + /wasm/lib/libsodium.a \ + /wasm/lib/libvpx.a \ + /wasm/lib/libtoxcore.a \ + -o /wasm/bin/libtoxcore.js +RUN ls -lh /wasm/bin/libtoxcore.js /wasm/bin/libtoxcore.wasm diff --git a/other/docker/wasm/wasm.Dockerfile.dockerignore b/other/docker/wasm/wasm.Dockerfile.dockerignore new file mode 100644 index 0000000..3a3643c --- /dev/null +++ b/other/docker/wasm/wasm.Dockerfile.dockerignore @@ -0,0 +1,23 @@ +# ===== common ===== +# Ignore everything ... +**/* +# ... except sources +!**/*.[ch] +!**/*.cc +!**/*.hh +!CHANGELOG.md +!LICENSE +!README.md +!auto_tests/data/* +!other/bootstrap_daemon/bash-completion/** +!other/bootstrap_daemon/tox-bootstrapd.* +!other/proxy/*.mod +!other/proxy/*.sum +!other/proxy/*.go +# ... and CMake build files (used by most builds). +!**/CMakeLists.txt +!.github/scripts/flags*.sh +!cmake/*.cmake +!other/pkgconfig/* +!other/rpm/* +!so.version diff --git a/other/emscripten/Dockerfile b/other/emscripten/Dockerfile deleted file mode 100644 index adfbdba..0000000 --- a/other/emscripten/Dockerfile +++ /dev/null @@ -1,85 +0,0 @@ -FROM ubuntu:20.04 - -ENV DEBIAN_FRONTEND="noninteractive" - -# Install dependencies. -RUN apt-get update && apt-get install --no-install-recommends -y \ - autoconf \ - automake \ - ca-certificates \ - cmake \ - curl \ - git \ - libtool \ - make \ - ninja-build \ - pkg-config \ - python3 \ - unzip \ - wget \ - xz-utils \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -WORKDIR /work/emsdk -RUN git clone --depth=1 https://github.com/emscripten-core/emsdk /work/emsdk \ - && ./emsdk install 3.1.3 \ - && ./emsdk activate 3.1.3 - -# Build libsodium. -RUN . "/work/emsdk/emsdk_env.sh" \ - && git clone --depth=1 --branch=1.0.18 https://github.com/jedisct1/libsodium /work/libsodium \ - && cd /work/libsodium \ - && autoreconf -fi \ - && emconfigure ./configure --disable-shared \ - --without-pthreads \ - --disable-ssp --disable-asm --disable-pie \ - --host x86_64-linux-gnu \ - && emmake make install -j8 - -# Build an unused libsodium binding first so emcc caches all the system -# libraries. This makes rebuilds of toxcore below much faster. -RUN . "/work/emsdk/emsdk_env.sh" \ - && mkdir -p /work/wasm \ - && emcc -O3 -flto \ - --closure=1 \ - -s ALLOW_UNIMPLEMENTED_SYSCALLS=1 \ - -s EXPORT_NAME=libtoxcore \ - -s IGNORE_MISSING_MAIN=1 \ - -s MAIN_MODULE=1 \ - -s MALLOC=emmalloc \ - -s MODULARIZE=1 \ - -s STRICT=1 \ - -s WEBSOCKET_URL=wss:// \ - /usr/local/lib/libsodium.a \ - -o /work/wasm/libsodium.js - -# Build c-toxcore. -COPY . /work/c-toxcore -RUN . "/work/emsdk/emsdk_env.sh" \ - && cd /work/c-toxcore \ - && emcmake cmake -B_build -H. -GNinja \ - -DCMAKE_INSTALL_PREFIX:PATH="/usr/local" \ - -DCMAKE_C_FLAGS="-O3 -flto -fPIC" \ - -DBUILD_TOXAV=OFF \ - -DENABLE_SHARED=OFF \ - -DBOOTSTRAP_DAEMON=OFF \ - -DMIN_LOGGER_LEVEL=DEBUG \ - && emmake cmake --build _build --parallel 8 --target install - -# Build wasm bindings. -RUN . "/work/emsdk/emsdk_env.sh" \ - && mkdir -p /work/wasm \ - && emcc -O3 -flto \ - --closure=1 \ - -s ALLOW_UNIMPLEMENTED_SYSCALLS=1 \ - -s EXPORT_NAME=libtoxcore \ - -s IGNORE_MISSING_MAIN=1 \ - -s MAIN_MODULE=1 \ - -s MALLOC=emmalloc \ - -s MODULARIZE=1 \ - -s STRICT=1 \ - -s WEBSOCKET_URL=wss:// \ - /usr/local/lib/libsodium.a \ - /usr/local/lib/libtoxcore.a \ - -o /work/wasm/libtoxcore.js diff --git a/other/emscripten/build b/other/emscripten/build deleted file mode 100755 index 18ea242..0000000 --- a/other/emscripten/build +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -docker build -t toxchat/toxcore-js -f other/emscripten/Dockerfile . diff --git a/other/proxy/proxy_server.go b/other/proxy/proxy_server.go index 04d9b2f..9bf927c 100644 --- a/other/proxy/proxy_server.go +++ b/other/proxy/proxy_server.go @@ -15,8 +15,8 @@ import ( const ( debug = false - httpAddr = ":8080" - socks5Addr = ":8081" + httpAddr = ":7080" + socks5Addr = ":7081" ) func handleTunneling(w http.ResponseWriter, r *http.Request) { diff --git a/other/version-sync b/other/version-sync index 9a98b05..df7e4cd 100755 --- a/other/version-sync +++ b/other/version-sync @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash set -eu @@ -13,25 +13,31 @@ update() { file="$SOURCE_DIR/$1" expr="$2" - sed -e "$expr" "$file" > "$file.updated-version" + sed -e "$expr" "$file" >"$file.updated-version" if diff "$file" "$file.updated-version"; then rm "$file.updated-version" else # use cat > and rm instead of move to keep file permissions - cat "$file.updated-version" > "$file" + cat "$file.updated-version" >"$file" rm "$file.updated-version" fi } -update 'configure.ac' 's/AC_INIT(\[tox\], \[.*\])/AC_INIT([tox], ['$VER'])/' +update 'configure.ac' 's/AC_INIT(\[tox\], \[.*\])/AC_INIT([tox], ['"$VER"'])/' -update 'toxcore/tox.api.h' 's/\(const VERSION_MAJOR *= \).*;/\1'$MAJOR';/' -update 'toxcore/tox.api.h' 's/\(const VERSION_MINOR *= \).*;/\1'$MINOR';/' -update 'toxcore/tox.api.h' 's/\(const VERSION_PATCH *= \).*;/\1'$PATCH';/' +update 'toxcore/tox.h' 's/\(#define TOX_VERSION_MAJOR *\).*/\1'"$MAJOR"'/' +update 'toxcore/tox.h' 's/\(#define TOX_VERSION_MINOR *\).*/\1'"$MINOR"'/' +update 'toxcore/tox.h' 's/\(#define TOX_VERSION_PATCH *\).*/\1'"$PATCH"'/' -update 'CMakeLists.txt' 's/\(PROJECT_VERSION_MAJOR "\).*"/\1'$MAJOR'"/' -update 'CMakeLists.txt' 's/\(PROJECT_VERSION_MINOR "\).*"/\1'$MINOR'"/' -update 'CMakeLists.txt' 's/\(PROJECT_VERSION_PATCH "\).*"/\1'$PATCH'"/' +update 'CMakeLists.txt' 's/\(PROJECT_VERSION_MAJOR "\).*"/\1'"$MAJOR"'"/' +update 'CMakeLists.txt' 's/\(PROJECT_VERSION_MINOR "\).*"/\1'"$MINOR"'"/' +update 'CMakeLists.txt' 's/\(PROJECT_VERSION_PATCH "\).*"/\1'"$PATCH"'"/' + +update 'other/docker/pkgsrc/pkgsrc.Dockerfile' 's/\(COPY . \/work\/c-toxcore-\).*/\1'"$VER"'/' +update 'other/docker/pkgsrc/pkgsrc.Dockerfile' 's/\(tar", "zcf", "c-toxcore.tar.gz", "c-toxcore-\).*/\1'"$VER"'"]/' + +update 'other/docker/pkgsrc/pkgsrc.patch' 's/\(+DISTNAME=\ttoxcore-\).*/\1'"$VER"'/' +update 'other/docker/pkgsrc/pkgsrc.patch' 's/\(+lib\/libtoxcore.so.\).*/\1'"$MINOR.$PATCH.0"'/' # # calculating the SO version @@ -64,14 +70,14 @@ update 'CMakeLists.txt' 's/\(PROJECT_VERSION_PATCH "\).*"/\1'$PATCH'"/' # this must be constant starting from the 1.0 release LAST_SOMAJOR=2 -if [ $MAJOR -eq 0 ]; then +if [ "$MAJOR" -eq 0 ]; then SOMAJOR=$MINOR SOMINOR=$PATCH # update lastmajor above - update 'other/version-sync' 's/^\(LAST_SOMAJOR=\).*/\1'$SOMAJOR'/' + update 'other/version-sync' 's/^\(LAST_SOMAJOR=\).*/\1'"$SOMAJOR"'/' else - SOMAJOR=$(expr $MAJOR + $LAST_SOMAJOR) + SOMAJOR=$(("$MAJOR" + "$LAST_SOMAJOR")) SOMINOR=$MINOR fi @@ -115,16 +121,16 @@ fi # <=> major.minor.patch # -if [ $MAJOR -eq 0 ]; then - LIBTOOL_CURRENT=$(expr $SOMAJOR + $SOMINOR) +if [ "$MAJOR" -eq 0 ]; then + LIBTOOL_CURRENT=$(("$SOMAJOR" + "$SOMINOR")) LIBTOOL_AGE=$SOMINOR LIBTOOL_REVISION=0 else - LIBTOOL_CURRENT=$(expr $SOMAJOR + $SOMINOR) + LIBTOOL_CURRENT=$(("$SOMAJOR" + "$SOMINOR")) LIBTOOL_AGE=$SOMINOR LIBTOOL_REVISION=$PATCH fi -update 'so.version' 's/^\(CURRENT=\).*/\1'$LIBTOOL_CURRENT'/' -update 'so.version' 's/^\(AGE=\).*/\1'$LIBTOOL_AGE'/' -update 'so.version' 's/^\(REVISION=\).*/\1'$LIBTOOL_REVISION'/' +update 'so.version' 's/^\(CURRENT=\).*/\1'"$LIBTOOL_CURRENT"'/' +update 'so.version' 's/^\(AGE=\).*/\1'"$LIBTOOL_AGE"'/' +update 'so.version' 's/^\(REVISION=\).*/\1'"$LIBTOOL_REVISION"'/' diff --git a/so.version b/so.version index 3415d97..7e5d922 100644 --- a/so.version +++ b/so.version @@ -11,6 +11,6 @@ # For a full reference see: # https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info -CURRENT=22 +CURRENT=23 REVISION=0 -AGE=20 +AGE=21 diff --git a/testing/fuzzing/CMakeLists.txt b/testing/fuzzing/CMakeLists.txt index 3ab9ecd..32a3109 100644 --- a/testing/fuzzing/CMakeLists.txt +++ b/testing/fuzzing/CMakeLists.txt @@ -20,10 +20,13 @@ function(fuzz_test target source_dir) endfunction() fuzz_test(bootstrap .) # Fuzzes the bootstrap process -fuzz_test(toxsave .) # Fuzzes the bootstrap process +# TODO(iphydf): Fix this in the cmake build. +# fuzz_test(e2e .) # Fuzzes an end-to-end connection +fuzz_test(toxsave .) # Fuzzes tox_new and tox_get_savedata fuzz_test(DHT ../../toxcore) fuzz_test(forwarding ../../toxcore) fuzz_test(group_announce ../../toxcore) fuzz_test(group_moderation ../../toxcore) +fuzz_test(net_crypto ../../toxcore) fuzz_test(tox_events ../../toxcore) diff --git a/testing/fuzzing/bootstrap_fuzz_test.cc b/testing/fuzzing/bootstrap_fuzz_test.cc index 4a784f8..386da1c 100644 --- a/testing/fuzzing/bootstrap_fuzz_test.cc +++ b/testing/fuzzing/bootstrap_fuzz_test.cc @@ -109,7 +109,7 @@ void TestBootstrap(Fuzz_Data &input) [](Tox *tox, Tox_Log_Level level, const char *file, uint32_t line, const char *func, const char *message, void *user_data) { // Log to stdout. - if (Fuzz_Data::DEBUG) { + if (Fuzz_Data::FUZZ_DEBUG) { std::printf("[tox1] %c %s:%d(%s): %s\n", tox_log_level_name(level), file, line, func, message); } @@ -161,6 +161,7 @@ void TestBootstrap(Fuzz_Data &input) assert(dispatch != nullptr); setup_callbacks(dispatch); + size_t input_size = input.size(); while (!input.empty()) { Tox_Err_Events_Iterate error_iterate; Tox_Events *events = tox_events_iterate(tox, true, &error_iterate); @@ -170,6 +171,11 @@ void TestBootstrap(Fuzz_Data &input) // Move the clock forward a decent amount so all the time-based checks // trigger more quickly. sys.clock += 200; + + // If no input was consumed, something went wrong. + assert(input_size != input.size()); + + input_size = input.size(); } tox_dispatch_free(dispatch); diff --git a/testing/fuzzing/e2e_fuzz_test.cc b/testing/fuzzing/e2e_fuzz_test.cc index df4e03c..45af343 100644 --- a/testing/fuzzing/e2e_fuzz_test.cc +++ b/testing/fuzzing/e2e_fuzz_test.cc @@ -5,7 +5,6 @@ #include #include -#include #include #include "../../toxcore/crypto_core.h" @@ -144,7 +143,7 @@ void TestEndToEnd(Fuzz_Data &input) [](Tox *tox, Tox_Log_Level level, const char *file, uint32_t line, const char *func, const char *message, void *user_data) { // Log to stdout. - if (Fuzz_Data::DEBUG) { + if (Fuzz_Data::FUZZ_DEBUG) { std::printf("[tox1] %c %s:%d(%s): %s\n", tox_log_level_name(level), file, line, func, message); } diff --git a/testing/fuzzing/fuzz_support.cc b/testing/fuzzing/fuzz_support.cc index 7f94970..904d542 100644 --- a/testing/fuzzing/fuzz_support.cc +++ b/testing/fuzzing/fuzz_support.cc @@ -57,13 +57,13 @@ static int recv_common(Fuzz_Data &input, uint8_t *buf, size_t buf_len) if (fuzz_len == 0xffff) { errno = EWOULDBLOCK; - if (Fuzz_Data::DEBUG) { + if (Fuzz_Data::FUZZ_DEBUG) { std::printf("recvfrom: no data for tox1\n"); } return -1; } - if (Fuzz_Data::DEBUG) { + if (Fuzz_Data::FUZZ_DEBUG) { std::printf( "recvfrom: %zu (%02x, %02x) for tox1\n", fuzz_len, input.data()[-2], input.data()[-1]); } @@ -77,7 +77,7 @@ static int recv_common(Fuzz_Data &input, uint8_t *buf, size_t buf_len) static void *report_alloc(const char *name, const char *func, std::size_t size, void *ptr) { - if (Fuzz_Data::DEBUG) { + if (Fuzz_Data::FUZZ_DEBUG) { printf("%s: %s(%zu): %s\n", name, func, size, ptr == nullptr ? "false" : "true"); } return ptr; @@ -175,13 +175,40 @@ static constexpr Network_Funcs fuzz_network_funcs = { static constexpr Random_Funcs fuzz_random_funcs = { /* .random_bytes = */ ![](Fuzz_System *self, uint8_t *bytes, size_t length) { - // Amount of data is limited - const size_t bytes_read = std::min(length, self->data.size()); - // Initialize everything to make MSAN and others happy - std::memset(bytes, 0, length); - CONSUME_OR_ABORT(const uint8_t *data, self->data, bytes_read); - std::copy(data, data + bytes_read, bytes); - if (Fuzz_Data::DEBUG) { + // Initialize the buffer with zeros in case there's no randomness left. + std::fill_n(bytes, length, 0); + + // For integers, we copy bytes directly, because we want to control the + // exact values. + if (length == sizeof(uint8_t) || length == sizeof(uint16_t) || length == sizeof(uint32_t) + || length == sizeof(uint64_t)) { + CONSUME_OR_RETURN(const uint8_t *data, self->data, length); + std::copy(data, data + length, bytes); + if (Fuzz_Data::FUZZ_DEBUG) { + if (length == 1) { + std::printf("rng: %d (0x%02x)\n", bytes[0], bytes[0]); + } else { + std::printf("rng: %02x..%02x[%zu]\n", bytes[0], bytes[length - 1], length); + } + } + return; + } + + // For nonces and keys, we fill the buffer with the same 1-2 bytes + // repeated. We only need these to be different enough to not often be + // the same. + assert(length == 24 || length == 32); + // We must cover the case of having only 1 byte left in the input. In + // that case, we will use the same byte for all the bytes in the output. + const size_t chunk_size = std::max(self->data.size(), static_cast(2)); + CONSUME_OR_RETURN(const uint8_t *chunk, self->data, chunk_size); + if (chunk_size == 2) { + std::fill_n(bytes, length / 2, chunk[0]); + std::fill_n(bytes + length / 2, length / 2, chunk[1]); + } else { + std::fill_n(bytes, length, chunk[0]); + } + if (Fuzz_Data::FUZZ_DEBUG) { if (length == 1) { std::printf("rng: %d (0x%02x)\n", bytes[0], bytes[0]); } else { @@ -364,7 +391,7 @@ static constexpr Network_Funcs record_network_funcs = { if (self->recvq.empty()) { self->push("\xff\xff"); errno = EWOULDBLOCK; - if (Fuzz_Data::DEBUG) { + if (Fuzz_Data::FUZZ_DEBUG) { std::printf("%s: recvfrom: no data\n", self->name_); } return -1; @@ -387,7 +414,7 @@ static constexpr Network_Funcs record_network_funcs = { assert(recvlen > 0 && recvlen <= INT_MAX); self->push(uint8_t(recvlen >> 8)); self->push(uint8_t(recvlen & 0xff)); - if (Fuzz_Data::DEBUG) { + if (Fuzz_Data::FUZZ_DEBUG) { std::printf("%s: recvfrom: %zu (%02x, %02x)\n", self->name_, recvlen, self->recording().end()[-2], self->recording().end()[-1]); } @@ -428,7 +455,7 @@ static constexpr Random_Funcs record_random_funcs = { bytes[i] = simple_rng(self->seed_) & 0xff; self->push(bytes[i]); } - if (Fuzz_Data::DEBUG) { + if (Fuzz_Data::FUZZ_DEBUG) { std::printf( "%s: rng: %02x..%02x[%zu]\n", self->name_, bytes[0], bytes[length - 1], length); } diff --git a/testing/fuzzing/fuzz_support.hh b/testing/fuzzing/fuzz_support.hh index c9eca0a..1e03abf 100644 --- a/testing/fuzzing/fuzz_support.hh +++ b/testing/fuzzing/fuzz_support.hh @@ -5,21 +5,21 @@ #ifndef C_TOXCORE_TESTING_FUZZING_FUZZ_SUPPORT_H #define C_TOXCORE_TESTING_FUZZING_FUZZ_SUPPORT_H +#include +#include #include #include #include #include #include #include -#include #include #include -#include "../../toxcore/tox.h" #include "../../toxcore/tox_private.h" struct Fuzz_Data { - static constexpr bool DEBUG = false; + static constexpr bool FUZZ_DEBUG = false; static constexpr std::size_t TRACE_TRAP = -1; // 579; private: @@ -47,7 +47,7 @@ public: // Special case because memcpy causes UB for bool (which can't be // anything other than 0 or 1). const bool val = fd.data_[0]; - if (DEBUG) { + if (FUZZ_DEBUG) { std::printf("consume@%zu(%s): bool %s\n", fd.pos(), func, val ? "true" : "false"); } ++fd.data_; @@ -74,7 +74,7 @@ public: const uint8_t *consume(const char *func, std::size_t count) { const uint8_t *val = data_; - if (DEBUG) { + if (FUZZ_DEBUG) { if (pos() == TRACE_TRAP) { __asm__("int $3"); } @@ -256,6 +256,38 @@ struct Null_System : System { Null_System(); }; +template +class int_map { +public: + struct iterator { + std::pair pair; + + bool operator==(const iterator &rhs) const { return pair.first == rhs.pair.first; } + bool operator!=(const iterator &rhs) const { return pair.first != rhs.pair.first; } + + std::pair operator*() const { return pair; } + const std::pair *operator->() const { return &pair; } + }; + + int_map() = default; + ~int_map() = default; + + iterator find(uint16_t key) const + { + if (!values[key]) { + return end(); + } + return {{key, values[key]}}; + } + + iterator end() const { return {{static_cast(values.size()), nullptr}}; } + + void emplace(uint16_t key, V value) { values[key] = value; } + +private: + std::array values; +}; + /** * A Tox_System implementation that records all I/O but does not actually * perform any real I/O. Everything inside this system is hermetic in-process @@ -266,7 +298,7 @@ struct Null_System : System { * initialised with the same seed will be identical (same keys, etc.). */ struct Record_System : System { - static constexpr bool DEBUG = Fuzz_Data::DEBUG; + static constexpr bool FUZZ_DEBUG = Fuzz_Data::FUZZ_DEBUG; /** @brief State shared between all tox instances. */ struct Global { @@ -280,7 +312,7 @@ struct Record_System : System { * toxcore sends packets to itself sometimes when doing onion routing * with only 2 nodes in the network. */ - std::unordered_map bound; + int_map bound; }; Global &global_; @@ -300,7 +332,7 @@ struct Record_System : System { void push(bool byte) { - if (DEBUG) { + if (FUZZ_DEBUG) { if (recording_.size() == Fuzz_Data::TRACE_TRAP) { __asm__("int $3"); } @@ -312,7 +344,7 @@ struct Record_System : System { void push(uint8_t byte) { - if (DEBUG) { + if (FUZZ_DEBUG) { if (recording_.size() == Fuzz_Data::TRACE_TRAP) { __asm__("int $3"); } @@ -323,7 +355,7 @@ struct Record_System : System { void push(const uint8_t *bytes, std::size_t size) { - if (DEBUG) { + if (FUZZ_DEBUG) { if (recording_.size() == Fuzz_Data::TRACE_TRAP) { __asm__("int $3"); } @@ -352,7 +384,7 @@ private: * everything down drastically. It's useful while developing the fuzzer and the * protodump program. */ -extern const bool DEBUG; +extern const bool FUZZ_DEBUG; inline constexpr char tox_log_level_name(Tox_Log_Level level) { diff --git a/testing/fuzzing/protodump.cc b/testing/fuzzing/protodump.cc index 28df05a..3dd781c 100644 --- a/testing/fuzzing/protodump.cc +++ b/testing/fuzzing/protodump.cc @@ -31,8 +31,6 @@ #include "../../toxcore/tox_dispatch.h" #include "../../toxcore/tox_events.h" #include "../../toxcore/tox_private.h" -#include "../../toxcore/tox_struct.h" -#include "../../toxcore/util.h" #include "fuzz_support.hh" namespace { @@ -179,7 +177,7 @@ void dump(std::vector recording, const char *filename) void RecordBootstrap(const char *init, const char *bootstrap) { - Record_System::Global global; + auto global = std::make_unique(); Tox_Options *opts = tox_options_new(nullptr); assert(opts != nullptr); @@ -198,9 +196,9 @@ void RecordBootstrap(const char *init, const char *bootstrap) Tox_Err_New_Testing error_new_testing; Tox_Options_Testing tox_options_testing; - Record_System sys1(global, 4, "tox1"); // fair dice roll - tox_options_set_log_user_data(opts, &sys1); - tox_options_testing.operating_system = sys1.sys.get(); + auto sys1 = std::make_unique(*global, 4, "tox1"); // fair dice roll + tox_options_set_log_user_data(opts, sys1.get()); + tox_options_testing.operating_system = sys1->sys.get(); Tox *tox1 = tox_new_testing(opts, &error_new, &tox_options_testing, &error_new_testing); assert(tox1 != nullptr); assert(error_new == TOX_ERR_NEW_OK); @@ -212,9 +210,9 @@ void RecordBootstrap(const char *init, const char *bootstrap) std::array dht_key1; tox_self_get_dht_id(tox1, dht_key1.data()); - Record_System sys2(global, 5, "tox2"); // unfair dice roll - tox_options_set_log_user_data(opts, &sys2); - tox_options_testing.operating_system = sys2.sys.get(); + auto sys2 = std::make_unique(*global, 5, "tox2"); // unfair dice roll + tox_options_set_log_user_data(opts, sys2.get()); + tox_options_testing.operating_system = sys2->sys.get(); Tox *tox2 = tox_new_testing(opts, &error_new, &tox_options_testing, &error_new_testing); assert(tox2 != nullptr); assert(error_new == TOX_ERR_NEW_OK); @@ -252,31 +250,31 @@ void RecordBootstrap(const char *init, const char *bootstrap) Tox_Events *events; events = tox_events_iterate(tox1, true, &error_iterate); - assert(tox_events_equal(sys1.sys.get(), events, events)); + assert(tox_events_equal(sys1->sys.get(), events, events)); tox_dispatch_invoke(dispatch, events, &state1); tox_events_free(events); events = tox_events_iterate(tox2, true, &error_iterate); - assert(tox_events_equal(sys2.sys.get(), events, events)); + assert(tox_events_equal(sys2->sys.get(), events, events)); tox_dispatch_invoke(dispatch, events, &state2); tox_events_free(events); // Move the clock forward a decent amount so all the time-based checks // trigger more quickly. - sys1.clock += clock_increment; - sys2.clock += clock_increment; + sys1->clock += clock_increment; + sys2->clock += clock_increment; - if (Fuzz_Data::DEBUG) { + if (Fuzz_Data::FUZZ_DEBUG) { printf("tox1: rng: %d (for clock)\n", clock_increment); printf("tox2: rng: %d (for clock)\n", clock_increment); } - sys1.push(clock_increment); - sys2.push(clock_increment); + sys1->push(clock_increment); + sys2->push(clock_increment); }; while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE || tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE) { - if (Fuzz_Data::DEBUG) { + if (Fuzz_Data::FUZZ_DEBUG) { std::printf("tox1: %d, tox2: %d\n", tox_self_get_connection_status(tox1), tox_self_get_connection_status(tox2)); } @@ -291,7 +289,7 @@ void RecordBootstrap(const char *init, const char *bootstrap) while (tox_friend_get_connection_status(tox2, friend_number, nullptr) == TOX_CONNECTION_NONE || tox_friend_get_connection_status(tox1, 0, nullptr) == TOX_CONNECTION_NONE) { - if (Fuzz_Data::DEBUG) { + if (Fuzz_Data::FUZZ_DEBUG) { std::printf("tox1: %d, tox2: %d, tox1 -> tox2: %d, tox2 -> tox1: %d\n", tox_self_get_connection_status(tox1), tox_self_get_connection_status(tox2), tox_friend_get_connection_status(tox1, 0, nullptr), @@ -302,10 +300,10 @@ void RecordBootstrap(const char *init, const char *bootstrap) std::printf("tox clients connected\n"); - dump(sys1.take_recording(), init); + dump(sys1->take_recording(), init); while (state1.done < MESSAGE_COUNT && state2.done < MESSAGE_COUNT) { - if (Fuzz_Data::DEBUG) { + if (Fuzz_Data::FUZZ_DEBUG) { std::printf("tox1: %d, tox2: %d, tox1 -> tox2: %d, tox2 -> tox1: %d\n", tox_self_get_connection_status(tox1), tox_self_get_connection_status(tox2), tox_friend_get_connection_status(tox1, 0, nullptr), @@ -320,7 +318,7 @@ void RecordBootstrap(const char *init, const char *bootstrap) tox_kill(tox2); tox_kill(tox1); - dump(sys1.recording(), bootstrap); + dump(sys1->recording(), bootstrap); } } diff --git a/testing/fuzzing/protodump_reduce.cc b/testing/fuzzing/protodump_reduce.cc index 820a3fc..53d39d0 100644 --- a/testing/fuzzing/protodump_reduce.cc +++ b/testing/fuzzing/protodump_reduce.cc @@ -11,7 +11,7 @@ namespace { -constexpr bool PROTODUMP_DEBUG = Fuzz_Data::DEBUG; +constexpr bool PROTODUMP_DEBUG = Fuzz_Data::FUZZ_DEBUG; void setup_callbacks(Tox_Dispatch *dispatch) { diff --git a/testing/fuzzing/rebuild_protodump b/testing/fuzzing/rebuild_protodump index dafeb99..4c5a451 100755 --- a/testing/fuzzing/rebuild_protodump +++ b/testing/fuzzing/rebuild_protodump @@ -1,6 +1,10 @@ #!/bin/sh -set -eux +set -eux -o pipefail + +WORKSPACE_ROOT=$(bazel info workspace) + +cd "$WORKSPACE_ROOT" bazel test --config=asan-libfuzzer //c-toxcore/testing/fuzzing:protodump_reduce_test diff --git a/testing/fuzzing/toxsave_fuzz_test.cc b/testing/fuzzing/toxsave_fuzz_test.cc index f48c2bf..0ba9737 100644 --- a/testing/fuzzing/toxsave_fuzz_test.cc +++ b/testing/fuzzing/toxsave_fuzz_test.cc @@ -20,6 +20,8 @@ void TestSaveDataLoading(Fuzz_Data &input) const size_t savedata_size = input.size(); CONSUME_OR_RETURN(const uint8_t *savedata, input, savedata_size); + tox_options_set_experimental_groups_persistence(tox_options, true); + // pass test data to Tox tox_options_set_savedata_data(tox_options, savedata, savedata_size); tox_options_set_savedata_type(tox_options, TOX_SAVEDATA_TYPE_TOX_SAVE); diff --git a/third_party/.gitignore b/third_party/.gitignore index 8e21180..abfbd72 100644 --- a/third_party/.gitignore +++ b/third_party/.gitignore @@ -1 +1,2 @@ -googletest +/ci-tools +/googletest diff --git a/tools/update-versions.sh b/tools/update-versions.sh new file mode 100755 index 0000000..814b6f4 --- /dev/null +++ b/tools/update-versions.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +set -eux -o pipefail + +VERSION=$1 + +GIT_ROOT=$(git rev-parse --show-toplevel) +cd "$GIT_ROOT" + +# Strip suffixes (e.g. "-rc.1") from the version for the toxcore version sync. +VERSION="${VERSION%-*}" + +IFS="." read -ra version_parts <<<"$VERSION" + +other/version-sync "$GIT_ROOT" "${version_parts[0]}" "${version_parts[1]}" "${version_parts[2]}" diff --git a/toxav/rtp.c b/toxav/rtp.c index dd955d0..c520f58 100644 --- a/toxav/rtp.c +++ b/toxav/rtp.c @@ -17,6 +17,7 @@ #include "../toxcore/logger.h" #include "../toxcore/mono_time.h" #include "../toxcore/net_crypto.h" +#include "../toxcore/network.h" #include "../toxcore/tox_private.h" #include "../toxcore/util.h" @@ -678,7 +679,7 @@ static uint32_t rtp_random_u32(void) return randombytes_random(); } -RTPSession *rtp_new(const Logger *log, int payload_type, Tox *tox, ToxAV *toxav, uint32_t friendnumber, +RTPSession *rtp_new(const Logger *log, const Memory *mem, int payload_type, Tox *tox, ToxAV *toxav, uint32_t friendnumber, BWController *bwc, void *cs, rtp_m_cb *mcb) { assert(mcb != nullptr); @@ -704,6 +705,8 @@ RTPSession *rtp_new(const Logger *log, int payload_type, Tox *tox, ToxAV *toxav, session->ssrc = payload_type == RTP_TYPE_VIDEO ? 0 : rtp_random_u32(); // Zoff: what is this?? session->payload_type = payload_type; + session->log = log; + session->mem = mem; session->tox = tox; session->toxav = toxav; session->friend_number = friendnumber; @@ -773,18 +776,17 @@ void rtp_stop_receiving(Tox *tox) * @param error the error from rtp_send_custom_lossy_packet. * @param rdata_size The package length to be shown in the log. */ -static void rtp_report_error_maybe(const Logger *log, Tox_Err_Friend_Custom_Packet error, uint16_t rdata_size) +static void rtp_report_error_maybe(const Logger *log, const Memory *mem, Tox_Err_Friend_Custom_Packet error, uint16_t rdata_size) { if (error != TOX_ERR_FRIEND_CUSTOM_PACKET_OK) { - char *netstrerror = net_new_strerror(net_error()); + Net_Strerror error_str; const char *toxerror = tox_err_friend_custom_packet_to_string(error); LOGGER_WARNING(log, "RTP send failed (len: %u)! tox error: %s net error: %s", - rdata_size, toxerror, netstrerror); - net_kill_strerror(netstrerror); + rdata_size, toxerror, net_strerror(net_error(), &error_str)); } } -static void rtp_send_piece(const Logger *log, Tox *tox, uint32_t friend_number, const struct RTPHeader *header, +static void rtp_send_piece(const Logger *log, const Memory *mem, Tox *tox, uint32_t friend_number, const struct RTPHeader *header, const uint8_t *data, uint8_t *rdata, uint16_t length) { rtp_header_pack(rdata + 1, header); @@ -795,7 +797,7 @@ static void rtp_send_piece(const Logger *log, Tox *tox, uint32_t friend_number, Tox_Err_Friend_Custom_Packet error; tox_friend_send_lossy_packet(tox, friend_number, rdata, rdata_size, &error); - rtp_report_error_maybe(log, error, rdata_size); + rtp_report_error_maybe(log, mem, error, rdata_size); } static struct RTPHeader rtp_default_header(const RTPSession *session, uint32_t length, bool is_keyframe) @@ -868,7 +870,7 @@ int rtp_send_data(const Logger *log, RTPSession *session, const uint8_t *data, u * Send the packet in single piece. */ assert(length < UINT16_MAX); - rtp_send_piece(log, session->tox, session->friend_number, &header, data, rdata, length); + rtp_send_piece(log, session->mem, session->tox, session->friend_number, &header, data, rdata, length); } else { /* * The length is greater than the maximum allowed length (including header) @@ -878,7 +880,7 @@ int rtp_send_data(const Logger *log, RTPSession *session, const uint8_t *data, u uint16_t piece = MAX_CRYPTO_DATA_SIZE - (RTP_HEADER_SIZE + 1); while ((length - sent) + RTP_HEADER_SIZE + 1 > MAX_CRYPTO_DATA_SIZE) { - rtp_send_piece(log, session->tox, session->friend_number, &header, data + sent, rdata, piece); + rtp_send_piece(log, session->mem, session->tox, session->friend_number, &header, data + sent, rdata, piece); sent += piece; header.offset_lower = sent; @@ -889,7 +891,7 @@ int rtp_send_data(const Logger *log, RTPSession *session, const uint8_t *data, u piece = length - sent; if (piece != 0) { - rtp_send_piece(log, session->tox, session->friend_number, &header, data + sent, rdata, piece); + rtp_send_piece(log, session->mem, session->tox, session->friend_number, &header, data + sent, rdata, piece); } } diff --git a/toxav/rtp.h b/toxav/rtp.h index 1668a54..aba31b5 100644 --- a/toxav/rtp.h +++ b/toxav/rtp.h @@ -162,6 +162,7 @@ typedef struct RTPSession { struct RTPWorkBufferList *work_buffer_list; uint8_t first_packets_counter; /* dismiss first few lost video packets */ const Logger *log; + const Memory *mem; Tox *tox; ToxAV *toxav; uint32_t friend_number; @@ -192,7 +193,7 @@ size_t rtp_header_pack(uint8_t *rdata, const struct RTPHeader *header); */ size_t rtp_header_unpack(const uint8_t *data, struct RTPHeader *header); -RTPSession *rtp_new(const Logger *log, int payload_type, Tox *tox, ToxAV *toxav, uint32_t friendnumber, +RTPSession *rtp_new(const Logger *log, const Memory *mem, int payload_type, Tox *tox, ToxAV *toxav, uint32_t friendnumber, BWController *bwc, void *cs, rtp_m_cb *mcb); void rtp_kill(const Logger *log, RTPSession *session); void rtp_allow_receiving_mark(RTPSession *session); diff --git a/toxav/toxav.c b/toxav/toxav.c index b69ce15..2f9639f 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c @@ -13,6 +13,7 @@ #include "rtp.h" #include "toxav_hacks.h" +#include "../toxcore/Messenger.h" #include "../toxcore/ccompat.h" #include "../toxcore/logger.h" #include "../toxcore/mono_time.h" @@ -87,6 +88,7 @@ typedef struct DecodeTimeStats { } DecodeTimeStats; struct ToxAV { + const Memory *mem; Logger *log; Tox *tox; MSISession *msi; @@ -219,6 +221,7 @@ ToxAV *toxav_new(Tox *tox, Toxav_Err_New *error) goto RETURN; } + av->mem = tox->sys.mem; av->log = tox->m->log; av->tox = tox; av->msi = msi_new(av->log, av->tox); @@ -994,9 +997,8 @@ static Toxav_Err_Send_Frame send_frames(const ToxAV *av, ToxAVCall *call) is_keyframe); if (res < 0) { - char *netstrerror = net_new_strerror(net_error()); - LOGGER_WARNING(av->log, "Could not send video frame: %s", netstrerror); - net_kill_strerror(netstrerror); + Net_Strerror error_str; + LOGGER_WARNING(av->log, "Could not send video frame: %s", net_strerror(net_error(), &error_str)); return TOXAV_ERR_SEND_FRAME_RTP_FAILED; } } @@ -1507,7 +1509,7 @@ static bool call_prepare_transmission(ToxAVCall *call) goto FAILURE; } - call->audio_rtp = rtp_new(av->log, RTP_TYPE_AUDIO, av->tox, av, call->friend_number, call->bwc, + call->audio_rtp = rtp_new(av->log, av->mem, RTP_TYPE_AUDIO, av->tox, av, call->friend_number, call->bwc, call->audio, ac_queue_message); if (call->audio_rtp == nullptr) { @@ -1523,7 +1525,7 @@ static bool call_prepare_transmission(ToxAVCall *call) goto FAILURE; } - call->video_rtp = rtp_new(av->log, RTP_TYPE_VIDEO, av->tox, av, call->friend_number, call->bwc, + call->video_rtp = rtp_new(av->log, av->mem, RTP_TYPE_VIDEO, av->tox, av, call->friend_number, call->bwc, call->video, vc_queue_message); if (call->video_rtp == nullptr) { diff --git a/toxcore/BUILD.bazel b/toxcore/BUILD.bazel index 8bbd870..1f2549f 100644 --- a/toxcore/BUILD.bazel +++ b/toxcore/BUILD.bazel @@ -6,6 +6,8 @@ exports_files( "tox.h", "tox_dispatch.h", "tox_events.h", + "tox_log_level.h", + "tox_options.h", "tox_private.h", ], visibility = ["//c-toxcore:__subpackages__"], @@ -192,6 +194,7 @@ cc_library( deps = [ ":attributes", ":ccompat", + ":mem", "//c-toxcore/third_party:cmp", ], ) @@ -204,6 +207,7 @@ cc_test( ":bin_pack", ":bin_unpack", ":logger", + ":mem", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -766,6 +770,23 @@ cc_library( ], ) +cc_fuzz_test( + name = "net_crypto_fuzz_test", + size = "small", + testonly = True, + srcs = ["net_crypto_fuzz_test.cc"], + corpus = ["//tools/toktok-fuzzer/corpus:net_crypto_fuzz_test"], + deps = [ + ":DHT", + ":TCP_client", + ":mem_test_util", + ":net_crypto", + ":network", + "//c-toxcore/testing/fuzzing:fuzz_support", + "//c-toxcore/testing/fuzzing:fuzz_tox", + ], +) + cc_library( name = "onion_announce", srcs = ["onion_announce.c"], @@ -1070,6 +1091,25 @@ cc_library( ], ) +cc_library( + name = "tox_options", + srcs = ["tox_options.c"], + hdrs = ["tox_options.h"], + copts = ["-UTOX_HIDE_DEPRECATED"], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":ccompat", + ":tox_log_level", + ], +) + +cc_library( + name = "tox_log_level", + srcs = ["tox_log_level.c"], + hdrs = ["tox_log_level.h"], + visibility = ["//c-toxcore:__subpackages__"], +) + cc_library( name = "tox", srcs = [ @@ -1102,6 +1142,8 @@ cc_library( ":network", ":onion_client", ":state", + ":tox_log_level", + ":tox_options", ":util", "//c-toxcore/toxencryptsave:defines", "@pthread", @@ -1115,6 +1157,8 @@ cc_test( deps = [ ":crypto_core", ":tox", + ":tox_log_level", + ":tox_options", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 630b6c4..0dc4900 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -30,8 +30,8 @@ /** The timeout after which a node is discarded completely. */ #define KILL_NODE_TIMEOUT (BAD_NODE_TIMEOUT + PING_INTERVAL) -/** Ping interval in seconds for each random sending of a get nodes request. */ -#define GET_NODE_INTERVAL 20 +/** Ping interval in seconds for each random sending of a nodes request. */ +#define NODES_REQUEST_INTERVAL 20 #define MAX_PUNCHING_PORTS 48 @@ -46,7 +46,7 @@ #define NAT_PING_REQUEST 0 #define NAT_PING_RESPONSE 1 -/** Number of get node requests to send to quickly find close nodes. */ +/** Number of node requests to send to quickly find close nodes. */ #define MAX_BOOTSTRAP_TIMES 5 // TODO(sudden6): find out why we need multiple callbacks and if we really need 32 @@ -66,9 +66,9 @@ struct DHT_Friend { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; Client_data client_list[MAX_FRIEND_CLIENTS]; - /* Time at which the last get_nodes request was sent. */ - uint64_t lastgetnode; - /* number of times get_node packets were sent. */ + /* Time at which the last nodes request was sent. */ + uint64_t last_nodes_request; + /* number of times nodes request packets were sent. */ uint32_t bootstrap_times; /* Symmetric NAT hole punching stuff. */ @@ -104,7 +104,7 @@ struct DHT { bool lan_discovery_enabled; Client_data close_clientlist[LCLIENT_LIST]; - uint64_t close_lastgetnodes; + uint64_t close_last_nodes_request; uint32_t close_bootstrap_times; /* DHT keypair */ @@ -130,7 +130,7 @@ struct DHT { Node_format to_bootstrap[MAX_CLOSE_TO_BOOTSTRAP_NODES]; unsigned int num_to_bootstrap; - dht_get_nodes_response_cb *get_nodes_response; + dht_nodes_response_cb *nodes_response_callback; }; const uint8_t *dht_friend_public_key(const DHT_Friend *dht_friend) @@ -431,7 +431,7 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed const int ipp_size = unpack_ip_port(&nodes[num].ip_port, data + len_processed, length - len_processed, tcp_enabled); if (ipp_size == -1) { - return -1; + break; } len_processed += ipp_size; @@ -450,6 +450,10 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed #endif /* NDEBUG */ } + if (num == 0 && max_num_nodes > 0 && length > 0) { + return -1; + } + if (processed_data_len != nullptr) { *processed_data_len = len_processed; } @@ -708,7 +712,7 @@ static void get_close_nodes_inner( } /** - * Find MAX_SENT_NODES nodes closest to the public_key for the send nodes request: + * Find MAX_SENT_NODES nodes closest to the public_key for the nodes request: * put them in the nodes_list and return how many were found. * * want_announce: return only nodes which implement the dht announcements protocol. @@ -1131,7 +1135,7 @@ static bool is_pk_in_close_list(const DHT *dht, const uint8_t *public_key, const ip_port); } -/** @brief Check if the node obtained with a get_nodes with public_key should be pinged. +/** @brief Check if the node obtained from a nodes response with public_key should be pinged. * * NOTE: for best results call it after addto_lists. * @@ -1139,7 +1143,7 @@ static bool is_pk_in_close_list(const DHT *dht, const uint8_t *public_key, const * return true if it should. */ non_null() -static bool ping_node_from_getnodes_ok(DHT *dht, const uint8_t *public_key, const IP_Port *ip_port) +static bool ping_node_from_nodes_response_ok(DHT *dht, const uint8_t *public_key, const IP_Port *ip_port) { bool ret = false; @@ -1310,7 +1314,7 @@ static void returnedip_ports(DHT *dht, const IP_Port *ip_port, const uint8_t *pu } } -bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id) +bool dht_send_nodes_request(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id) { /* Check if packet is going to be sent to ourself. */ if (pk_equal(public_key, dht->self_public_key)) { @@ -1345,21 +1349,21 @@ bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, c const uint8_t *shared_key = dht_get_shared_key_sent(dht, public_key); const int len = dht_create_packet(dht->mem, dht->rng, - dht->self_public_key, shared_key, NET_PACKET_GET_NODES, + dht->self_public_key, shared_key, NET_PACKET_NODES_REQUEST, plain, sizeof(plain), data, sizeof(data)); if (len != sizeof(data)) { - LOGGER_ERROR(dht->log, "getnodes packet encryption failed"); + LOGGER_ERROR(dht->log, "nodes request packet encryption failed"); return false; } return sendpacket(dht->net, ip_port, data, len) > 0; } -/** Send a send nodes response: message for IPv6 nodes */ +/** Send a nodes response */ non_null() -static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id, - const uint8_t *sendback_data, uint16_t length, const uint8_t *shared_encryption_key) +static int send_nodes_response(const DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id, + const uint8_t *sendback_data, uint16_t length, const uint8_t *shared_encryption_key) { /* Check if packet is going to be sent to ourself. */ if (pk_equal(public_key, dht->self_public_key)) { @@ -1396,7 +1400,7 @@ static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t VLA(uint8_t, data, data_size); const int len = dht_create_packet(dht->mem, dht->rng, - dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6, + dht->self_public_key, shared_encryption_key, NET_PACKET_NODES_RESPONSE, plain, 1 + nodes_length + length, data, data_size); if (len < 0 || (uint32_t)len != data_size) { @@ -1409,7 +1413,7 @@ static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t #define CRYPTO_NODE_SIZE (CRYPTO_PUBLIC_KEY_SIZE + sizeof(uint64_t)) non_null() -static int handle_getnodes(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) +static int handle_nodes_request(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { DHT *const dht = (DHT *)object; @@ -1436,16 +1440,16 @@ static int handle_getnodes(void *object, const IP_Port *source, const uint8_t *p return 1; } - sendnodes_ipv6(dht, source, packet + 1, plain, plain + CRYPTO_PUBLIC_KEY_SIZE, sizeof(uint64_t), shared_key); + send_nodes_response(dht, source, packet + 1, plain, plain + CRYPTO_PUBLIC_KEY_SIZE, sizeof(uint64_t), shared_key); ping_add(dht->ping, packet + 1, source); return 0; } -/** Return true if we sent a getnode packet to the peer associated with the supplied info. */ +/** Return true if we sent a nodes request packet to the peer associated with the supplied info. */ non_null() -static bool sent_getnode_to_node(DHT *dht, const uint8_t *public_key, const IP_Port *node_ip_port, uint64_t ping_id) +static bool sent_nodes_request_to_node(DHT *dht, const uint8_t *public_key, const IP_Port *node_ip_port, uint64_t ping_id) { uint8_t data[sizeof(Node_format) * 2]; @@ -1463,8 +1467,8 @@ static bool sent_getnode_to_node(DHT *dht, const uint8_t *public_key, const IP_P } non_null() -static bool handle_sendnodes_core(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, - Node_format *plain_nodes, uint16_t size_plain_nodes, uint32_t *num_nodes_out) +static bool handle_nodes_response_core(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, + Node_format *plain_nodes, uint16_t size_plain_nodes, uint32_t *num_nodes_out) { DHT *const dht = (DHT *)object; const uint32_t cid_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + 1 + sizeof(uint64_t) + CRYPTO_MAC_SIZE; @@ -1505,7 +1509,7 @@ static bool handle_sendnodes_core(void *object, const IP_Port *source, const uin uint64_t ping_id; memcpy(&ping_id, plain + 1 + data_size, sizeof(ping_id)); - if (!sent_getnode_to_node(dht, packet + 1, source, ping_id)) { + if (!sent_nodes_request_to_node(dht, packet + 1, source, ping_id)) { return false; } @@ -1533,14 +1537,14 @@ static bool handle_sendnodes_core(void *object, const IP_Port *source, const uin } non_null() -static int handle_sendnodes_ipv6(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, +static int handle_nodes_response(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { DHT *const dht = (DHT *)object; Node_format plain_nodes[MAX_SENT_NODES]; uint32_t num_nodes; - if (!handle_sendnodes_core(object, source, packet, length, plain_nodes, MAX_SENT_NODES, &num_nodes)) { + if (!handle_nodes_response_core(object, source, packet, length, plain_nodes, MAX_SENT_NODES, &num_nodes)) { return 1; } @@ -1550,11 +1554,11 @@ static int handle_sendnodes_ipv6(void *object, const IP_Port *source, const uint for (uint32_t i = 0; i < num_nodes; ++i) { if (ipport_isset(&plain_nodes[i].ip_port)) { - ping_node_from_getnodes_ok(dht, plain_nodes[i].public_key, &plain_nodes[i].ip_port); + ping_node_from_nodes_response_ok(dht, plain_nodes[i].public_key, &plain_nodes[i].ip_port); returnedip_ports(dht, &plain_nodes[i].ip_port, plain_nodes[i].public_key, packet + 1); - if (dht->get_nodes_response != nullptr) { - dht->get_nodes_response(dht, &plain_nodes[i], userdata); + if (dht->nodes_response_callback != nullptr) { + dht->nodes_response_callback(dht, &plain_nodes[i], userdata); } } } @@ -1767,7 +1771,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co if (mono_time_is_timeout(dht->mono_time, assoc->last_pinged, PING_INTERVAL)) { const IP_Port *target = &assoc->ip_port; const uint8_t *target_key = client->public_key; - dht_getnodes(dht, target, target_key, public_key); + dht_send_nodes_request(dht, target, target_key, public_key); assoc->last_pinged = temp_time; } @@ -1792,7 +1796,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co sort_client_list(dht->mem, list, dht->cur_time, list_count, public_key); } - if (num_nodes > 0 && (mono_time_is_timeout(dht->mono_time, *lastgetnode, GET_NODE_INTERVAL) + if (num_nodes > 0 && (mono_time_is_timeout(dht->mono_time, *lastgetnode, NODES_REQUEST_INTERVAL) || *bootstrap_times < MAX_BOOTSTRAP_TIMES)) { uint32_t rand_node = random_range_u32(dht->rng, num_nodes); @@ -1802,7 +1806,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co const IP_Port *target = &assoc_list[rand_node]->ip_port; const uint8_t *target_key = client_list[rand_node]->public_key; - dht_getnodes(dht, target, target_key, public_key); + dht_send_nodes_request(dht, target, target_key, public_key); *lastgetnode = temp_time; ++*bootstrap_times; @@ -1815,7 +1819,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co /** @brief Ping each client in the "friends" list every PING_INTERVAL seconds. * - * Send a get nodes request every GET_NODE_INTERVAL seconds to a random good + * Send a nodes request every NODES_REQUEST_INTERVAL seconds to a random good * node for each "friend" in our "friends" list. */ non_null() @@ -1825,31 +1829,31 @@ static void do_dht_friends(DHT *dht) DHT_Friend *const dht_friend = &dht->friends_list[i]; for (size_t j = 0; j < dht_friend->num_to_bootstrap; ++j) { - dht_getnodes(dht, &dht_friend->to_bootstrap[j].ip_port, dht_friend->to_bootstrap[j].public_key, dht_friend->public_key); + dht_send_nodes_request(dht, &dht_friend->to_bootstrap[j].ip_port, dht_friend->to_bootstrap[j].public_key, dht_friend->public_key); } dht_friend->num_to_bootstrap = 0; - do_ping_and_sendnode_requests(dht, &dht_friend->lastgetnode, dht_friend->public_key, dht_friend->client_list, + do_ping_and_sendnode_requests(dht, &dht_friend->last_nodes_request, dht_friend->public_key, dht_friend->client_list, MAX_FRIEND_CLIENTS, &dht_friend->bootstrap_times, true); } } /** @brief Ping each client in the close nodes list every PING_INTERVAL seconds. * - * Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list. + * Send a nodes request every NODES_REQUEST_INTERVAL seconds to a random good node in the list. */ non_null() static void do_close(DHT *dht) { for (size_t i = 0; i < dht->num_to_bootstrap; ++i) { - dht_getnodes(dht, &dht->to_bootstrap[i].ip_port, dht->to_bootstrap[i].public_key, dht->self_public_key); + dht_send_nodes_request(dht, &dht->to_bootstrap[i].ip_port, dht->to_bootstrap[i].public_key, dht->self_public_key); } dht->num_to_bootstrap = 0; const uint8_t not_killed = do_ping_and_sendnode_requests( - dht, &dht->close_lastgetnodes, dht->self_public_key, dht->close_clientlist, LCLIENT_LIST, &dht->close_bootstrap_times, + dht, &dht->close_last_nodes_request, dht->self_public_key, dht->close_clientlist, LCLIENT_LIST, &dht->close_bootstrap_times, false); if (not_killed != 0) { @@ -1883,7 +1887,7 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key) return true; } - return dht_getnodes(dht, ip_port, public_key, dht->self_public_key); + return dht_send_nodes_request(dht, ip_port, public_key, dht->self_public_key); } bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dns_enabled, @@ -2530,9 +2534,9 @@ static int cryptopacket_handle(void *object, const IP_Port *source, const uint8_ return 1; } -void dht_callback_get_nodes_response(DHT *dht, dht_get_nodes_response_cb *function) +void dht_callback_nodes_response(DHT *dht, dht_nodes_response_cb *function) { - dht->get_nodes_response = function; + dht->nodes_response_callback = function; } non_null(1, 2, 3) nullable(5) @@ -2593,8 +2597,8 @@ DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Netw return nullptr; } - networking_registerhandler(dht->net, NET_PACKET_GET_NODES, &handle_getnodes, dht); - networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht); + networking_registerhandler(dht->net, NET_PACKET_NODES_REQUEST, &handle_nodes_request, dht); + networking_registerhandler(dht->net, NET_PACKET_NODES_RESPONSE, &handle_nodes_response, dht); networking_registerhandler(dht->net, NET_PACKET_CRYPTO, &cryptopacket_handle, dht); networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_lan_discovery, dht); cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, &handle_nat_ping, dht); @@ -2672,8 +2676,8 @@ void kill_dht(DHT *dht) return; } - networking_registerhandler(dht->net, NET_PACKET_GET_NODES, nullptr, nullptr); - networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, nullptr, nullptr); + networking_registerhandler(dht->net, NET_PACKET_NODES_REQUEST, nullptr, nullptr); + networking_registerhandler(dht->net, NET_PACKET_NODES_RESPONSE, nullptr, nullptr); networking_registerhandler(dht->net, NET_PACKET_CRYPTO, nullptr, nullptr); networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, nullptr, nullptr); cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, nullptr, nullptr); diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 8e0e5e7..16b2933 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -36,7 +36,7 @@ extern "C" { #define MAX_CLOSE_TO_BOOTSTRAP_NODES 8 -/** The max number of nodes to send with send nodes. */ +/** The max number of nodes to send with nodes response. */ #define MAX_SENT_NODES 4 /** Ping timeout in seconds */ @@ -259,21 +259,21 @@ non_null() const uint8_t *dht_get_shared_key_sent(DHT *dht, const uint8_t *public_key); /** - * Sends a getnodes request to `ip_port` with the public key `public_key` for nodes + * Sends a nodes request to `ip_port` with the public key `public_key` for nodes * that are close to `client_id`. * * @retval true on success. */ non_null() -bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id); +bool dht_send_nodes_request(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id); typedef void dht_ip_cb(void *object, int32_t number, const IP_Port *ip_port); -typedef void dht_get_nodes_response_cb(const DHT *dht, const Node_format *node, void *user_data); +typedef void dht_nodes_response_cb(const DHT *dht, const Node_format *node, void *user_data); -/** Sets the callback to be triggered on a getnodes response. */ +/** Sets the callback to be triggered on a nodes response. */ non_null(1) nullable(2) -void dht_callback_get_nodes_response(DHT *dht, dht_get_nodes_response_cb *function); +void dht_callback_nodes_response(DHT *dht, dht_nodes_response_cb *function); /** @brief Add a new friend to the friends list. * @param public_key must be CRYPTO_PUBLIC_KEY_SIZE bytes long. @@ -390,7 +390,7 @@ void do_dht(DHT *dht); * Use these two functions to bootstrap the client. */ /** - * @brief Sends a "get nodes" request to the given node with ip, port and public_key + * @brief Sends a "nodes request" to the given node with ip, port and public_key * to setup connections */ non_null() @@ -398,7 +398,7 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key); /** @brief Resolves address into an IP address. * - * If successful, sends a "get nodes" request to the given node with ip, port + * If successful, sends a "nodes request" to the given node with ip, port * and public_key to setup connections * * @param address can be a hostname or an IP address (IPv4 or IPv6). diff --git a/toxcore/Makefile.inc b/toxcore/Makefile.inc index 2ee4a72..de9227b 100644 --- a/toxcore/Makefile.inc +++ b/toxcore/Makefile.inc @@ -1,26 +1,20 @@ lib_LTLIBRARIES += libtoxcore.la libtoxcore_la_include_HEADERS = \ - ../toxcore/tox.h + ../toxcore/tox.h \ + ../toxcore/tox_options.h libtoxcore_la_includedir = $(includedir)/tox libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \ ../third_party/cmp/cmp.h \ - ../toxcore/attributes.h \ - ../toxcore/bin_pack.c \ - ../toxcore/bin_pack.h \ - ../toxcore/bin_unpack.c \ - ../toxcore/bin_unpack.h \ - ../toxcore/ccompat.c \ - ../toxcore/ccompat.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/dht_get_nodes_response.c \ + ../toxcore/events/dht_nodes_response.c \ ../toxcore/events/events_alloc.c \ ../toxcore/events/events_alloc.h \ ../toxcore/events/file_chunk_request.c \ @@ -56,97 +50,108 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \ ../toxcore/events/group_topic.c \ ../toxcore/events/group_topic_lock.c \ ../toxcore/events/group_voice_state.c \ - ../toxcore/DHT.h \ - ../toxcore/DHT.c \ - ../toxcore/mem.h \ - ../toxcore/mem.c \ - ../toxcore/mono_time.h \ - ../toxcore/mono_time.c \ - ../toxcore/network.h \ - ../toxcore/network.c \ - ../toxcore/crypto_core.h \ - ../toxcore/crypto_core.c \ - ../toxcore/crypto_core_pack.h \ + ../toxcore/announce.c \ + ../toxcore/announce.h \ + ../toxcore/attributes.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_pack.c \ - ../toxcore/timed_auth.h \ - ../toxcore/timed_auth.c \ - ../toxcore/ping_array.h \ - ../toxcore/ping_array.c \ - ../toxcore/net_crypto.h \ - ../toxcore/net_crypto.c \ - ../toxcore/net_profile.c \ - ../toxcore/net_profile.h \ - ../toxcore/friend_requests.h \ - ../toxcore/friend_requests.c \ - ../toxcore/LAN_discovery.h \ - ../toxcore/LAN_discovery.c \ - ../toxcore/friend_connection.h \ + ../toxcore/crypto_core_pack.h \ + ../toxcore/crypto_core.c \ + ../toxcore/crypto_core.h \ + ../toxcore/DHT.c \ + ../toxcore/DHT.h \ + ../toxcore/forwarding.c \ + ../toxcore/forwarding.h \ ../toxcore/friend_connection.c \ - ../toxcore/Messenger.h \ - ../toxcore/Messenger.c \ - ../toxcore/ping.h \ - ../toxcore/ping.c \ - ../toxcore/shared_key_cache.h \ - ../toxcore/shared_key_cache.c \ - ../toxcore/sort.h \ - ../toxcore/sort.c \ - ../toxcore/state.h \ - ../toxcore/state.c \ - ../toxcore/tox.h \ - ../toxcore/tox.c \ - ../toxcore/tox_dispatch.h \ - ../toxcore/tox_dispatch.c \ - ../toxcore/tox_event.h \ - ../toxcore/tox_event.c \ - ../toxcore/tox_events.h \ - ../toxcore/tox_events.c \ - ../toxcore/tox_pack.h \ - ../toxcore/tox_pack.c \ - ../toxcore/tox_unpack.h \ - ../toxcore/tox_unpack.c \ - ../toxcore/tox_private.c \ - ../toxcore/tox_private.h \ - ../toxcore/tox_struct.h \ - ../toxcore/tox_api.c \ - ../toxcore/util.h \ - ../toxcore/util.c \ - ../toxcore/group.h \ - ../toxcore/group.c \ - ../toxcore/group_announce.h \ + ../toxcore/friend_connection.h \ + ../toxcore/friend_requests.c \ + ../toxcore/friend_requests.h \ ../toxcore/group_announce.c \ - ../toxcore/group_onion_announce.c \ - ../toxcore/group_onion_announce.h \ - ../toxcore/group_chats.h \ + ../toxcore/group_announce.h \ ../toxcore/group_chats.c \ + ../toxcore/group_chats.h \ ../toxcore/group_common.h \ ../toxcore/group_connection.c \ ../toxcore/group_connection.h \ - ../toxcore/group_pack.c \ - ../toxcore/group_pack.h \ ../toxcore/group_moderation.c \ ../toxcore/group_moderation.h \ - ../toxcore/onion.h \ - ../toxcore/onion.c \ - ../toxcore/logger.h \ - ../toxcore/logger.c \ - ../toxcore/onion_announce.h \ - ../toxcore/onion_announce.c \ - ../toxcore/onion_client.h \ - ../toxcore/onion_client.c \ - ../toxcore/announce.h \ - ../toxcore/announce.c \ - ../toxcore/forwarding.h \ - ../toxcore/forwarding.c \ - ../toxcore/TCP_client.h \ - ../toxcore/TCP_client.c \ - ../toxcore/TCP_common.h \ - ../toxcore/TCP_common.c \ - ../toxcore/TCP_server.h \ - ../toxcore/TCP_server.c \ - ../toxcore/TCP_connection.h \ - ../toxcore/TCP_connection.c \ + ../toxcore/group_onion_announce.c \ + ../toxcore/group_onion_announce.h \ + ../toxcore/group_pack.c \ + ../toxcore/group_pack.h \ + ../toxcore/group.c \ + ../toxcore/group.h \ + ../toxcore/LAN_discovery.c \ + ../toxcore/LAN_discovery.h \ ../toxcore/list.c \ - ../toxcore/list.h + ../toxcore/list.h \ + ../toxcore/logger.c \ + ../toxcore/logger.h \ + ../toxcore/mem.c \ + ../toxcore/mem.h \ + ../toxcore/Messenger.c \ + ../toxcore/Messenger.h \ + ../toxcore/mono_time.c \ + ../toxcore/mono_time.h \ + ../toxcore/net_crypto.c \ + ../toxcore/net_crypto.h \ + ../toxcore/net_profile.c \ + ../toxcore/net_profile.h \ + ../toxcore/network.c \ + ../toxcore/network.h \ + ../toxcore/onion_announce.c \ + ../toxcore/onion_announce.h \ + ../toxcore/onion_client.c \ + ../toxcore/onion_client.h \ + ../toxcore/onion.c \ + ../toxcore/onion.h \ + ../toxcore/ping_array.c \ + ../toxcore/ping_array.h \ + ../toxcore/ping.c \ + ../toxcore/ping.h \ + ../toxcore/shared_key_cache.c \ + ../toxcore/shared_key_cache.h \ + ../toxcore/sort.c \ + ../toxcore/sort.h \ + ../toxcore/state.c \ + ../toxcore/state.h \ + ../toxcore/TCP_client.c \ + ../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_dispatch.c \ + ../toxcore/tox_dispatch.h \ + ../toxcore/tox_event.c \ + ../toxcore/tox_event.h \ + ../toxcore/tox_events.c \ + ../toxcore/tox_events.h \ + ../toxcore/tox_log_level.c \ + ../toxcore/tox_log_level.h \ + ../toxcore/tox_options.c \ + ../toxcore/tox_options.h \ + ../toxcore/tox_pack.c \ + ../toxcore/tox_pack.h \ + ../toxcore/tox_private.c \ + ../toxcore/tox_private.h \ + ../toxcore/tox_struct.h \ + ../toxcore/tox_unpack.c \ + ../toxcore/tox_unpack.h \ + ../toxcore/tox.c \ + ../toxcore/tox.h \ + ../toxcore/util.c \ + ../toxcore/util.h libtoxcore_la_CFLAGS = -I$(top_srcdir) \ -I$(top_srcdir)/toxcore \ diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index e7f8ee9..b89f831 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -3171,7 +3171,7 @@ static bool handle_groups_load(void *obj, Bin_Unpack *bu) non_null() static State_Load_Status groups_load(Messenger *m, const uint8_t *data, uint32_t length) { - if (!bin_unpack_obj(handle_groups_load, m, data, length)) { + if (!bin_unpack_obj(m->mem, handle_groups_load, m, data, length)) { LOGGER_ERROR(m->log, "msgpack failed to unpack groupchats array"); return STATE_LOAD_STATUS_ERROR; } diff --git a/toxcore/TCP_common.c b/toxcore/TCP_common.c index e9f67dc..1a8a5d9 100644 --- a/toxcore/TCP_common.c +++ b/toxcore/TCP_common.c @@ -236,7 +236,7 @@ int read_tcp_packet( * return -1 on failure. */ non_null() -static uint16_t read_tcp_length(const Logger *logger, const Memory *mem, const Network *ns, Socket sock, const IP_Port *ip_port) +static uint16_t read_tcp_length(const Logger *logger, const Network *ns, Socket sock, const IP_Port *ip_port) { const uint16_t count = net_socket_data_recv_buffer(ns, sock); @@ -275,7 +275,7 @@ int read_packet_tcp_secure_connection( uint16_t max_len, const IP_Port *ip_port) { if (*next_packet_length == 0) { - const uint16_t len = read_tcp_length(logger, mem, ns, sock, ip_port); + const uint16_t len = read_tcp_length(logger, ns, sock, ip_port); if (len == (uint16_t) -1) { return -1; diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index f5b32d9..288cd94 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c @@ -920,7 +920,7 @@ static int accept_connection(TCP_Server *tcp_server, Socket sock) } non_null() -static Socket new_listening_tcp_socket(const Logger *logger, const Network *ns, Family family, uint16_t port) +static Socket new_listening_tcp_socket(const Logger *logger, const Memory *mem, const Network *ns, Family family, uint16_t port) { const Socket sock = net_socket(ns, family, TOX_SOCK_STREAM, TOX_PROTO_TCP); @@ -942,10 +942,9 @@ static Socket new_listening_tcp_socket(const Logger *logger, const Network *ns, ok = ok && bind_to_port(ns, sock, family, port) && (net_listen(ns, sock, TCP_MAX_BACKLOG) == 0); if (!ok) { - char *const error = net_new_strerror(net_error()); + Net_Strerror error_str; LOGGER_WARNING(logger, "could not bind to TCP port %d (family = %d): %s", - port, family.value, error != nullptr ? error : "(null)"); - net_kill_strerror(error); + port, family.value, net_strerror(net_error(), &error_str)); kill_sock(ns, sock); return net_invalid_socket(); } @@ -1015,7 +1014,7 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random const Family family = ipv6_enabled ? net_family_ipv6() : net_family_ipv4(); for (uint32_t i = 0; i < num_sockets; ++i) { - const Socket sock = new_listening_tcp_socket(logger, ns, family, ports[i]); + const Socket sock = new_listening_tcp_socket(logger, mem, ns, family, ports[i]); if (!sock_valid(sock)) { continue; diff --git a/toxcore/bin_pack_test.cc b/toxcore/bin_pack_test.cc index 08e37ba..c46719c 100644 --- a/toxcore/bin_pack_test.cc +++ b/toxcore/bin_pack_test.cc @@ -3,11 +3,10 @@ #include #include -#include -#include #include "bin_unpack.h" #include "logger.h" +#include "mem.h" namespace { @@ -24,6 +23,7 @@ TEST(BinPack, TooSmallBufferIsNotExceeded) TEST(BinPack, PackedUint64CanBeUnpacked) { + const Memory *mem = os_memory(); const uint64_t orig = 1234567812345678LL; std::array buf; EXPECT_TRUE(bin_pack_obj( @@ -34,6 +34,7 @@ TEST(BinPack, PackedUint64CanBeUnpacked) uint64_t unpacked = 0; EXPECT_TRUE(bin_unpack_obj( + mem, [](void *obj, Bin_Unpack *bu) { return bin_unpack_u64_b(bu, static_cast(obj)); }, @@ -43,6 +44,7 @@ TEST(BinPack, PackedUint64CanBeUnpacked) TEST(BinPack, MsgPackedUint8CanBeUnpackedAsUint32) { + const Memory *mem = os_memory(); const uint8_t orig = 123; std::array buf; EXPECT_TRUE(bin_pack_obj( @@ -53,6 +55,7 @@ TEST(BinPack, MsgPackedUint8CanBeUnpackedAsUint32) uint32_t unpacked = 0; EXPECT_TRUE(bin_unpack_obj( + mem, [](void *obj, Bin_Unpack *bu) { return bin_unpack_u32(bu, static_cast(obj)); }, &unpacked, buf.data(), buf.size())); EXPECT_EQ(unpacked, 123); @@ -60,6 +63,7 @@ TEST(BinPack, MsgPackedUint8CanBeUnpackedAsUint32) TEST(BinPack, MsgPackedUint32CanBeUnpackedAsUint8IfSmallEnough) { + const Memory *mem = os_memory(); const uint32_t orig = 123; std::array buf; EXPECT_TRUE(bin_pack_obj( @@ -70,6 +74,7 @@ TEST(BinPack, MsgPackedUint32CanBeUnpackedAsUint8IfSmallEnough) uint8_t unpacked = 0; EXPECT_TRUE(bin_unpack_obj( + mem, [](void *obj, Bin_Unpack *bu) { return bin_unpack_u08(bu, static_cast(obj)); }, &unpacked, buf.data(), buf.size())); @@ -78,6 +83,7 @@ TEST(BinPack, MsgPackedUint32CanBeUnpackedAsUint8IfSmallEnough) TEST(BinPack, LargeMsgPackedUint32CannotBeUnpackedAsUint8) { + const Memory *mem = os_memory(); const uint32_t orig = 1234567; std::array buf; EXPECT_TRUE(bin_pack_obj( @@ -88,12 +94,14 @@ TEST(BinPack, LargeMsgPackedUint32CannotBeUnpackedAsUint8) uint8_t unpacked = 0; EXPECT_FALSE(bin_unpack_obj( + mem, [](void *obj, Bin_Unpack *bu) { return bin_unpack_u08(bu, static_cast(obj)); }, &unpacked, buf.data(), buf.size())); } TEST(BinPack, BinCanHoldPackedInts) { + const Memory *mem = os_memory(); struct Stuff { uint64_t u64; uint16_t u16; @@ -113,6 +121,7 @@ TEST(BinPack, BinCanHoldPackedInts) Stuff unpacked; EXPECT_TRUE(bin_unpack_obj( + mem, [](void *obj, Bin_Unpack *bu) { Stuff *stuff = static_cast(obj); uint32_t size; @@ -128,6 +137,7 @@ TEST(BinPack, BinCanHoldPackedInts) TEST(BinPack, BinCanHoldArbitraryData) { + const Memory *mem = os_memory(); std::array buf; EXPECT_TRUE(bin_pack_obj( [](const void *obj, const Logger *logger, Bin_Pack *bp) { @@ -138,6 +148,7 @@ TEST(BinPack, BinCanHoldArbitraryData) std::array str; EXPECT_TRUE(bin_unpack_obj( + mem, [](void *obj, Bin_Unpack *bu) { uint8_t *data = static_cast(obj); return bin_unpack_bin_fixed(bu, data, 5); @@ -148,10 +159,12 @@ TEST(BinPack, BinCanHoldArbitraryData) TEST(BinPack, OversizedArrayFailsUnpack) { + const Memory *mem = os_memory(); std::array buf = {0x91}; uint32_t size; EXPECT_FALSE(bin_unpack_obj( + mem, [](void *obj, Bin_Unpack *bu) { uint32_t *size_ptr = static_cast(obj); return bin_unpack_array(bu, size_ptr); diff --git a/toxcore/bin_unpack.c b/toxcore/bin_unpack.c index 82b7f8d..e311094 100644 --- a/toxcore/bin_unpack.c +++ b/toxcore/bin_unpack.c @@ -5,14 +5,16 @@ #include "bin_unpack.h" #include -#include #include #include "../third_party/cmp/cmp.h" #include "attributes.h" #include "ccompat.h" +#include "mem.h" struct Bin_Unpack { + const Memory *mem; + const uint8_t *bytes; uint32_t bytes_size; cmp_ctx_t ctx; @@ -54,17 +56,18 @@ static size_t null_writer(cmp_ctx_t *ctx, const void *data, size_t count) } non_null() -static void bin_unpack_init(Bin_Unpack *bu, const uint8_t *buf, uint32_t buf_size) +static void bin_unpack_init(Bin_Unpack *bu, const Memory *mem, const uint8_t *buf, uint32_t buf_size) { + bu->mem = mem; bu->bytes = buf; bu->bytes_size = buf_size; cmp_init(&bu->ctx, bu, buf_reader, buf_skipper, null_writer); } -bool bin_unpack_obj(bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size) +bool bin_unpack_obj(const Memory *mem, bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size) { Bin_Unpack bu; - bin_unpack_init(&bu, buf, buf_size); + bin_unpack_init(&bu, mem, buf, buf_size); return callback(obj, &bu); } @@ -120,10 +123,14 @@ bool bin_unpack_bin(Bin_Unpack *bu, uint8_t **data_ptr, uint32_t *data_length_pt // There aren't as many bytes as this bin claims to want to allocate. return false; } - uint8_t *const data = (uint8_t *)malloc(bin_size); + uint8_t *const data = (uint8_t *)mem_balloc(bu->mem, bin_size); + + if (data == nullptr) { + return false; + } if (!bin_unpack_bin_b(bu, data, bin_size)) { - free(data); + mem_delete(bu->mem, data); return false; } diff --git a/toxcore/bin_unpack.h b/toxcore/bin_unpack.h index 3557476..029c3a0 100644 --- a/toxcore/bin_unpack.h +++ b/toxcore/bin_unpack.h @@ -9,6 +9,7 @@ #include #include "attributes.h" +#include "mem.h" #ifdef __cplusplus extern "C" { @@ -46,7 +47,7 @@ typedef bool bin_unpack_cb(void *obj, Bin_Unpack *bu); * @retval false if an error occurred (e.g. buffer overrun). */ non_null() -bool bin_unpack_obj(bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size); +bool bin_unpack_obj(const Memory *mem, bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size); /** @brief Start unpacking a MessagePack array. * diff --git a/toxcore/events/dht_get_nodes_response.c b/toxcore/events/dht_get_nodes_response.c deleted file mode 100644 index 918b97d..0000000 --- a/toxcore/events/dht_get_nodes_response.c +++ /dev/null @@ -1,227 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later - * Copyright © 2022-2025 The TokTok team. - */ - -#include "events_alloc.h" - -#include -#include - -#include "../attributes.h" -#include "../bin_pack.h" -#include "../bin_unpack.h" -#include "../ccompat.h" -#include "../mem.h" -#include "../tox.h" -#include "../tox_event.h" -#include "../tox_events.h" -#include "../tox_private.h" - -/***************************************************** - * - * :: struct and accessors - * - *****************************************************/ - -struct Tox_Event_Dht_Get_Nodes_Response { - uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; - uint8_t *ip; - uint32_t ip_length; - uint16_t port; -}; - -non_null() -static bool tox_event_dht_get_nodes_response_set_public_key(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE]) -{ - memcpy(dht_get_nodes_response->public_key, public_key, TOX_PUBLIC_KEY_SIZE); - return true; -} -const uint8_t *tox_event_dht_get_nodes_response_get_public_key(const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response) -{ - return dht_get_nodes_response->public_key; -} - -non_null() -static bool tox_event_dht_get_nodes_response_set_ip(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, - const char *ip, uint32_t ip_length, const Memory *mem) -{ - if (dht_get_nodes_response->ip != nullptr) { - mem_delete(mem, dht_get_nodes_response->ip); - dht_get_nodes_response->ip = nullptr; - dht_get_nodes_response->ip_length = 0; - } - - uint8_t *ip_tmp = (uint8_t *)mem_balloc(mem, ip_length); - - if (ip_tmp == nullptr) { - return false; - } - - memcpy(ip_tmp, ip, ip_length); - dht_get_nodes_response->ip = ip_tmp; - dht_get_nodes_response->ip_length = ip_length; - return true; -} -uint32_t tox_event_dht_get_nodes_response_get_ip_length(const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response) -{ - return dht_get_nodes_response->ip_length; -} -const uint8_t *tox_event_dht_get_nodes_response_get_ip(const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response) -{ - return dht_get_nodes_response->ip; -} - -non_null() -static bool tox_event_dht_get_nodes_response_set_port(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, uint16_t port) -{ - dht_get_nodes_response->port = port; - return true; -} -uint16_t tox_event_dht_get_nodes_response_get_port(const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response) -{ - return dht_get_nodes_response->port; -} - -non_null() -static void tox_event_dht_get_nodes_response_construct(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response) -{ - *dht_get_nodes_response = (Tox_Event_Dht_Get_Nodes_Response) { - { - 0 - } - }; -} -non_null() -static void tox_event_dht_get_nodes_response_destruct(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, const Memory *mem) -{ - mem_delete(mem, dht_get_nodes_response->ip); -} - -bool tox_event_dht_get_nodes_response_pack( - const Tox_Event_Dht_Get_Nodes_Response *event, Bin_Pack *bp) -{ - return bin_pack_array(bp, 3) - && bin_pack_bin(bp, event->public_key, TOX_PUBLIC_KEY_SIZE) - && bin_pack_bin(bp, event->ip, event->ip_length) - && bin_pack_u16(bp, event->port); -} - -non_null() -static bool tox_event_dht_get_nodes_response_unpack_into( - Tox_Event_Dht_Get_Nodes_Response *event, Bin_Unpack *bu) -{ - if (!bin_unpack_array_fixed(bu, 3, nullptr)) { - return false; - } - - return bin_unpack_bin_fixed(bu, event->public_key, TOX_PUBLIC_KEY_SIZE) - && bin_unpack_bin(bu, &event->ip, &event->ip_length) - && bin_unpack_u16(bu, &event->port); -} - -const Tox_Event_Dht_Get_Nodes_Response *tox_event_get_dht_get_nodes_response( - const Tox_Event *event) -{ - return event->type == TOX_EVENT_DHT_GET_NODES_RESPONSE ? event->data.dht_get_nodes_response : nullptr; -} - -Tox_Event_Dht_Get_Nodes_Response *tox_event_dht_get_nodes_response_new(const Memory *mem) -{ - Tox_Event_Dht_Get_Nodes_Response *const dht_get_nodes_response = - (Tox_Event_Dht_Get_Nodes_Response *)mem_alloc(mem, sizeof(Tox_Event_Dht_Get_Nodes_Response)); - - if (dht_get_nodes_response == nullptr) { - return nullptr; - } - - tox_event_dht_get_nodes_response_construct(dht_get_nodes_response); - return dht_get_nodes_response; -} - -void tox_event_dht_get_nodes_response_free(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, const Memory *mem) -{ - if (dht_get_nodes_response != nullptr) { - tox_event_dht_get_nodes_response_destruct(dht_get_nodes_response, mem); - } - mem_delete(mem, dht_get_nodes_response); -} - -non_null() -static Tox_Event_Dht_Get_Nodes_Response *tox_events_add_dht_get_nodes_response(Tox_Events *events, const Memory *mem) -{ - Tox_Event_Dht_Get_Nodes_Response *const dht_get_nodes_response = tox_event_dht_get_nodes_response_new(mem); - - if (dht_get_nodes_response == nullptr) { - return nullptr; - } - - Tox_Event event; - event.type = TOX_EVENT_DHT_GET_NODES_RESPONSE; - event.data.dht_get_nodes_response = dht_get_nodes_response; - - if (!tox_events_add(events, &event)) { - tox_event_dht_get_nodes_response_free(dht_get_nodes_response, mem); - return nullptr; - } - return dht_get_nodes_response; -} - -bool tox_event_dht_get_nodes_response_unpack( - Tox_Event_Dht_Get_Nodes_Response **event, Bin_Unpack *bu, const Memory *mem) -{ - *event = tox_event_dht_get_nodes_response_new(mem); - - if (*event == nullptr) { - return false; - } - - return tox_event_dht_get_nodes_response_unpack_into(*event, bu); -} - -non_null() -static Tox_Event_Dht_Get_Nodes_Response *tox_event_dht_get_nodes_response_alloc(void *user_data) -{ - Tox_Events_State *state = tox_events_alloc(user_data); - assert(state != nullptr); - - if (state->events == nullptr) { - return nullptr; - } - - Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response = tox_events_add_dht_get_nodes_response(state->events, state->mem); - - if (dht_get_nodes_response == nullptr) { - state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; - return nullptr; - } - - return dht_get_nodes_response; -} - -/***************************************************** - * - * :: event handler - * - *****************************************************/ - -void tox_events_handle_dht_get_nodes_response( - Tox *tox, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE], - const char *ip, uint16_t port, void *user_data) -{ - Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response = tox_event_dht_get_nodes_response_alloc(user_data); - - if (dht_get_nodes_response == nullptr) { - return; - } - - const size_t ip_length = strlen(ip); - if (ip_length >= UINT32_MAX) { - return; - } - - const Tox_System *sys = tox_get_system(tox); - - tox_event_dht_get_nodes_response_set_public_key(dht_get_nodes_response, public_key); - tox_event_dht_get_nodes_response_set_ip(dht_get_nodes_response, ip, ip_length + 1, sys->mem); - tox_event_dht_get_nodes_response_set_port(dht_get_nodes_response, port); -} diff --git a/toxcore/events/dht_nodes_response.c b/toxcore/events/dht_nodes_response.c new file mode 100644 index 0000000..9c11e22 --- /dev/null +++ b/toxcore/events/dht_nodes_response.c @@ -0,0 +1,222 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2025 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include + +#include "../attributes.h" +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../mem.h" +#include "../tox.h" +#include "../tox_event.h" +#include "../tox_events.h" +#include "../tox_private.h" + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + +struct Tox_Event_Dht_Nodes_Response { + uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; + uint8_t *ip; + uint32_t ip_length; + uint16_t port; +}; + +non_null() +static bool tox_event_dht_nodes_response_set_public_key(Tox_Event_Dht_Nodes_Response *dht_nodes_response, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE]) +{ + memcpy(dht_nodes_response->public_key, public_key, TOX_PUBLIC_KEY_SIZE); + return true; +} +const uint8_t *tox_event_dht_nodes_response_get_public_key(const Tox_Event_Dht_Nodes_Response *dht_nodes_response) +{ + return dht_nodes_response->public_key; +} + +non_null() +static bool tox_event_dht_nodes_response_set_ip(Tox_Event_Dht_Nodes_Response *dht_nodes_response, + const char *ip, uint32_t ip_length, const Memory *mem) +{ + if (dht_nodes_response->ip != nullptr) { + mem_delete(mem, dht_nodes_response->ip); + dht_nodes_response->ip = nullptr; + dht_nodes_response->ip_length = 0; + } + + uint8_t *ip_tmp = (uint8_t *)mem_balloc(mem, ip_length + 1); + + if (ip_tmp == nullptr) { + return false; + } + + memcpy(ip_tmp, ip, ip_length + 1); + dht_nodes_response->ip = ip_tmp; + dht_nodes_response->ip_length = ip_length; + return true; +} +uint32_t tox_event_dht_nodes_response_get_ip_length(const Tox_Event_Dht_Nodes_Response *dht_nodes_response) +{ + return dht_nodes_response->ip_length; +} +const uint8_t *tox_event_dht_nodes_response_get_ip(const Tox_Event_Dht_Nodes_Response *dht_nodes_response) +{ + return dht_nodes_response->ip; +} + +non_null() +static bool tox_event_dht_nodes_response_set_port(Tox_Event_Dht_Nodes_Response *dht_nodes_response, uint16_t port) +{ + dht_nodes_response->port = port; + return true; +} +uint16_t tox_event_dht_nodes_response_get_port(const Tox_Event_Dht_Nodes_Response *dht_nodes_response) +{ + return dht_nodes_response->port; +} + +non_null() +static void tox_event_dht_nodes_response_construct(Tox_Event_Dht_Nodes_Response *dht_nodes_response) +{ + *dht_nodes_response = (Tox_Event_Dht_Nodes_Response) { + { + 0 + } + }; +} +non_null() +static void tox_event_dht_nodes_response_destruct(Tox_Event_Dht_Nodes_Response *dht_nodes_response, const Memory *mem) +{ + mem_delete(mem, dht_nodes_response->ip); +} + +bool tox_event_dht_nodes_response_pack( + const Tox_Event_Dht_Nodes_Response *event, Bin_Pack *bp) +{ + return bin_pack_array(bp, 3) + && bin_pack_bin(bp, event->public_key, TOX_PUBLIC_KEY_SIZE) + && bin_pack_bin(bp, event->ip, event->ip_length) + && bin_pack_u16(bp, event->port); +} + +non_null() +static bool tox_event_dht_nodes_response_unpack_into( + Tox_Event_Dht_Nodes_Response *event, Bin_Unpack *bu) +{ + if (!bin_unpack_array_fixed(bu, 3, nullptr)) { + return false; + } + + return bin_unpack_bin_fixed(bu, event->public_key, TOX_PUBLIC_KEY_SIZE) + && bin_unpack_bin(bu, &event->ip, &event->ip_length) + && bin_unpack_u16(bu, &event->port); +} + +const Tox_Event_Dht_Nodes_Response *tox_event_get_dht_nodes_response( + const Tox_Event *event) +{ + return event->type == TOX_EVENT_DHT_GET_NODES_RESPONSE ? event->data.dht_nodes_response : nullptr; +} + +Tox_Event_Dht_Nodes_Response *tox_event_dht_nodes_response_new(const Memory *mem) +{ + Tox_Event_Dht_Nodes_Response *const dht_nodes_response = + (Tox_Event_Dht_Nodes_Response *)mem_alloc(mem, sizeof(Tox_Event_Dht_Nodes_Response)); + + if (dht_nodes_response == nullptr) { + return nullptr; + } + + tox_event_dht_nodes_response_construct(dht_nodes_response); + return dht_nodes_response; +} + +void tox_event_dht_nodes_response_free(Tox_Event_Dht_Nodes_Response *dht_nodes_response, const Memory *mem) +{ + if (dht_nodes_response != nullptr) { + tox_event_dht_nodes_response_destruct(dht_nodes_response, mem); + } + mem_delete(mem, dht_nodes_response); +} + +non_null() +static Tox_Event_Dht_Nodes_Response *tox_events_add_dht_nodes_response(Tox_Events *events, const Memory *mem) +{ + Tox_Event_Dht_Nodes_Response *const dht_nodes_response = tox_event_dht_nodes_response_new(mem); + + if (dht_nodes_response == nullptr) { + return nullptr; + } + + Tox_Event event; + event.type = TOX_EVENT_DHT_GET_NODES_RESPONSE; + event.data.dht_nodes_response = dht_nodes_response; + + if (!tox_events_add(events, &event)) { + tox_event_dht_nodes_response_free(dht_nodes_response, mem); + return nullptr; + } + return dht_nodes_response; +} + +bool tox_event_dht_nodes_response_unpack( + Tox_Event_Dht_Nodes_Response **event, Bin_Unpack *bu, const Memory *mem) +{ + *event = tox_event_dht_nodes_response_new(mem); + + if (*event == nullptr) { + return false; + } + + return tox_event_dht_nodes_response_unpack_into(*event, bu); +} + +non_null() +static Tox_Event_Dht_Nodes_Response *tox_event_dht_nodes_response_alloc(void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return nullptr; + } + + Tox_Event_Dht_Nodes_Response *dht_nodes_response = tox_events_add_dht_nodes_response(state->events, state->mem); + + if (dht_nodes_response == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return nullptr; + } + + return dht_nodes_response; +} + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + +void tox_events_handle_dht_nodes_response( + Tox *tox, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE], + const char *ip, uint32_t ip_length, uint16_t port, void *user_data) +{ + Tox_Event_Dht_Nodes_Response *dht_nodes_response = tox_event_dht_nodes_response_alloc(user_data); + + if (dht_nodes_response == nullptr) { + return; + } + + const Tox_System *sys = tox_get_system(tox); + + tox_event_dht_nodes_response_set_public_key(dht_nodes_response, public_key); + tox_event_dht_nodes_response_set_ip(dht_nodes_response, ip, ip_length, sys->mem); + tox_event_dht_nodes_response_set_port(dht_nodes_response, port); +} diff --git a/toxcore/events/events_alloc.h b/toxcore/events/events_alloc.h index 7477559..d0343d9 100644 --- a/toxcore/events/events_alloc.h +++ b/toxcore/events/events_alloc.h @@ -35,7 +35,7 @@ tox_conference_message_cb tox_events_handle_conference_message; tox_conference_peer_list_changed_cb tox_events_handle_conference_peer_list_changed; tox_conference_peer_name_cb tox_events_handle_conference_peer_name; tox_conference_title_cb tox_events_handle_conference_title; -tox_dht_get_nodes_response_cb tox_events_handle_dht_get_nodes_response; +tox_dht_nodes_response_cb tox_events_handle_dht_nodes_response; tox_file_chunk_request_cb tox_events_handle_file_chunk_request; tox_file_recv_cb tox_events_handle_file_recv; tox_file_recv_chunk_cb tox_events_handle_file_recv_chunk; diff --git a/toxcore/forwarding_fuzz_test.cc b/toxcore/forwarding_fuzz_test.cc index 4b8521a..829d694 100644 --- a/toxcore/forwarding_fuzz_test.cc +++ b/toxcore/forwarding_fuzz_test.cc @@ -13,11 +13,11 @@ namespace { std::optional> prepare(Fuzz_Data &input) { CONSUME_OR_RETURN_VAL(const uint8_t *ipp_packed, input, SIZE_IP_PORT, std::nullopt); - IP_Port ipp; + IP_Port ipp{}; unpack_ip_port(&ipp, ipp_packed, SIZE_IP6, true); CONSUME_OR_RETURN_VAL(const uint8_t *forwarder_packed, input, SIZE_IP_PORT, std::nullopt); - IP_Port forwarder; + IP_Port forwarder{}; unpack_ip_port(&forwarder, forwarder_packed, SIZE_IP6, true); // 2 bytes: size of the request @@ -37,22 +37,22 @@ void TestSendForwardRequest(Fuzz_Data &input) const uint16_t chain_keys_size = chain_length * CRYPTO_PUBLIC_KEY_SIZE; CONSUME_OR_RETURN(const uint8_t *chain_keys, input, chain_keys_size); - auto prep = prepare(input); + const auto prep = prepare(input); if (!prep.has_value()) { return; } - auto [ipp, forwarder, data, data_size] = prep.value(); + const auto [ipp, forwarder, data, data_size] = prep.value(); // rest of the fuzz data is input for malloc and network Fuzz_System sys(input); - Ptr logger(logger_new(sys.mem.get()), logger_kill); + const Ptr logger(logger_new(sys.mem.get()), logger_kill); if (logger == nullptr) { return; } - Ptr net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(), &ipp.ip, - ipp.port, ipp.port + 100, nullptr), + const Ptr net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(), + &ipp.ip, ipp.port, ipp.port + 100, nullptr), kill_networking); if (net == nullptr) { return; @@ -66,22 +66,22 @@ void TestForwardReply(Fuzz_Data &input) CONSUME1_OR_RETURN(const uint16_t, sendback_length, input); CONSUME_OR_RETURN(const uint8_t *sendback, input, sendback_length); - auto prep = prepare(input); + const auto prep = prepare(input); if (!prep.has_value()) { return; } - auto [ipp, forwarder, data, data_size] = prep.value(); + const auto [ipp, forwarder, data, data_size] = prep.value(); // rest of the fuzz data is input for malloc and network Fuzz_System sys(input); - Ptr logger(logger_new(sys.mem.get()), logger_kill); + const Ptr logger(logger_new(sys.mem.get()), logger_kill); if (logger == nullptr) { return; } - Ptr net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(), &ipp.ip, - ipp.port, ipp.port + 100, nullptr), + const Ptr net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(), + &ipp.ip, ipp.port, ipp.port + 100, nullptr), kill_networking); if (net == nullptr) { return; diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index a364ac9..8ba655c 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c @@ -168,8 +168,6 @@ non_null() static void group_delete(GC_Session *c, GC_Chat *chat); non_null() static void group_cleanup(const GC_Session *c, GC_Chat *chat); non_null() static bool group_exists(const GC_Session *c, const uint8_t *chat_id); non_null() static void add_tcp_relays_to_chat(const GC_Session *c, GC_Chat *chat); -non_null(1, 2) nullable(4) -static bool peer_delete(const GC_Session *c, GC_Chat *chat, uint32_t peer_number, void *userdata); non_null() static void create_gc_session_keypair(const Logger *log, const Random *rng, uint8_t *public_key, uint8_t *secret_key); non_null() static size_t load_gc_peers(GC_Chat *chat, const GC_SavedPeerInfo *addrs, uint16_t num_addrs); @@ -837,6 +835,21 @@ static int saved_peer_index(const GC_Chat *chat, const uint8_t *public_key) return -1; } +/** @brief Removes entry containing `public_key` from the saved peers list. */ +non_null() +static void saved_peers_remove_entry(GC_Chat *chat, const uint8_t *public_key) +{ + const int idx = saved_peer_index(chat, public_key); + + if (idx < 0) { + return; + } + + chat->saved_peers[idx] = (GC_SavedPeerInfo) { + 0 + }; +} + /** @brief Returns the index of the first vacant entry in saved peers list. * * If `public_key` is non-null and already exists in the list, its index will be returned. @@ -6701,6 +6714,7 @@ void gc_callback_rejected(const Messenger *m, gc_rejected_cb *function) * * Return true on success. */ +non_null(1, 2) nullable(4) static bool peer_delete(const GC_Session *c, GC_Chat *chat, uint32_t peer_number, void *userdata) { GC_Peer *peer = get_gc_peer(chat, peer_number); @@ -6709,17 +6723,23 @@ static bool peer_delete(const GC_Session *c, GC_Chat *chat, uint32_t peer_number return false; } + GC_Connection *gconn = &peer->gconn; + // We need to save some peer info for the callback before deleting it - const bool peer_confirmed = peer->gconn.confirmed; + const bool peer_confirmed = gconn->confirmed; const GC_Peer_Id peer_id = peer->peer_id; uint8_t nick[MAX_GC_NICK_SIZE]; const uint16_t nick_length = peer->nick_length; - const GC_Exit_Info exit_info = peer->gconn.exit_info; + const GC_Exit_Info exit_info = gconn->exit_info; assert(nick_length <= MAX_GC_NICK_SIZE); memcpy(nick, peer->nick, nick_length); - gcc_peer_cleanup(chat->mem, &peer->gconn); + if (exit_info.exit_type == GC_EXIT_TYPE_KICKED) { + saved_peers_remove_entry(chat, gconn->addr.public_key.enc); + } + + gcc_peer_cleanup(chat->mem, gconn); --chat->numpeers; diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index c21ac7d..ee89a9e 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -20,6 +20,10 @@ #include "net_profile.h" #include "network.h" +#ifdef __cplusplus +extern "C" { +#endif + /*** Crypto payloads. */ /*** Ranges. */ @@ -422,4 +426,8 @@ void kill_net_crypto(Net_Crypto *c); non_null() const Net_Profile *nc_get_tcp_client_net_profile(const Net_Crypto *c); +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif /* C_TOXCORE_TOXCORE_NET_CRYPTO_H */ diff --git a/toxcore/net_crypto_fuzz_test.cc b/toxcore/net_crypto_fuzz_test.cc new file mode 100644 index 0000000..e5add8d --- /dev/null +++ b/toxcore/net_crypto_fuzz_test.cc @@ -0,0 +1,93 @@ +#include "net_crypto.h" + +#include +#include +#include +#include +#include + +#include "../testing/fuzzing/fuzz_support.hh" +#include "../testing/fuzzing/fuzz_tox.hh" +#include "DHT.h" +#include "TCP_client.h" +#include "network.h" + +namespace { + +std::optional> prepare(Fuzz_Data &input) +{ + IP_Port ipp; + ip_init(&ipp.ip, true); + ipp.port = 33445; + + CONSUME_OR_RETURN_VAL(const uint8_t *iterations_packed, input, 1, std::nullopt); + uint8_t iterations = *iterations_packed; + + return {{ipp, iterations}}; +} + +void TestNetCrypto(Fuzz_Data &input) +{ + const auto prep = prepare(input); + if (!prep.has_value()) { + return; + } + const auto [ipp, iterations] = prep.value(); + + // rest of the fuzz data is input for malloc and network + Fuzz_System sys(input); + + const Ptr logger(logger_new(sys.mem.get()), logger_kill); + if (logger == nullptr) { + return; + } + + const Ptr net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(), + &ipp.ip, ipp.port, ipp.port + 100, nullptr), + kill_networking); + if (net == nullptr) { + return; + } + + const std::unique_ptr> mono_time( + mono_time_new( + sys.mem.get(), [](void *user_data) { return *static_cast(user_data); }, + &sys.clock), + [mem = sys.mem.get()](Mono_Time *ptr) { mono_time_free(mem, ptr); }); + if (mono_time == nullptr) { + return; + } + + const Ptr dht(new_dht(logger.get(), sys.mem.get(), sys.rng.get(), sys.ns.get(), + mono_time.get(), net.get(), false, false), + kill_dht); + if (dht == nullptr) { + return; + } + + const TCP_Proxy_Info proxy_info = {0}; + + const Ptr net_crypto(new_net_crypto(logger.get(), sys.mem.get(), sys.rng.get(), + sys.ns.get(), mono_time.get(), dht.get(), &proxy_info), + kill_net_crypto); + if (net_crypto == nullptr) { + return; + } + + for (uint8_t i = 0; i < iterations; ++i) { + networking_poll(net.get(), nullptr); + do_dht(dht.get()); + do_net_crypto(net_crypto.get(), nullptr); + // "Sleep" + sys.clock += System::BOOTSTRAP_ITERATION_INTERVAL; + } +} + +} // namespace + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + fuzz_select_target(data, size); + return 0; +} diff --git a/toxcore/net_profile.c b/toxcore/net_profile.c index bbff79c..1d700bd 100644 --- a/toxcore/net_profile.c +++ b/toxcore/net_profile.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-3.0-or-later - * Copyright © 2023-2024 The TokTok team. + * Copyright © 2023-2025 The TokTok team. */ /** diff --git a/toxcore/net_profile.h b/toxcore/net_profile.h index a2f66a1..a4c6516 100644 --- a/toxcore/net_profile.h +++ b/toxcore/net_profile.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-3.0-or-later - * Copyright © 2023-2024 The TokTok team. + * Copyright © 2023-2025 The TokTok team. */ /** diff --git a/toxcore/network.c b/toxcore/network.c index 396d56b..bd6babf 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -264,9 +264,11 @@ static int make_family(Family tox_family) { switch (tox_family.value) { case TOX_AF_INET: + case TCP_INET: return AF_INET; case TOX_AF_INET6: + case TCP_INET6: return AF_INET6; case TOX_AF_UNSPEC: @@ -590,7 +592,11 @@ static int sys_getsockopt(void *obj, Socket sock, int level, int optname, void * non_null() static int sys_setsockopt(void *obj, Socket sock, int level, int optname, const void *optval, size_t optlen) { +#ifdef EMSCRIPTEN + return 0; +#else return setsockopt(net_socket_to_native(sock), level, optname, (const char *)optval, optlen); +#endif /* EMSCRIPTEN */ } // sets and fills an array of addrs for address @@ -770,11 +776,11 @@ static const char *net_packet_type_name(Net_Packet_Type type) case NET_PACKET_PING_RESPONSE: return "PING_RESPONSE"; - case NET_PACKET_GET_NODES: - return "GET_NODES"; + case NET_PACKET_NODES_REQUEST: + return "NODES_REQUEST"; - case NET_PACKET_SEND_NODES_IPV6: - return "SEND_NODES_IPV6"; + case NET_PACKET_NODES_RESPONSE: + return "NODES_RESPONSE"; case NET_PACKET_COOKIE_REQUEST: return "COOKIE_REQUEST"; @@ -883,13 +889,12 @@ static void loglogdata(const Logger *log, const char *message, const uint8_t *bu if (res < 0) { /* Windows doesn't necessarily know `%zu` */ Ip_Ntoa ip_str; const int error = net_error(); - char *strerror = net_new_strerror(error); + Net_Strerror error_str; LOGGER_TRACE(log, "[%02x = %-21s] %s %3u%c %s:%u (%u: %s) | %08x%08x...%02x", buffer[0], net_packet_type_name((Net_Packet_Type)buffer[0]), message, min_u16(buflen, 999), 'E', net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), error, - strerror, data_0(buflen, buffer), data_1(buflen, buffer), buffer[buflen - 1]); - net_kill_strerror(strerror); + net_strerror(error, &error_str), data_0(buflen, buffer), data_1(buflen, buffer), buffer[buflen - 1]); } else if ((res > 0) && ((size_t)res <= buflen)) { Ip_Ntoa ip_str; LOGGER_TRACE(log, "[%02x = %-21s] %s %3u%c %s:%u (%u: %s) | %08x%08x...%02x", @@ -1048,7 +1053,7 @@ int send_packet(const Networking_Core *net, const IP_Port *ip_port, Packet packe if (net_family_is_unspec(net->family)) { /* Socket not initialized */ // TODO(iphydf): Make this an error. Currently, the onion client calls - // this via DHT getnodes. + // this via DHT nodes requests. LOGGER_WARNING(net->log, "attempted to send message of length %u on uninitialised socket", packet.length); return -1; } @@ -1131,7 +1136,7 @@ int sendpacket(const Networking_Core *net, const IP_Port *ip_port, const uint8_t * Packet length is put into length. */ non_null() -static int receivepacket(const Network *ns, const Memory *mem, const Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) +static int receivepacket(const Network *ns, const Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) { memset(ip_port, 0, sizeof(IP_Port)); Network_Addr addr = {{0}}; @@ -1144,9 +1149,8 @@ static int receivepacket(const Network *ns, const Memory *mem, const Logger *log const int error = net_error(); if (!should_ignore_recv_error(error)) { - char *strerror = net_new_strerror(error); - LOGGER_ERROR(log, "unexpected error reading from socket: %u, %s", error, strerror); - net_kill_strerror(strerror); + Net_Strerror error_str; + LOGGER_ERROR(log, "unexpected error reading from socket: %u, %s", error, net_strerror(error, &error_str)); } return -1; /* Nothing received. */ @@ -1210,7 +1214,7 @@ void networking_poll(const Networking_Core *net, void *userdata) uint8_t data[MAX_UDP_PACKET_SIZE] = {0}; uint32_t length; - while (receivepacket(net->ns, net->mem, net->log, net->sock, &ip_port, data, &length) != -1) { + while (receivepacket(net->ns, net->log, net->sock, &ip_port, data, &length) != -1) { if (length < 1) { continue; } @@ -1298,9 +1302,8 @@ Networking_Core *new_networking_ex( /* Check for socket error. */ if (!sock_valid(temp->sock)) { const int neterror = net_error(); - char *strerror = net_new_strerror(neterror); - LOGGER_ERROR(log, "failed to get a socket?! %d, %s", neterror, strerror); - net_kill_strerror(strerror); + Net_Strerror error_str; + LOGGER_ERROR(log, "failed to get a socket?! %d, %s", neterror, net_strerror(neterror, &error_str)); netprof_kill(mem, temp->udp_net_profile); mem_delete(mem, temp); @@ -1402,15 +1405,13 @@ Networking_Core *new_networking_ex( const int res = net_setsockopt(ns, temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); const int neterror = net_error(); - char *strerror = net_new_strerror(neterror); + Net_Strerror error_str; if (res < 0) { - LOGGER_INFO(log, "Failed to activate local multicast membership in FF02::1. (%d, %s)", neterror, strerror); + LOGGER_INFO(log, "Failed to activate local multicast membership in FF02::1. (%d, %s)", neterror, net_strerror(neterror, &error_str)); } else { - LOGGER_TRACE(log, "Local multicast group joined successfully. (%d, %s)", neterror, strerror); + LOGGER_TRACE(log, "Local multicast group joined successfully. (%d, %s)", neterror, net_strerror(neterror, &error_str)); } - - net_kill_strerror(strerror); #endif /* ESP_PLATFORM */ } @@ -1468,10 +1469,9 @@ Networking_Core *new_networking_ex( Ip_Ntoa ip_str; const int neterror = net_error(); - char *strerror = net_new_strerror(neterror); + Net_Strerror error_str; LOGGER_ERROR(log, "failed to bind socket: %d, %s IP: %s port_from: %u port_to: %u", - neterror, strerror, net_ip_ntoa(ip, &ip_str), port_from, port_to); - net_kill_strerror(strerror); + neterror, net_strerror(neterror, &error_str), net_ip_ntoa(ip, &ip_str), port_from, port_to); kill_networking(temp); if (error != nullptr) { @@ -1878,14 +1878,14 @@ bool ip_parse_addr(const IP *ip, char *address, size_t length) return false; } - if (net_family_is_ipv4(ip->family)) { + if (net_family_is_ipv4(ip->family) || net_family_is_tcp_ipv4(ip->family)) { struct in_addr addr; assert(make_family(ip->family) == AF_INET); fill_addr4(&ip->ip.v4, &addr); return inet_ntop4(&addr, address, length) != nullptr; } - if (net_family_is_ipv6(ip->family)) { + if (net_family_is_ipv6(ip->family) || net_family_is_tcp_ipv6(ip->family)) { struct in6_addr addr; assert(make_family(ip->family) == AF_INET6); fill_addr6(&ip->ip.v6, &addr); @@ -2097,10 +2097,9 @@ bool net_connect(const Network *ns, const Memory *mem, const Logger *log, Socket // Non-blocking socket: "Operation in progress" means it's connecting. if (!should_ignore_connect_error(error)) { - char *net_strerror = net_new_strerror(error); + Net_Strerror error_str; LOGGER_WARNING(log, "failed to connect to %s:%d: %d (%s)", - net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), error, net_strerror); - net_kill_strerror(net_strerror); + net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), error, net_strerror(error, &error_str)); *err = NET_ERR_CONNECT_FAILED; return false; } @@ -2367,19 +2366,11 @@ int net_error(void) } #ifdef OS_WIN32 -char *net_new_strerror(int error) +char *net_strerror(int error, Net_Strerror *buf) { - char *str = nullptr; - // Windows API is weird. The 5th function arg is of char* type, but we - // have to pass char** so that it could assign new memory block to our - // pointer, so we have to cast our char** to char* for the compilation - // not to fail (otherwise it would fail to find a variant of this function - // accepting char** as the 5th arg) and Windows inside casts it back - // to char** to do the assignment. So no, this cast you see here, although - // it looks weird, is not a mistake. - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, - error, 0, (char *)&str, 0, nullptr); - return str; + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, + error, 0, buf->data, NET_STRERROR_SIZE, nullptr); + return buf->data; } #else #if defined(_GNU_SOURCE) && defined(__GLIBC__) @@ -2407,36 +2398,19 @@ static const char *net_strerror_r(int error, char *tmp, size_t tmp_size) return tmp; } #endif /* GNU */ -char *net_new_strerror(int error) +char *net_strerror(int error, Net_Strerror *buf) { - char tmp[256]; - errno = 0; - const char *retstr = net_strerror_r(error, tmp, sizeof(tmp)); + const char *retstr = net_strerror_r(error, buf->data, NET_STRERROR_SIZE); const size_t retstr_len = strlen(retstr); + assert(retstr_len < NET_STRERROR_SIZE); + buf->size = (uint16_t)retstr_len; - char *str = (char *)malloc(retstr_len + 1); - - if (str == nullptr) { - return nullptr; - } - - memcpy(str, retstr, retstr_len + 1); - - return str; + return buf->data; } #endif /* OS_WIN32 */ -void net_kill_strerror(char *strerror) -{ -#ifdef OS_WIN32 - LocalFree((char *)strerror); -#else - free(strerror); -#endif /* OS_WIN32 */ -} - const Net_Profile *net_get_net_profile(const Networking_Core *net) { if (net == nullptr) { diff --git a/toxcore/network.h b/toxcore/network.h index 41d7eaf..a13c98b 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -113,8 +113,8 @@ Family net_family_tox_tcp_ipv6(void); typedef enum Net_Packet_Type { NET_PACKET_PING_REQUEST = 0x00, /* Ping request packet ID. */ NET_PACKET_PING_RESPONSE = 0x01, /* Ping response packet ID. */ - NET_PACKET_GET_NODES = 0x02, /* Get nodes request packet ID. */ - NET_PACKET_SEND_NODES_IPV6 = 0x04, /* Send nodes response packet ID for other addresses. */ + NET_PACKET_NODES_REQUEST = 0x02, /* Nodes request packet ID. */ + NET_PACKET_NODES_RESPONSE = 0x04, /* Nodes response packet ID. */ NET_PACKET_COOKIE_REQUEST = 0x18, /* Cookie request packet */ NET_PACKET_COOKIE_RESPONSE = 0x19, /* Cookie response packet */ NET_PACKET_CRYPTO_HS = 0x1a, /* Crypto handshake packet */ @@ -236,12 +236,27 @@ Socket net_invalid_socket(void); /** * Calls send(sockfd, buf, len, MSG_NOSIGNAL). + * + * @param ns System network object. + * @param log Logger object. + * @param sock Socket to send data with. + * @param buf Data to send. + * @param len Length of data. + * @param ip_port IP and port to send data to. + * @param net_profile Network profile to record the packet. */ non_null(1, 2, 4, 6) nullable(7) int net_send(const Network *ns, const Logger *log, Socket sock, const uint8_t *buf, size_t len, const IP_Port *ip_port, Net_Profile *net_profile); /** * Calls recv(sockfd, buf, len, MSG_NOSIGNAL). + * + * @param ns System network object. + * @param log Logger object. + * @param sock Socket to receive data with. + * @param buf Buffer to store received data. + * @param len Length of buffer. + * @param ip_port IP and port of the sender. */ non_null() int net_recv(const Network *ns, const Logger *log, Socket sock, uint8_t *buf, size_t len, const IP_Port *ip_port); @@ -582,26 +597,32 @@ bool bind_to_port(const Network *ns, Socket sock, Family family, uint16_t port); * Note that different platforms may return different codes for the same error, * so you likely shouldn't be checking the value returned by this function * unless you know what you are doing, you likely just want to use it in - * combination with `net_new_strerror()` to print the error. + * combination with `net_strerror()` to print the error. * * return platform-dependent network error code, if any. */ int net_error(void); +#define NET_STRERROR_SIZE 256 + +/** @brief Contains a null terminated formatted error message. + * + * This struct should not contain more than at most the 2 fields. + */ +typedef struct Net_Strerror { + char data[NET_STRERROR_SIZE]; + uint16_t size; +} Net_Strerror; + /** @brief Get a text explanation for the error code from `net_error()`. * - * return NULL on failure. - * return pointer to a NULL-terminated string describing the error code on - * success. The returned string must be freed using `net_kill_strerror()`. + * @param error The error code to get a string for. + * @param buf The struct to store the error message in (usually on stack). + * + * @return pointer to a NULL-terminated string describing the error code. */ -char *net_new_strerror(int error); - -/** @brief Frees the string returned by `net_new_strerror()`. - * It's valid to pass NULL as the argument, the function does nothing in this - * case. - */ -nullable(1) -void net_kill_strerror(char *strerror); +non_null() +char *net_strerror(int error, Net_Strerror *buf); /** @brief Initialize networking. * Bind to ip and port. diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index 7f76c83..e802d70 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -470,6 +470,7 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa onion_paths->paths[pathnum].path_num = path_num; } else { + assert(0 <= n && n < NUMBER_ONION_PATHS); pathnum = n; } } @@ -1264,7 +1265,7 @@ static int handle_dhtpk_announce(void *object, const uint8_t *source_pubkey, con const Family family = nodes[i].ip_port.ip.family; if (net_family_is_ipv4(family) || net_family_is_ipv6(family)) { - dht_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].public_key, onion_c->friends_list[friend_num].dht_public_key); + dht_send_nodes_request(onion_c->dht, &nodes[i].ip_port, nodes[i].public_key, onion_c->friends_list[friend_num].dht_public_key); } else if (net_family_is_tcp_ipv4(family) || net_family_is_tcp_ipv6(family)) { if (onion_c->friends_list[friend_num].tcp_relay_node_callback != nullptr) { void *obj = onion_c->friends_list[friend_num].tcp_relay_node_callback_object; diff --git a/toxcore/tox.c b/toxcore/tox.c index 7349928..8e1b439 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -32,6 +32,8 @@ #include "network.h" #include "onion_client.h" #include "state.h" +#include "tox_log_level.h" +#include "tox_options.h" #include "tox_private.h" #include "tox_struct.h" // IWYU pragma: keep #include "util.h" @@ -360,20 +362,22 @@ static void tox_conference_peer_list_changed_handler(Messenger *m, uint32_t conf } } -static dht_get_nodes_response_cb tox_dht_get_nodes_response_handler; +static dht_nodes_response_cb tox_dht_nodes_response_handler; non_null(1, 2) nullable(3) -static void tox_dht_get_nodes_response_handler(const DHT *dht, const Node_format *node, void *user_data) +static void tox_dht_nodes_response_handler(const DHT *dht, const Node_format *node, void *user_data) { struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; - if (tox_data->tox->dht_get_nodes_response_callback == nullptr) { + if (tox_data->tox->dht_nodes_response_callback == nullptr) { return; } Ip_Ntoa ip_str; + net_ip_ntoa(&node->ip_port.ip, &ip_str); + tox_unlock(tox_data->tox); - tox_data->tox->dht_get_nodes_response_callback( - tox_data->tox, node->public_key, net_ip_ntoa(&node->ip_port.ip, &ip_str), net_ntohs(node->ip_port.port), + tox_data->tox->dht_nodes_response_callback( + tox_data->tox, node->public_key, ip_str.buf, ip_str.length, net_ntohs(node->ip_port.port), tox_data->user_data); tox_lock(tox_data->tox); } @@ -986,7 +990,7 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error callback_file_reqchunk(tox->m, tox_file_chunk_request_handler); callback_file_sendrequest(tox->m, tox_file_recv_handler); callback_file_data(tox->m, tox_file_recv_chunk_handler); - dht_callback_get_nodes_response(tox->m->dht, tox_dht_get_nodes_response_handler); + dht_callback_nodes_response(tox->m->dht, tox_dht_nodes_response_handler); g_callback_group_invite(tox->m->conferences_object, tox_conference_invite_handler); g_callback_group_connected(tox->m->conferences_object, tox_conference_connected_handler); g_callback_group_message(tox->m->conferences_object, tox_conference_message_handler); diff --git a/toxcore/tox.h b/toxcore/tox.h index dddaf16..f44b820 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -102,14 +102,14 @@ #include #include +#include "tox_options.h" // IWYU pragma: export + #ifdef __cplusplus extern "C" { #endif /** @{ @namespace tox */ -#ifndef TOX_DEFINED -#define TOX_DEFINED /** * @brief The Tox instance type. * @@ -120,7 +120,6 @@ extern "C" { * limiting factor is the number of usable ports on a device. */ typedef struct Tox Tox; -#endif /* TOX_DEFINED */ /** @{ * @name API version @@ -155,7 +154,7 @@ uint32_t tox_version_minor(void); * Incremented when bugfixes are applied without changing any functionality or * API or ABI. */ -#define TOX_VERSION_PATCH 20 +#define TOX_VERSION_PATCH 21 uint32_t tox_version_patch(void); @@ -393,439 +392,6 @@ const char *tox_message_type_to_string(Tox_Message_Type value); /** @} */ -/** @{ - * @name Startup options - */ - -/** - * @brief Type of proxy used to connect to TCP relays. - */ -typedef enum Tox_Proxy_Type { - - /** - * Don't use a proxy. - */ - TOX_PROXY_TYPE_NONE, - - /** - * HTTP proxy using CONNECT. - */ - TOX_PROXY_TYPE_HTTP, - - /** - * SOCKS proxy for simple socket pipes. - */ - TOX_PROXY_TYPE_SOCKS5, - -} Tox_Proxy_Type; - -const char *tox_proxy_type_to_string(Tox_Proxy_Type value); - -/** - * @brief Type of savedata to create the Tox instance from. - */ -typedef enum Tox_Savedata_Type { - - /** - * No savedata. - */ - TOX_SAVEDATA_TYPE_NONE, - - /** - * Savedata is one that was obtained from tox_get_savedata. - */ - TOX_SAVEDATA_TYPE_TOX_SAVE, - - /** - * Savedata is a secret key of length TOX_SECRET_KEY_SIZE. - */ - TOX_SAVEDATA_TYPE_SECRET_KEY, - -} Tox_Savedata_Type; - -const char *tox_savedata_type_to_string(Tox_Savedata_Type value); - -/** - * @brief Severity level of log messages. - */ -typedef enum Tox_Log_Level { - - /** - * Very detailed traces including all network activity. - */ - TOX_LOG_LEVEL_TRACE, - - /** - * Debug messages such as which port we bind to. - */ - TOX_LOG_LEVEL_DEBUG, - - /** - * Informational log messages such as video call status changes. - */ - TOX_LOG_LEVEL_INFO, - - /** - * Warnings about internal inconsistency or logic errors. - */ - TOX_LOG_LEVEL_WARNING, - - /** - * Severe unexpected errors caused by external or internal inconsistency. - */ - TOX_LOG_LEVEL_ERROR, - -} Tox_Log_Level; - -const char *tox_log_level_to_string(Tox_Log_Level value); - -/** - * @brief This event is triggered when Tox logs an internal message. - * - * This is mostly useful for debugging. This callback can be called from any - * function, not just tox_iterate. This means the user data lifetime must at - * least extend between registering and unregistering it or tox_kill. - * - * Other toxcore modules such as toxav may concurrently call this callback at - * any time. Thus, user code must make sure it is equipped to handle concurrent - * execution, e.g. by employing appropriate mutex locking. - * - * When using the experimental_thread_safety option, no Tox API functions can - * be called from within the log callback. - * - * @param level The severity of the log message. - * @param file The source file from which the message originated. - * @param line The source line from which the message originated. - * @param func The function from which the message originated. - * @param message The log message. - * @param user_data The user data pointer passed to tox_new in options. - */ -typedef void tox_log_cb(Tox *tox, Tox_Log_Level level, const char *file, uint32_t line, const char *func, - const char *message, void *user_data); - -/** - * @brief This struct contains all the startup options for Tox. - * - * You must tox_options_new to allocate an object of this type. - * - * WARNING: Although this struct happens to be visible in the API, it is - * effectively private. Do not allocate this yourself or access members - * directly, as it *will* break binary compatibility frequently. - * - * @deprecated The memory layout of this struct (size, alignment, and field - * order) is not part of the ABI. To remain compatible, prefer to use - * tox_options_new to allocate the object and accessor functions to set the - * members. The struct will become opaque (i.e. the definition will become - * private) in v0.3.0. - */ -typedef struct Tox_Options Tox_Options; -#ifndef TOX_HIDE_DEPRECATED -struct Tox_Options { - - /** - * The type of socket to create. - * - * If this is set to false, an IPv4 socket is created, which subsequently - * only allows IPv4 communication. - * If it is set to true, an IPv6 socket is created, allowing both IPv4 and - * IPv6 communication. - */ - bool ipv6_enabled; - - /** - * Enable the use of UDP communication when available. - * - * Setting this to false will force Tox to use TCP only. Communications will - * need to be relayed through a TCP relay node, potentially slowing them - * down. - * - * If a proxy is enabled, UDP will be disabled if either the Tox library or - * the proxy don't support proxying UDP messages. - */ - bool udp_enabled; - - /** - * Enable local network peer discovery. - * - * Disabling this will cause Tox to not look for peers on the local network. - */ - bool local_discovery_enabled; - - /** - * Enable storing DHT announcements and forwarding corresponding requests. - * - * Disabling this will cause Tox to ignore the relevant packets. - */ - bool dht_announcements_enabled; - - /** - * Pass communications through a proxy. - */ - Tox_Proxy_Type proxy_type; - - /** - * The IP address or DNS name of the proxy to be used. - * - * If used, this must be non-NULL and be a valid DNS name. The name must not - * exceed TOX_MAX_HOSTNAME_LENGTH characters, and be in a NUL-terminated C - * string format (TOX_MAX_HOSTNAME_LENGTH includes the NUL byte). - * - * This member is ignored (it can be NULL) if proxy_type is - * TOX_PROXY_TYPE_NONE. - * - * The data pointed at by this member is owned by the user, so must - * outlive the options object. - */ - const char *proxy_host; - - /** - * The port to use to connect to the proxy server. - * - * Ports must be in the range (1, 65535). The value is ignored if - * proxy_type is TOX_PROXY_TYPE_NONE. - */ - uint16_t proxy_port; - - /** - * The start port of the inclusive port range to attempt to use. - * - * If both start_port and end_port are 0, the default port range will be - * used: `[33445, 33545]`. - * - * If either start_port or end_port is 0 while the other is non-zero, the - * non-zero port will be the only port in the range. - * - * Having start_port > end_port will yield the same behavior as if - * start_port and end_port were swapped. - */ - uint16_t start_port; - - /** - * The end port of the inclusive port range to attempt to use. - */ - uint16_t end_port; - - /** - * The port to use for the TCP server (relay). If 0, the TCP server is - * disabled. - * - * Enabling it is not required for Tox to function properly. - * - * When enabled, your Tox instance can act as a TCP relay for other Tox - * instance. This leads to increased traffic, thus when writing a client - * it is recommended to enable TCP server only if the user has an option - * to disable it. - */ - uint16_t tcp_port; - - /** - * Enables or disables UDP hole-punching. (Default: enabled). - */ - bool hole_punching_enabled; - - /** - * The type of savedata to load from. - */ - Tox_Savedata_Type savedata_type; - - /** - * The savedata. - * - * The data pointed at by this member is owned by the user, so must outlive - * the options object. - */ - const uint8_t *savedata_data; - - /** - * The length of the savedata. - */ - size_t savedata_length; - - /** - * Logging callback for the new Tox instance. - */ - tox_log_cb *log_callback; - - /** - * User data pointer passed to the logging callback. - */ - void *log_user_data; - - /** - * These options are experimental, so avoid writing code that depends on - * them. Options marked "experimental" may change their behaviour or go away - * entirely in the future, or may be renamed to something non-experimental - * if they become part of the supported API. - */ - /** - * Make public API functions thread-safe using a per-instance lock. - * - * Default: false. - */ - bool experimental_thread_safety; - - /** - * Enable saving DHT-based group chats to Tox save data (via - * `tox_get_savedata`). This format will change in the future, so don't rely - * on it. - * - * As an alternative, clients can save the group chat ID in client-owned - * savedata. Then, when the client starts, it can use `tox_group_join` - * with the saved chat ID to recreate the group chat. - * - * Default: false. - */ - bool experimental_groups_persistence; - - /** - * @brief Disable DNS hostname resolution. - * - * Hostnames or IP addresses are passed to the bootstrap/add_tcp_relay - * function and proxy host options. If disabled (this flag is true), only - * IP addresses are allowed. - * - * If this is set to true, the library will not attempt to resolve - * hostnames. This is useful for clients that want to resolve hostnames - * themselves and pass the resolved IP addresses to the library (e.g. in - * case it wants to use Tor). - * Passing hostnames will result in a TOX_ERR_BOOTSTRAP_BAD_HOST error if - * this is set to true. - * - * Default: false. May become true in the future (0.3.0). - */ - bool experimental_disable_dns; -}; -#endif /* TOX_HIDE_DEPRECATED */ - -bool tox_options_get_ipv6_enabled(const Tox_Options *options); - -void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled); - -bool tox_options_get_udp_enabled(const Tox_Options *options); - -void tox_options_set_udp_enabled(Tox_Options *options, bool udp_enabled); - -bool tox_options_get_local_discovery_enabled(const Tox_Options *options); - -void tox_options_set_local_discovery_enabled(Tox_Options *options, bool local_discovery_enabled); - -bool tox_options_get_dht_announcements_enabled(const Tox_Options *options); - -void tox_options_set_dht_announcements_enabled(Tox_Options *options, bool dht_announcements_enabled); - -Tox_Proxy_Type tox_options_get_proxy_type(const Tox_Options *options); - -void tox_options_set_proxy_type(Tox_Options *options, Tox_Proxy_Type proxy_type); - -const char *tox_options_get_proxy_host(const Tox_Options *options); - -void tox_options_set_proxy_host(Tox_Options *options, const char *proxy_host); - -uint16_t tox_options_get_proxy_port(const Tox_Options *options); - -void tox_options_set_proxy_port(Tox_Options *options, uint16_t proxy_port); - -uint16_t tox_options_get_start_port(const Tox_Options *options); - -void tox_options_set_start_port(Tox_Options *options, uint16_t start_port); - -uint16_t tox_options_get_end_port(const Tox_Options *options); - -void tox_options_set_end_port(Tox_Options *options, uint16_t end_port); - -uint16_t tox_options_get_tcp_port(const Tox_Options *options); - -void tox_options_set_tcp_port(Tox_Options *options, uint16_t tcp_port); - -bool tox_options_get_hole_punching_enabled(const Tox_Options *options); - -void tox_options_set_hole_punching_enabled(Tox_Options *options, bool hole_punching_enabled); - -Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options *options); - -void tox_options_set_savedata_type(Tox_Options *options, Tox_Savedata_Type savedata_type); - -const uint8_t *tox_options_get_savedata_data(const Tox_Options *options); - -void tox_options_set_savedata_data(Tox_Options *options, const uint8_t savedata_data[], size_t length); - -size_t tox_options_get_savedata_length(const Tox_Options *options); - -void tox_options_set_savedata_length(Tox_Options *options, size_t savedata_length); - -tox_log_cb *tox_options_get_log_callback(const Tox_Options *options); - -void tox_options_set_log_callback(Tox_Options *options, tox_log_cb *log_callback); - -void *tox_options_get_log_user_data(const Tox_Options *options); - -void tox_options_set_log_user_data(Tox_Options *options, void *log_user_data); - -bool tox_options_get_experimental_thread_safety(const Tox_Options *options); - -void tox_options_set_experimental_thread_safety(Tox_Options *options, bool experimental_thread_safety); - -bool tox_options_get_experimental_groups_persistence(const Tox_Options *options); - -void tox_options_set_experimental_groups_persistence(Tox_Options *options, bool experimental_groups_persistence); - -bool tox_options_get_experimental_disable_dns(const Tox_Options *options); - -void tox_options_set_experimental_disable_dns(Tox_Options *options, bool experimental_disable_dns); - -/** - * @brief Initialises a Tox_Options object with the default options. - * - * The result of this function is independent of the original options. All - * values will be overwritten, no values will be read (so it is permissible - * to pass an uninitialised object). - * - * If options is NULL, this function has no effect. - * - * @param options An options object to be filled with default options. - */ -void tox_options_default(Tox_Options *options); - -typedef enum Tox_Err_Options_New { - - /** - * The function returned successfully. - */ - TOX_ERR_OPTIONS_NEW_OK, - - /** - * The function failed to allocate enough memory for the options struct. - */ - TOX_ERR_OPTIONS_NEW_MALLOC, - -} Tox_Err_Options_New; - -const char *tox_err_options_new_to_string(Tox_Err_Options_New value); - -/** - * @brief Allocates a new Tox_Options object and initialises it with the default - * options. - * - * This function can be used to preserve long term ABI compatibility by - * giving the responsibility of allocation and deallocation to the Tox library. - * - * Objects returned from this function must be freed using the tox_options_free - * function. - * - * @return A new Tox_Options object with default options or NULL on failure. - */ -Tox_Options *tox_options_new(Tox_Err_Options_New *error); - -/** - * @brief Releases all resources associated with an options objects. - * - * Passing a pointer that was not returned by tox_options_new results in - * undefined behaviour. - */ -void tox_options_free(Tox_Options *options); - -/** @} */ - /** @{ * @name Creation and destruction */ @@ -974,7 +540,7 @@ typedef enum Tox_Err_Bootstrap { const char *tox_err_bootstrap_to_string(Tox_Err_Bootstrap value); /** - * @brief Sends a "get nodes" request to the given bootstrap node with IP, port, + * @brief Sends a "nodes request" to the given bootstrap node with IP, port, * and public key to setup connections. * * This function will attempt to connect to the node using UDP. You must use @@ -5795,7 +5361,6 @@ typedef Tox_User_Status TOX_USER_STATUS; typedef Tox_Message_Type TOX_MESSAGE_TYPE; typedef Tox_Proxy_Type TOX_PROXY_TYPE; typedef Tox_Savedata_Type TOX_SAVEDATA_TYPE; -typedef Tox_Log_Level TOX_LOG_LEVEL; typedef Tox_Connection TOX_CONNECTION; typedef Tox_File_Control TOX_FILE_CONTROL; typedef Tox_Conference_Type TOX_CONFERENCE_TYPE; diff --git a/toxcore/tox_api.c b/toxcore/tox_api.c index 7988018..808cd47 100644 --- a/toxcore/tox_api.c +++ b/toxcore/tox_api.c @@ -1,20 +1,11 @@ /* SPDX-License-Identifier: GPL-3.0-or-later * Copyright © 2016-2025 The TokTok team. */ -#include "tox.h" +#include "tox.h" // IWYU pragma: associated -#include - -#include "ccompat.h" +#include "tox_options.h" #include "tox_private.h" -#define SET_ERROR_PARAMETER(param, x) \ - do { \ - if (param != nullptr) { \ - *param = x; \ - } \ - } while (0) - uint32_t tox_version_major(void) { return TOX_VERSION_MAJOR; @@ -136,200 +127,6 @@ uint32_t tox_dht_node_public_key_size(void) return TOX_DHT_NODE_PUBLIC_KEY_SIZE; } -bool tox_options_get_ipv6_enabled(const Tox_Options *options) -{ - return options->ipv6_enabled; -} -void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled) -{ - options->ipv6_enabled = ipv6_enabled; -} -bool tox_options_get_udp_enabled(const Tox_Options *options) -{ - return options->udp_enabled; -} -void tox_options_set_udp_enabled(Tox_Options *options, bool udp_enabled) -{ - options->udp_enabled = udp_enabled; -} -Tox_Proxy_Type tox_options_get_proxy_type(const Tox_Options *options) -{ - return options->proxy_type; -} -void tox_options_set_proxy_type(Tox_Options *options, Tox_Proxy_Type proxy_type) -{ - options->proxy_type = proxy_type; -} -const char *tox_options_get_proxy_host(const Tox_Options *options) -{ - return options->proxy_host; -} -void tox_options_set_proxy_host(Tox_Options *options, const char *proxy_host) -{ - options->proxy_host = proxy_host; -} -uint16_t tox_options_get_proxy_port(const Tox_Options *options) -{ - return options->proxy_port; -} -void tox_options_set_proxy_port(Tox_Options *options, uint16_t proxy_port) -{ - options->proxy_port = proxy_port; -} -uint16_t tox_options_get_start_port(const Tox_Options *options) -{ - return options->start_port; -} -void tox_options_set_start_port(Tox_Options *options, uint16_t start_port) -{ - options->start_port = start_port; -} -uint16_t tox_options_get_end_port(const Tox_Options *options) -{ - return options->end_port; -} -void tox_options_set_end_port(Tox_Options *options, uint16_t end_port) -{ - options->end_port = end_port; -} -uint16_t tox_options_get_tcp_port(const Tox_Options *options) -{ - return options->tcp_port; -} -void tox_options_set_tcp_port(Tox_Options *options, uint16_t tcp_port) -{ - options->tcp_port = tcp_port; -} -bool tox_options_get_hole_punching_enabled(const Tox_Options *options) -{ - return options->hole_punching_enabled; -} -void tox_options_set_hole_punching_enabled(Tox_Options *options, bool hole_punching_enabled) -{ - options->hole_punching_enabled = hole_punching_enabled; -} -Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options *options) -{ - return options->savedata_type; -} -void tox_options_set_savedata_type(Tox_Options *options, Tox_Savedata_Type savedata_type) -{ - options->savedata_type = savedata_type; -} -size_t tox_options_get_savedata_length(const Tox_Options *options) -{ - return options->savedata_length; -} -void tox_options_set_savedata_length(Tox_Options *options, size_t savedata_length) -{ - options->savedata_length = savedata_length; -} -tox_log_cb *tox_options_get_log_callback(const Tox_Options *options) -{ - return options->log_callback; -} -void tox_options_set_log_callback(Tox_Options *options, tox_log_cb *log_callback) -{ - options->log_callback = log_callback; -} -void *tox_options_get_log_user_data(const Tox_Options *options) -{ - return options->log_user_data; -} -void tox_options_set_log_user_data(Tox_Options *options, void *log_user_data) -{ - options->log_user_data = log_user_data; -} -bool tox_options_get_local_discovery_enabled(const Tox_Options *options) -{ - return options->local_discovery_enabled; -} -void tox_options_set_local_discovery_enabled(Tox_Options *options, bool local_discovery_enabled) -{ - options->local_discovery_enabled = local_discovery_enabled; -} -bool tox_options_get_dht_announcements_enabled(const Tox_Options *options) -{ - return options->dht_announcements_enabled; -} -void tox_options_set_dht_announcements_enabled(Tox_Options *options, bool dht_announcements_enabled) -{ - options->dht_announcements_enabled = dht_announcements_enabled; -} -bool tox_options_get_experimental_thread_safety(const Tox_Options *options) -{ - return options->experimental_thread_safety; -} -void tox_options_set_experimental_thread_safety( - Tox_Options *options, bool experimental_thread_safety) -{ - options->experimental_thread_safety = experimental_thread_safety; -} -bool tox_options_get_experimental_groups_persistence(const Tox_Options *options) -{ - return options->experimental_groups_persistence; -} -void tox_options_set_experimental_groups_persistence( - Tox_Options *options, bool experimental_groups_persistence) -{ - options->experimental_groups_persistence = experimental_groups_persistence; -} -bool tox_options_get_experimental_disable_dns(const Tox_Options *options) -{ - return options->experimental_disable_dns; -} -void tox_options_set_experimental_disable_dns(Tox_Options *options, bool experimental_disable_dns) -{ - options->experimental_disable_dns = experimental_disable_dns; -} - -const uint8_t *tox_options_get_savedata_data(const Tox_Options *options) -{ - return options->savedata_data; -} - -void tox_options_set_savedata_data(Tox_Options *options, const uint8_t *savedata_data, size_t length) -{ - options->savedata_data = savedata_data; - options->savedata_length = length; -} - -void tox_options_default(Tox_Options *options) -{ - if (options != nullptr) { - const Tox_Options default_options = {false}; - *options = default_options; - tox_options_set_ipv6_enabled(options, true); - tox_options_set_udp_enabled(options, true); - tox_options_set_proxy_type(options, TOX_PROXY_TYPE_NONE); - tox_options_set_hole_punching_enabled(options, true); - tox_options_set_local_discovery_enabled(options, true); - tox_options_set_dht_announcements_enabled(options, true); - tox_options_set_experimental_thread_safety(options, false); - tox_options_set_experimental_groups_persistence(options, false); - tox_options_set_experimental_disable_dns(options, false); - } -} - -Tox_Options *tox_options_new(Tox_Err_Options_New *error) -{ - Tox_Options *options = (Tox_Options *)calloc(1, sizeof(Tox_Options)); - - if (options != nullptr) { - tox_options_default(options); - SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_OK); - return options; - } - - SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_MALLOC); - return nullptr; -} - -void tox_options_free(Tox_Options *options) -{ - free(options); -} - const char *tox_user_status_to_string(Tox_User_Status value) { switch (value) { @@ -387,27 +184,6 @@ const char *tox_savedata_type_to_string(Tox_Savedata_Type value) return ""; } -const char *tox_log_level_to_string(Tox_Log_Level value) -{ - switch (value) { - case TOX_LOG_LEVEL_TRACE: - return "TOX_LOG_LEVEL_TRACE"; - - case TOX_LOG_LEVEL_DEBUG: - return "TOX_LOG_LEVEL_DEBUG"; - - case TOX_LOG_LEVEL_INFO: - return "TOX_LOG_LEVEL_INFO"; - - case TOX_LOG_LEVEL_WARNING: - return "TOX_LOG_LEVEL_WARNING"; - - case TOX_LOG_LEVEL_ERROR: - return "TOX_LOG_LEVEL_ERROR"; - } - - return ""; -} const char *tox_err_options_new_to_string(Tox_Err_Options_New value) { switch (value) { diff --git a/toxcore/tox_dispatch.c b/toxcore/tox_dispatch.c index dde768e..11805ac 100644 --- a/toxcore/tox_dispatch.c +++ b/toxcore/tox_dispatch.c @@ -53,7 +53,7 @@ struct Tox_Dispatch { tox_events_group_self_join_cb *group_self_join_callback; tox_events_group_join_fail_cb *group_join_fail_callback; tox_events_group_moderation_cb *group_moderation_callback; - tox_events_dht_get_nodes_response_cb *dht_get_nodes_response_callback; + tox_events_dht_nodes_response_cb *dht_nodes_response_callback; }; Tox_Dispatch *tox_dispatch_new(Tox_Err_Dispatch_New *error) @@ -279,10 +279,10 @@ void tox_events_callback_group_moderation( { dispatch->group_moderation_callback = callback; } -void tox_events_callback_dht_get_nodes_response( - Tox_Dispatch *dispatch, tox_events_dht_get_nodes_response_cb *callback) +void tox_events_callback_dht_nodes_response( + Tox_Dispatch *dispatch, tox_events_dht_nodes_response_cb *callback) { - dispatch->dht_get_nodes_response_callback = callback; + dispatch->dht_nodes_response_callback = callback; } non_null(1, 2) nullable(3) @@ -602,8 +602,8 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev } case TOX_EVENT_DHT_GET_NODES_RESPONSE: { - if (dispatch->dht_get_nodes_response_callback != nullptr) { - dispatch->dht_get_nodes_response_callback(event->data.dht_get_nodes_response, user_data); + if (dispatch->dht_nodes_response_callback != nullptr) { + dispatch->dht_nodes_response_callback(event->data.dht_nodes_response, user_data); } break; diff --git a/toxcore/tox_dispatch.h b/toxcore/tox_dispatch.h index 01770ee..6ad3fc8 100644 --- a/toxcore/tox_dispatch.h +++ b/toxcore/tox_dispatch.h @@ -136,8 +136,8 @@ typedef void tox_events_group_join_fail_cb( const Tox_Event_Group_Join_Fail *event, void *user_data); typedef void tox_events_group_moderation_cb( const Tox_Event_Group_Moderation *event, void *user_data); -typedef void tox_events_dht_get_nodes_response_cb( - const Tox_Event_Dht_Get_Nodes_Response *event, void *user_data); +typedef void tox_events_dht_nodes_response_cb( + const Tox_Event_Dht_Nodes_Response *event, void *user_data); void tox_events_callback_conference_connected( Tox_Dispatch *dispatch, tox_events_conference_connected_cb *callback); @@ -217,8 +217,8 @@ void tox_events_callback_group_join_fail( Tox_Dispatch *dispatch, tox_events_group_join_fail_cb *callback); void tox_events_callback_group_moderation( Tox_Dispatch *dispatch, tox_events_group_moderation_cb *callback); -void tox_events_callback_dht_get_nodes_response( - Tox_Dispatch *dispatch, tox_events_dht_get_nodes_response_cb *callback); +void tox_events_callback_dht_nodes_response( + Tox_Dispatch *dispatch, tox_events_dht_nodes_response_cb *callback); #ifdef __cplusplus } /* extern "C" */ diff --git a/toxcore/tox_event.c b/toxcore/tox_event.c index 10cabe1..251b6a8 100644 --- a/toxcore/tox_event.c +++ b/toxcore/tox_event.c @@ -351,7 +351,7 @@ bool tox_event_construct(Tox_Event *event, Tox_Event_Type type, const Memory *me } case TOX_EVENT_DHT_GET_NODES_RESPONSE: { - event->data.dht_get_nodes_response = tox_event_dht_get_nodes_response_new(mem); + event->data.dht_nodes_response = tox_event_dht_nodes_response_new(mem); break; } @@ -566,7 +566,7 @@ void tox_event_destruct(Tox_Event *event, const Memory *mem) } case TOX_EVENT_DHT_GET_NODES_RESPONSE: { - tox_event_dht_get_nodes_response_free(event->data.dht_get_nodes_response, mem); + tox_event_dht_nodes_response_free(event->data.dht_nodes_response, mem); break; } @@ -706,7 +706,7 @@ static bool tox_event_data_pack(Tox_Event_Type type, const Tox_Event_Data *data, return tox_event_group_moderation_pack(data->group_moderation, bp); case TOX_EVENT_DHT_GET_NODES_RESPONSE: - return tox_event_dht_get_nodes_response_pack(data->dht_get_nodes_response, bp); + return tox_event_dht_nodes_response_pack(data->dht_nodes_response, bp); case TOX_EVENT_INVALID: return false; @@ -1070,7 +1070,7 @@ static bool tox_event_data_unpack(Tox_Event_Type type, Tox_Event_Data *data, Bin return tox_event_group_moderation_unpack(&data->group_moderation, bu, mem); case TOX_EVENT_DHT_GET_NODES_RESPONSE: - return tox_event_dht_get_nodes_response_unpack(&data->dht_get_nodes_response, bu, mem); + return tox_event_dht_nodes_response_unpack(&data->dht_nodes_response, bu, mem); case TOX_EVENT_INVALID: return false; diff --git a/toxcore/tox_event.h b/toxcore/tox_event.h index 293939c..eebc233 100644 --- a/toxcore/tox_event.h +++ b/toxcore/tox_event.h @@ -61,7 +61,7 @@ typedef union Tox_Event_Data { Tox_Event_Group_Self_Join *group_self_join; Tox_Event_Group_Join_Fail *group_join_fail; Tox_Event_Group_Moderation *group_moderation; - Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response; + Tox_Event_Dht_Nodes_Response *dht_nodes_response; } Tox_Event_Data; struct Tox_Event { @@ -113,7 +113,7 @@ non_null() Tox_Event_Group_Peer_Exit *tox_event_group_peer_exit_new(const Memory non_null() Tox_Event_Group_Self_Join *tox_event_group_self_join_new(const Memory *mem); non_null() Tox_Event_Group_Join_Fail *tox_event_group_join_fail_new(const Memory *mem); non_null() Tox_Event_Group_Moderation *tox_event_group_moderation_new(const Memory *mem); -non_null() Tox_Event_Dht_Get_Nodes_Response *tox_event_dht_get_nodes_response_new(const Memory *mem); +non_null() Tox_Event_Dht_Nodes_Response *tox_event_dht_nodes_response_new(const Memory *mem); /** * Destructor. @@ -159,7 +159,7 @@ non_null(2) nullable(1) void tox_event_group_peer_exit_free(Tox_Event_Group_Peer non_null(2) nullable(1) void tox_event_group_self_join_free(Tox_Event_Group_Self_Join *group_self_join, const Memory *mem); non_null(2) nullable(1) void tox_event_group_join_fail_free(Tox_Event_Group_Join_Fail *group_join_fail, const Memory *mem); non_null(2) nullable(1) void tox_event_group_moderation_free(Tox_Event_Group_Moderation *group_moderation, const Memory *mem); -non_null(2) nullable(1) void tox_event_dht_get_nodes_response_free(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, const Memory *mem); +non_null(2) nullable(1) void tox_event_dht_nodes_response_free(Tox_Event_Dht_Nodes_Response *dht_nodes_response, const Memory *mem); /** * Pack into msgpack. @@ -205,7 +205,7 @@ non_null() bool tox_event_group_peer_exit_pack(const Tox_Event_Group_Peer_Exit * non_null() bool tox_event_group_self_join_pack(const Tox_Event_Group_Self_Join *event, Bin_Pack *bp); non_null() bool tox_event_group_join_fail_pack(const Tox_Event_Group_Join_Fail *event, Bin_Pack *bp); non_null() bool tox_event_group_moderation_pack(const Tox_Event_Group_Moderation *event, Bin_Pack *bp); -non_null() bool tox_event_dht_get_nodes_response_pack(const Tox_Event_Dht_Get_Nodes_Response *event, Bin_Pack *bp); +non_null() bool tox_event_dht_nodes_response_pack(const Tox_Event_Dht_Nodes_Response *event, Bin_Pack *bp); /** * Unpack from msgpack. @@ -251,7 +251,7 @@ non_null() bool tox_event_group_peer_exit_unpack(Tox_Event_Group_Peer_Exit **eve non_null() bool tox_event_group_self_join_unpack(Tox_Event_Group_Self_Join **event, Bin_Unpack *bu, const Memory *mem); non_null() bool tox_event_group_join_fail_unpack(Tox_Event_Group_Join_Fail **event, Bin_Unpack *bu, const Memory *mem); non_null() bool tox_event_group_moderation_unpack(Tox_Event_Group_Moderation **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_dht_get_nodes_response_unpack(Tox_Event_Dht_Get_Nodes_Response **event, Bin_Unpack *bu, const Memory *mem); +non_null() bool tox_event_dht_nodes_response_unpack(Tox_Event_Dht_Nodes_Response **event, Bin_Unpack *bu, const Memory *mem); #ifdef __cplusplus } /* extern "C" */ diff --git a/toxcore/tox_events.c b/toxcore/tox_events.c index 0f2b1f2..81bb76f 100644 --- a/toxcore/tox_events.c +++ b/toxcore/tox_events.c @@ -17,7 +17,7 @@ #include "tox.h" #include "tox_event.h" #include "tox_private.h" -#include "tox_struct.h" +#include "tox_struct.h" // IWYU pragma: keep /***************************************************** * @@ -66,7 +66,7 @@ void tox_events_init(Tox *tox) tox_callback_group_self_join(tox, tox_events_handle_group_self_join); tox_callback_group_join_fail(tox, tox_events_handle_group_join_fail); tox_callback_group_moderation(tox, tox_events_handle_group_moderation); - tox_callback_dht_get_nodes_response(tox, tox_events_handle_dht_get_nodes_response); + tox_callback_dht_nodes_response(tox, tox_events_handle_dht_nodes_response); } uint32_t tox_events_get_size(const Tox_Events *events) @@ -173,7 +173,7 @@ Tox_Events *tox_events_load(const Tox_System *sys, const uint8_t *bytes, uint32_ }; events->mem = sys->mem; - if (!bin_unpack_obj(tox_events_unpack_handler, events, bytes, bytes_size)) { + if (!bin_unpack_obj(sys->mem, tox_events_unpack_handler, events, bytes, bytes_size)) { tox_events_free(events); return nullptr; } diff --git a/toxcore/tox_events.h b/toxcore/tox_events.h index 5452790..4a96feb 100644 --- a/toxcore/tox_events.h +++ b/toxcore/tox_events.h @@ -352,15 +352,15 @@ uint32_t tox_event_group_moderation_get_target_peer_id( Tox_Group_Mod_Event tox_event_group_moderation_get_mod_type( const Tox_Event_Group_Moderation *group_moderation); -typedef struct Tox_Event_Dht_Get_Nodes_Response Tox_Event_Dht_Get_Nodes_Response; -const uint8_t *tox_event_dht_get_nodes_response_get_public_key( - const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response); -const uint8_t *tox_event_dht_get_nodes_response_get_ip( - const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response); -uint32_t tox_event_dht_get_nodes_response_get_ip_length( - const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response); -uint16_t tox_event_dht_get_nodes_response_get_port( - const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response); +typedef struct Tox_Event_Dht_Nodes_Response Tox_Event_Dht_Nodes_Response; +const uint8_t *tox_event_dht_nodes_response_get_public_key( + const Tox_Event_Dht_Nodes_Response *dht_nodes_response); +const uint8_t *tox_event_dht_nodes_response_get_ip( + const Tox_Event_Dht_Nodes_Response *dht_nodes_response); +uint32_t tox_event_dht_nodes_response_get_ip_length( + const Tox_Event_Dht_Nodes_Response *dht_nodes_response); +uint16_t tox_event_dht_nodes_response_get_port( + const Tox_Event_Dht_Nodes_Response *dht_nodes_response); typedef enum Tox_Event_Type { TOX_EVENT_SELF_CONNECTION_STATUS = 0, @@ -507,7 +507,7 @@ const Tox_Event_Group_Join_Fail *tox_event_get_group_join_fail( const Tox_Event *event); const Tox_Event_Group_Moderation *tox_event_get_group_moderation( const Tox_Event *event); -const Tox_Event_Dht_Get_Nodes_Response *tox_event_get_dht_get_nodes_response( +const Tox_Event_Dht_Nodes_Response *tox_event_get_dht_nodes_response( const Tox_Event *event); /** diff --git a/toxcore/tox_log_level.c b/toxcore/tox_log_level.c new file mode 100644 index 0000000..04f83b0 --- /dev/null +++ b/toxcore/tox_log_level.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2025 The TokTok team. + * Copyright © 2013 Tox project. + */ +#include "tox_log_level.h" + +const char *tox_log_level_to_string(Tox_Log_Level value) +{ + switch (value) { + case TOX_LOG_LEVEL_TRACE: + return "TOX_LOG_LEVEL_TRACE"; + + case TOX_LOG_LEVEL_DEBUG: + return "TOX_LOG_LEVEL_DEBUG"; + + case TOX_LOG_LEVEL_INFO: + return "TOX_LOG_LEVEL_INFO"; + + case TOX_LOG_LEVEL_WARNING: + return "TOX_LOG_LEVEL_WARNING"; + + case TOX_LOG_LEVEL_ERROR: + return "TOX_LOG_LEVEL_ERROR"; + } + + return ""; +} diff --git a/toxcore/tox_log_level.h b/toxcore/tox_log_level.h new file mode 100644 index 0000000..0009ecd --- /dev/null +++ b/toxcore/tox_log_level.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2025 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_TOX_LOG_LEVEL_H +#define C_TOXCORE_TOXCORE_TOX_LOG_LEVEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Severity level of log messages. + */ +typedef enum Tox_Log_Level { + /** + * Very detailed traces including all network activity. + */ + TOX_LOG_LEVEL_TRACE, + + /** + * Debug messages such as which port we bind to. + */ + TOX_LOG_LEVEL_DEBUG, + + /** + * Informational log messages such as video call status changes. + */ + TOX_LOG_LEVEL_INFO, + + /** + * Warnings about internal inconsistency or logic errors. + */ + TOX_LOG_LEVEL_WARNING, + + /** + * Severe unexpected errors caused by external or internal inconsistency. + */ + TOX_LOG_LEVEL_ERROR, +} Tox_Log_Level; + +const char *tox_log_level_to_string(Tox_Log_Level value); + +//!TOKSTYLE- +#ifndef DOXYGEN_IGNORE + +#ifndef TOX_HIDE_DEPRECATED +typedef Tox_Log_Level TOX_LOG_LEVEL; +#endif /* TOX_HIDE_DEPRECATED */ + +#endif +//!TOKSTYLE+ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_LOG_LEVEL_H */ diff --git a/toxcore/tox_options.c b/toxcore/tox_options.c new file mode 100644 index 0000000..d67a8ae --- /dev/null +++ b/toxcore/tox_options.c @@ -0,0 +1,285 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2025 The TokTok team. + * Copyright © 2013 Tox project. + */ + +#include "tox_options.h" + +#include // free, malloc, calloc +#include // memcpy, strlen + +#include "ccompat.h" // nullptr + +#define SET_ERROR_PARAMETER(param, x) \ + do { \ + if (param != nullptr) { \ + *param = x; \ + } \ + } while (0) + + +bool tox_options_get_ipv6_enabled(const Tox_Options *options) +{ + return options->ipv6_enabled; +} +void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled) +{ + options->ipv6_enabled = ipv6_enabled; +} +bool tox_options_get_udp_enabled(const Tox_Options *options) +{ + return options->udp_enabled; +} +void tox_options_set_udp_enabled(Tox_Options *options, bool udp_enabled) +{ + options->udp_enabled = udp_enabled; +} +Tox_Proxy_Type tox_options_get_proxy_type(const Tox_Options *options) +{ + return options->proxy_type; +} +void tox_options_set_proxy_type(Tox_Options *options, Tox_Proxy_Type proxy_type) +{ + options->proxy_type = proxy_type; +} +const char *tox_options_get_proxy_host(const Tox_Options *options) +{ + return options->proxy_host; +} +bool tox_options_set_proxy_host(Tox_Options *options, const char *proxy_host) +{ + if (!options->experimental_owned_data) { + options->proxy_host = proxy_host; + return true; + } + + if (options->owned_proxy_host != nullptr) { + free(options->owned_proxy_host); + options->owned_proxy_host = nullptr; + } + if (proxy_host == nullptr) { + options->proxy_host = nullptr; + return true; + } + + const size_t proxy_host_length = strlen(proxy_host) + 1; + char *owned_ptr = (char *)malloc(proxy_host_length); + if (owned_ptr == nullptr) { + options->proxy_host = proxy_host; + options->owned_proxy_host = nullptr; + return false; + } + + memcpy(owned_ptr, proxy_host, proxy_host_length); + options->proxy_host = owned_ptr; + options->owned_proxy_host = owned_ptr; + return true; +} +uint16_t tox_options_get_proxy_port(const Tox_Options *options) +{ + return options->proxy_port; +} +void tox_options_set_proxy_port(Tox_Options *options, uint16_t proxy_port) +{ + options->proxy_port = proxy_port; +} +uint16_t tox_options_get_start_port(const Tox_Options *options) +{ + return options->start_port; +} +void tox_options_set_start_port(Tox_Options *options, uint16_t start_port) +{ + options->start_port = start_port; +} +uint16_t tox_options_get_end_port(const Tox_Options *options) +{ + return options->end_port; +} +void tox_options_set_end_port(Tox_Options *options, uint16_t end_port) +{ + options->end_port = end_port; +} +uint16_t tox_options_get_tcp_port(const Tox_Options *options) +{ + return options->tcp_port; +} +void tox_options_set_tcp_port(Tox_Options *options, uint16_t tcp_port) +{ + options->tcp_port = tcp_port; +} +bool tox_options_get_hole_punching_enabled(const Tox_Options *options) +{ + return options->hole_punching_enabled; +} +void tox_options_set_hole_punching_enabled(Tox_Options *options, bool hole_punching_enabled) +{ + options->hole_punching_enabled = hole_punching_enabled; +} +Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options *options) +{ + return options->savedata_type; +} +void tox_options_set_savedata_type(Tox_Options *options, Tox_Savedata_Type savedata_type) +{ + options->savedata_type = savedata_type; +} +size_t tox_options_get_savedata_length(const Tox_Options *options) +{ + return options->savedata_length; +} +void tox_options_set_savedata_length(Tox_Options *options, size_t savedata_length) +{ + options->savedata_length = savedata_length; +} +tox_log_cb *tox_options_get_log_callback(const Tox_Options *options) +{ + return options->log_callback; +} +void tox_options_set_log_callback(Tox_Options *options, tox_log_cb *log_callback) +{ + options->log_callback = log_callback; +} +void *tox_options_get_log_user_data(const Tox_Options *options) +{ + return options->log_user_data; +} +void tox_options_set_log_user_data(Tox_Options *options, void *log_user_data) +{ + options->log_user_data = log_user_data; +} +bool tox_options_get_local_discovery_enabled(const Tox_Options *options) +{ + return options->local_discovery_enabled; +} +void tox_options_set_local_discovery_enabled(Tox_Options *options, bool local_discovery_enabled) +{ + options->local_discovery_enabled = local_discovery_enabled; +} +bool tox_options_get_dht_announcements_enabled(const Tox_Options *options) +{ + return options->dht_announcements_enabled; +} +void tox_options_set_dht_announcements_enabled(Tox_Options *options, bool dht_announcements_enabled) +{ + options->dht_announcements_enabled = dht_announcements_enabled; +} +bool tox_options_get_experimental_thread_safety(const Tox_Options *options) +{ + return options->experimental_thread_safety; +} +void tox_options_set_experimental_thread_safety( + Tox_Options *options, bool experimental_thread_safety) +{ + options->experimental_thread_safety = experimental_thread_safety; +} +bool tox_options_get_experimental_groups_persistence(const Tox_Options *options) +{ + return options->experimental_groups_persistence; +} +void tox_options_set_experimental_groups_persistence( + Tox_Options *options, bool experimental_groups_persistence) +{ + options->experimental_groups_persistence = experimental_groups_persistence; +} +bool tox_options_get_experimental_disable_dns(const Tox_Options *options) +{ + return options->experimental_disable_dns; +} +void tox_options_set_experimental_disable_dns(Tox_Options *options, bool experimental_disable_dns) +{ + options->experimental_disable_dns = experimental_disable_dns; +} +bool tox_options_get_experimental_owned_data(const Tox_Options *options) +{ + return options->experimental_owned_data; +} +void tox_options_set_experimental_owned_data( + Tox_Options *options, bool experimental_owned_data) +{ + options->experimental_owned_data = experimental_owned_data; +} + +const uint8_t *tox_options_get_savedata_data(const Tox_Options *options) +{ + return options->savedata_data; +} + +bool tox_options_set_savedata_data(Tox_Options *options, const uint8_t *savedata_data, size_t length) +{ + if (!options->experimental_owned_data) { + options->savedata_data = savedata_data; + options->savedata_length = length; + return true; + } + + if (options->owned_savedata_data != nullptr) { + free(options->owned_savedata_data); + options->owned_savedata_data = nullptr; + } + if (savedata_data == nullptr) { + options->savedata_data = nullptr; + options->savedata_length = 0; + return true; + } + + uint8_t *owned_ptr = (uint8_t *)malloc(length); + if (owned_ptr == nullptr) { + options->savedata_data = savedata_data; + options->savedata_length = length; + options->owned_savedata_data = nullptr; + return false; + } + + memcpy(owned_ptr, savedata_data, length); + options->savedata_data = owned_ptr; + options->savedata_length = length; + options->owned_savedata_data = owned_ptr; + return true; +} + +void tox_options_default(Tox_Options *options) +{ + if (options != nullptr) { + // Free any owned data. + tox_options_set_proxy_host(options, nullptr); + tox_options_set_savedata_data(options, nullptr, 0); + + // Set the rest to default values. + const Tox_Options default_options = {false}; + *options = default_options; + tox_options_set_ipv6_enabled(options, true); + tox_options_set_udp_enabled(options, true); + tox_options_set_proxy_type(options, TOX_PROXY_TYPE_NONE); + tox_options_set_hole_punching_enabled(options, true); + tox_options_set_local_discovery_enabled(options, true); + tox_options_set_dht_announcements_enabled(options, true); + tox_options_set_experimental_thread_safety(options, false); + tox_options_set_experimental_groups_persistence(options, false); + tox_options_set_experimental_disable_dns(options, false); + tox_options_set_experimental_owned_data(options, false); + } +} + +Tox_Options *tox_options_new(Tox_Err_Options_New *error) +{ + Tox_Options *options = (Tox_Options *)calloc(1, sizeof(Tox_Options)); + + if (options != nullptr) { + tox_options_default(options); + SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_OK); + return options; + } + + SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_MALLOC); + return nullptr; +} + +void tox_options_free(Tox_Options *options) +{ + if (options != nullptr) { + // Free any owned data. + tox_options_set_proxy_host(options, nullptr); + tox_options_set_savedata_data(options, nullptr, 0); + free(options); + } +} diff --git a/toxcore/tox_options.h b/toxcore/tox_options.h new file mode 100644 index 0000000..7d8b7aa --- /dev/null +++ b/toxcore/tox_options.h @@ -0,0 +1,455 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2025 The TokTok team. + * Copyright © 2013 Tox project. + */ + +#ifndef C_TOXCORE_TOXCORE_TOX_OPTIONS_H +#define C_TOXCORE_TOXCORE_TOX_OPTIONS_H + +#include +#include +#include + +#include "tox_log_level.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct Tox; + +/** @{ + * @name Startup options + */ + +/** + * @brief Type of proxy used to connect to TCP relays. + */ +typedef enum Tox_Proxy_Type { + /** + * Don't use a proxy. + */ + TOX_PROXY_TYPE_NONE, + + /** + * HTTP proxy using CONNECT. + */ + TOX_PROXY_TYPE_HTTP, + + /** + * SOCKS proxy for simple socket pipes. + */ + TOX_PROXY_TYPE_SOCKS5, +} Tox_Proxy_Type; + +const char *tox_proxy_type_to_string(Tox_Proxy_Type value); + +/** + * @brief Type of savedata to create the Tox instance from. + */ +typedef enum Tox_Savedata_Type { + /** + * No savedata. + */ + TOX_SAVEDATA_TYPE_NONE, + + /** + * Savedata is one that was obtained from tox_get_savedata. + */ + TOX_SAVEDATA_TYPE_TOX_SAVE, + + /** + * Savedata is a secret key of length TOX_SECRET_KEY_SIZE. + */ + TOX_SAVEDATA_TYPE_SECRET_KEY, +} Tox_Savedata_Type; + +const char *tox_savedata_type_to_string(Tox_Savedata_Type value); + +/** + * @brief This event is triggered when Tox logs an internal message. + * + * This is mostly useful for debugging. This callback can be called from any + * function, not just tox_iterate. This means the user data lifetime must at + * least extend between registering and unregistering it or tox_kill. + * + * Other toxcore modules such as toxav may concurrently call this callback at + * any time. Thus, user code must make sure it is equipped to handle concurrent + * execution, e.g. by employing appropriate mutex locking. + * + * When using the experimental_thread_safety option, no Tox API functions can + * be called from within the log callback. + * + * @param level The severity of the log message. + * @param file The source file from which the message originated. + * @param line The source line from which the message originated. + * @param func The function from which the message originated. + * @param message The log message. + * @param user_data The user data pointer passed to tox_new in options. + */ +typedef void tox_log_cb(struct Tox *tox, Tox_Log_Level level, const char *file, + uint32_t line, const char *func, const char *message, + void *user_data); + +/** + * @brief This struct contains all the startup options for Tox. + * + * You must tox_options_new to allocate an object of this type. + * + * WARNING: Although this struct happens to be visible in the API, it is + * effectively private. Do not allocate this yourself or access members + * directly, as it *will* break binary compatibility frequently. + * + * @deprecated The memory layout of this struct (size, alignment, and field + * order) is not part of the ABI. To remain compatible, prefer to use + * tox_options_new to allocate the object and accessor functions to set the + * members. The struct will become opaque (i.e. the definition will become + * private) in v0.3.0. + */ +typedef struct Tox_Options Tox_Options; + +#ifndef TOX_HIDE_DEPRECATED +struct Tox_Options { + /** + * The type of socket to create. + * + * If this is set to false, an IPv4 socket is created, which subsequently + * only allows IPv4 communication. + * If it is set to true, an IPv6 socket is created, allowing both IPv4 and + * IPv6 communication. + */ + bool ipv6_enabled; + + /** + * Enable the use of UDP communication when available. + * + * Setting this to false will force Tox to use TCP only. Communications will + * need to be relayed through a TCP relay node, potentially slowing them + * down. + * + * If a proxy is enabled, UDP will be disabled if either the Tox library or + * the proxy don't support proxying UDP messages. + */ + bool udp_enabled; + + /** + * Enable local network peer discovery. + * + * Disabling this will cause Tox to not look for peers on the local network. + */ + bool local_discovery_enabled; + + /** + * Enable storing DHT announcements and forwarding corresponding requests. + * + * Disabling this will cause Tox to ignore the relevant packets. + */ + bool dht_announcements_enabled; + + /** + * Pass communications through a proxy. + */ + Tox_Proxy_Type proxy_type; + + /** + * The IP address or DNS name of the proxy to be used. + * + * If used, this must be non-NULL and be a valid DNS name. The name must not + * exceed TOX_MAX_HOSTNAME_LENGTH characters, and be in a NUL-terminated C + * string format (TOX_MAX_HOSTNAME_LENGTH includes the NUL byte). + * + * This member is ignored (it can be NULL) if proxy_type is + * TOX_PROXY_TYPE_NONE. + * + * The data pointed at by this member is owned by the user, so must + * outlive the options object (unless experimental_owned_data is set). + */ + const char *proxy_host; + + /** + * The port to use to connect to the proxy server. + * + * Ports must be in the range (1, 65535). The value is ignored if + * proxy_type is TOX_PROXY_TYPE_NONE. + */ + uint16_t proxy_port; + + /** + * The start port of the inclusive port range to attempt to use. + * + * If both start_port and end_port are 0, the default port range will be + * used: `[33445, 33545]`. + * + * If either start_port or end_port is 0 while the other is non-zero, the + * non-zero port will be the only port in the range. + * + * Having start_port > end_port will yield the same behavior as if + * start_port and end_port were swapped. + */ + uint16_t start_port; + + /** + * The end port of the inclusive port range to attempt to use. + */ + uint16_t end_port; + + /** + * The port to use for the TCP server (relay). If 0, the TCP server is + * disabled. + * + * Enabling it is not required for Tox to function properly. + * + * When enabled, your Tox instance can act as a TCP relay for other Tox + * instance. This leads to increased traffic, thus when writing a client + * it is recommended to enable TCP server only if the user has an option + * to disable it. + */ + uint16_t tcp_port; + + /** + * Enables or disables UDP hole-punching. (Default: enabled). + */ + bool hole_punching_enabled; + + /** + * The type of savedata to load from. + */ + Tox_Savedata_Type savedata_type; + + /** + * The savedata (either a Tox save or a secret key) to load from. + * + * The data pointed at by this member is owned by the user, so must + * outlive the options object (unless experimental_owned_data is set). + */ + const uint8_t *savedata_data; + + /** + * The length of the savedata. + */ + size_t savedata_length; + + /** + * Logging callback for the new Tox instance. + */ + tox_log_cb *log_callback; + + /** + * User data pointer passed to the logging callback. + */ + void *log_user_data; + + /** + * These options are experimental, so avoid writing code that depends on + * them. Options marked "experimental" may change their behaviour or go away + * entirely in the future, or may be renamed to something non-experimental + * if they become part of the supported API. + */ + /** + * Make public API functions thread-safe using a per-instance lock. + * + * Default: false. + */ + bool experimental_thread_safety; + + /** + * Enable saving DHT-based group chats to Tox save data (via + * `tox_get_savedata`). This format will change in the future, so don't rely + * on it. + * + * As an alternative, clients can save the group chat ID in client-owned + * savedata. Then, when the client starts, it can use `tox_group_join` + * with the saved chat ID to recreate the group chat. + * + * Default: false. + */ + bool experimental_groups_persistence; + + /** + * @brief Disable DNS hostname resolution. + * + * Hostnames or IP addresses are passed to the bootstrap/add_tcp_relay + * function and proxy host options. If disabled (this flag is true), only + * IP addresses are allowed. + * + * If this is set to true, the library will not attempt to resolve + * hostnames. This is useful for clients that want to resolve hostnames + * themselves and pass the resolved IP addresses to the library (e.g. in + * case it wants to use Tor). + * Passing hostnames will result in a TOX_ERR_BOOTSTRAP_BAD_HOST error if + * this is set to true. + * + * Default: false. May become true in the future (0.3.0). + */ + bool experimental_disable_dns; + + /** + * @brief Whether the savedata data is owned by the Tox_Options object. + * + * If true, the setters for savedata and proxy_host try to copy the string. + * If that fails, the value is not copied and the member is set to the + * user-provided pointer. In that case, the user must not free the string + * until the Tox_Options object is freed. Client code can check whether + * allocation succeeded by checking the returned bool. If + * experimental_owned_data is false, it will always return true. If set to + * true, the return value will be false on allocation failure. + * + * If set to true, this must be set before any other member that allocates + * memory is set. + */ + bool experimental_owned_data; + + /** + * @brief Owned pointer to the savedata data. + * @private + */ + uint8_t *owned_savedata_data; + + /** + * @brief Owned pointer to the proxy host. + * @private + */ + char *owned_proxy_host; +}; +#endif /* TOX_HIDE_DEPRECATED */ + +bool tox_options_get_ipv6_enabled(const Tox_Options *options); + +void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled); + +bool tox_options_get_udp_enabled(const Tox_Options *options); + +void tox_options_set_udp_enabled(Tox_Options *options, bool udp_enabled); + +bool tox_options_get_local_discovery_enabled(const Tox_Options *options); + +void tox_options_set_local_discovery_enabled(Tox_Options *options, bool local_discovery_enabled); + +bool tox_options_get_dht_announcements_enabled(const Tox_Options *options); + +void tox_options_set_dht_announcements_enabled( + Tox_Options *options, bool dht_announcements_enabled); + +Tox_Proxy_Type tox_options_get_proxy_type(const Tox_Options *options); + +void tox_options_set_proxy_type(Tox_Options *options, Tox_Proxy_Type proxy_type); + +const char *tox_options_get_proxy_host(const Tox_Options *options); + +bool tox_options_set_proxy_host(Tox_Options *options, const char *proxy_host); + +uint16_t tox_options_get_proxy_port(const Tox_Options *options); + +void tox_options_set_proxy_port(Tox_Options *options, uint16_t proxy_port); + +uint16_t tox_options_get_start_port(const Tox_Options *options); + +void tox_options_set_start_port(Tox_Options *options, uint16_t start_port); + +uint16_t tox_options_get_end_port(const Tox_Options *options); + +void tox_options_set_end_port(Tox_Options *options, uint16_t end_port); + +uint16_t tox_options_get_tcp_port(const Tox_Options *options); + +void tox_options_set_tcp_port(Tox_Options *options, uint16_t tcp_port); + +bool tox_options_get_hole_punching_enabled(const Tox_Options *options); + +void tox_options_set_hole_punching_enabled(Tox_Options *options, bool hole_punching_enabled); + +Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options *options); + +void tox_options_set_savedata_type(Tox_Options *options, Tox_Savedata_Type savedata_type); + +const uint8_t *tox_options_get_savedata_data(const Tox_Options *options); + +bool tox_options_set_savedata_data( + Tox_Options *options, const uint8_t savedata_data[], size_t length); + +size_t tox_options_get_savedata_length(const Tox_Options *options); + +void tox_options_set_savedata_length(Tox_Options *options, size_t savedata_length); + +tox_log_cb *tox_options_get_log_callback(const Tox_Options *options); + +void tox_options_set_log_callback(Tox_Options *options, tox_log_cb *log_callback); + +void *tox_options_get_log_user_data(const Tox_Options *options); + +void tox_options_set_log_user_data(Tox_Options *options, void *log_user_data); + +bool tox_options_get_experimental_owned_data(const Tox_Options *options); + +void tox_options_set_experimental_owned_data(Tox_Options *options, bool experimental_owned_data); + +bool tox_options_get_experimental_thread_safety(const Tox_Options *options); + +void tox_options_set_experimental_thread_safety( + Tox_Options *options, bool experimental_thread_safety); + +bool tox_options_get_experimental_groups_persistence(const Tox_Options *options); + +void tox_options_set_experimental_groups_persistence( + Tox_Options *options, bool experimental_groups_persistence); + +bool tox_options_get_experimental_disable_dns(const Tox_Options *options); + +void tox_options_set_experimental_disable_dns(Tox_Options *options, bool experimental_disable_dns); + +/** + * @brief Initialises a Tox_Options object with the default options. + * + * The result of this function is independent of the original options. All + * values will be overwritten, no values will be read (so it is permissible + * to pass an uninitialised object). + * + * If options is NULL, this function has no effect. + * + * @param options An options object to be filled with default options. + */ +void tox_options_default(Tox_Options *options); + +typedef enum Tox_Err_Options_New { + /** + * The function returned successfully. + */ + TOX_ERR_OPTIONS_NEW_OK, + + /** + * The function failed to allocate enough memory for the options struct. + */ + TOX_ERR_OPTIONS_NEW_MALLOC, +} Tox_Err_Options_New; + +const char *tox_err_options_new_to_string(Tox_Err_Options_New value); + +/** + * @brief Allocates a new Tox_Options object and initialises it with the default + * options. + * + * This function can be used to preserve long term ABI compatibility by + * giving the responsibility of allocation and deallocation to the Tox library. + * + * Objects returned from this function must be freed using the tox_options_free + * function. + * + * @return A new Tox_Options object with default options or NULL on failure. + */ +Tox_Options *tox_options_new(Tox_Err_Options_New *error); + +/** + * @brief Releases all resources associated with an options objects. + * + * Passing a pointer that was not returned by tox_options_new results in + * undefined behaviour. + */ +void tox_options_free(Tox_Options *options); + +/** @} */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_OPTIONS_H */ diff --git a/toxcore/tox_private.c b/toxcore/tox_private.c index d7e13ac..e215c37 100644 --- a/toxcore/tox_private.c +++ b/toxcore/tox_private.c @@ -11,8 +11,8 @@ #include #include "DHT.h" +#include "Messenger.h" #include "TCP_server.h" -#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "group_chats.h" @@ -23,7 +23,7 @@ #include "net_profile.h" #include "network.h" #include "tox.h" -#include "tox_struct.h" +#include "tox_struct.h" // IWYU pragma: keep #define SET_ERROR_PARAMETER(param, x) \ do { \ @@ -94,33 +94,33 @@ void *tox_get_av_object(const Tox *tox) return object; } -void tox_callback_dht_get_nodes_response(Tox *tox, tox_dht_get_nodes_response_cb *callback) +void tox_callback_dht_nodes_response(Tox *tox, tox_dht_nodes_response_cb *callback) { assert(tox != nullptr); - tox->dht_get_nodes_response_callback = callback; + tox->dht_nodes_response_callback = callback; } -bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port, - const uint8_t *target_public_key, Tox_Err_Dht_Get_Nodes *error) +bool tox_dht_send_nodes_request(const Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port, + const uint8_t *target_public_key, Tox_Err_Dht_Send_Nodes_Request *error) { assert(tox != nullptr); tox_lock(tox); if (tox->m->options.udp_disabled) { - SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_UDP_DISABLED); + SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_UDP_DISABLED); tox_unlock(tox); return false; } if (public_key == nullptr || ip == nullptr || target_public_key == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_NULL); + SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_NULL); tox_unlock(tox); return false; } if (port == 0) { - SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_BAD_PORT); + SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_BAD_PORT); tox_unlock(tox); return false; } @@ -130,7 +130,7 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip const int32_t count = net_getipport(tox->sys.ns, tox->sys.mem, ip, &root, TOX_SOCK_DGRAM, tox->m->options.dns_enabled); if (count < 1) { - SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_BAD_IP); + SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_BAD_IP); net_freeipport(tox->sys.mem, root); tox_unlock(tox); return false; @@ -141,7 +141,7 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip for (int32_t i = 0; i < count; ++i) { root[i].port = net_htons(port); - if (dht_getnodes(tox->m->dht, &root[i], public_key, target_public_key)) { + if (dht_send_nodes_request(tox->m->dht, &root[i], public_key, target_public_key)) { success = true; } } @@ -151,11 +151,11 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip net_freeipport(tox->sys.mem, root); if (!success) { - SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_FAIL); + SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_FAIL); return false; } - SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_OK); return true; } diff --git a/toxcore/tox_private.h b/toxcore/tox_private.h index cc8a085..4cc3edd 100644 --- a/toxcore/tox_private.h +++ b/toxcore/tox_private.h @@ -11,6 +11,7 @@ #include #include "tox.h" +#include "tox_options.h" #ifdef __cplusplus extern "C" { @@ -92,52 +93,53 @@ uint32_t tox_dht_node_public_key_size(void); * @param ip The node's IP address, represented as a NUL-terminated C string. * @param port The node's port. */ -typedef void tox_dht_get_nodes_response_cb(Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port, - void *user_data); +typedef void tox_dht_nodes_response_cb( + Tox *tox, const uint8_t *public_key, const char *ip, uint32_t ip_length, + uint16_t port, void *user_data); /** - * Set the callback for the `dht_get_nodes_response` event. Pass NULL to unset. + * Set the callback for the `dht_nodes_response` event. Pass NULL to unset. * - * This event is triggered when a getnodes response is received from a DHT peer. + * This event is triggered when a nodes response is received from a DHT peer. */ -void tox_callback_dht_get_nodes_response(Tox *tox, tox_dht_get_nodes_response_cb *callback); +void tox_callback_dht_nodes_response(Tox *tox, tox_dht_nodes_response_cb *callback); -typedef enum Tox_Err_Dht_Get_Nodes { +typedef enum Tox_Err_Dht_Send_Nodes_Request { /** * The function returned successfully. */ - TOX_ERR_DHT_GET_NODES_OK, + TOX_ERR_DHT_SEND_NODES_REQUEST_OK, /** * UDP is disabled in Tox options; the DHT can only be queried when UDP is * enabled. */ - TOX_ERR_DHT_GET_NODES_UDP_DISABLED, + TOX_ERR_DHT_SEND_NODES_REQUEST_UDP_DISABLED, /** * One of the arguments to the function was NULL when it was not expected. */ - TOX_ERR_DHT_GET_NODES_NULL, + TOX_ERR_DHT_SEND_NODES_REQUEST_NULL, /** * The supplied port is invalid. */ - TOX_ERR_DHT_GET_NODES_BAD_PORT, + TOX_ERR_DHT_SEND_NODES_REQUEST_BAD_PORT, /** * The supplied IP address is invalid. */ - TOX_ERR_DHT_GET_NODES_BAD_IP, + TOX_ERR_DHT_SEND_NODES_REQUEST_BAD_IP, /** - * The getnodes request failed. This usually means the packet failed to + * The nodes request failed. This usually means the packet failed to * send. */ - TOX_ERR_DHT_GET_NODES_FAIL, -} Tox_Err_Dht_Get_Nodes; + TOX_ERR_DHT_SEND_NODES_REQUEST_FAIL, +} Tox_Err_Dht_Send_Nodes_Request; /** - * This function sends a getnodes request to a DHT node for its peers that + * This function sends a nodes request to a DHT node for its peers that * are "close" to the passed target public key according to the distance metric * used by the DHT implementation. * @@ -151,8 +153,8 @@ typedef enum Tox_Err_Dht_Get_Nodes { * * @return true on success. */ -bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port, - const uint8_t *target_public_key, Tox_Err_Dht_Get_Nodes *error); +bool tox_dht_send_nodes_request(const Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port, + const uint8_t *target_public_key, Tox_Err_Dht_Send_Nodes_Request *error); /** * This function returns the number of DHT nodes in the closelist. @@ -201,7 +203,7 @@ typedef enum Tox_Netprof_Packet_Id { TOX_NETPROF_PACKET_ID_ONE = 0x01, /** - * Get nodes request packet (UDP). + * Nodes request packet (UDP). * Connection notification (TCP). */ TOX_NETPROF_PACKET_ID_TWO = 0x02, @@ -212,7 +214,7 @@ typedef enum Tox_Netprof_Packet_Id { TOX_NETPROF_PACKET_ID_TCP_DISCONNECT = 0x03, /** - * Send nodes response packet (UDP). + * Nodes response packet (UDP). * Ping packet (TCP). */ TOX_NETPROF_PACKET_ID_FOUR = 0x04, diff --git a/toxcore/tox_struct.h b/toxcore/tox_struct.h index 88f74ea..9383c2a 100644 --- a/toxcore/tox_struct.h +++ b/toxcore/tox_struct.h @@ -8,10 +8,9 @@ #include -#include "Messenger.h" -#include "mem.h" #include "mono_time.h" #include "tox.h" +#include "tox_options.h" // tox_log_cb #include "tox_private.h" #ifdef __cplusplus @@ -19,7 +18,7 @@ extern "C" { #endif struct Tox { - Messenger *m; + struct Messenger *m; Mono_Time *mono_time; Tox_System sys; pthread_mutex_t *mutex; @@ -44,7 +43,7 @@ struct Tox { tox_conference_title_cb *conference_title_callback; tox_conference_peer_name_cb *conference_peer_name_callback; tox_conference_peer_list_changed_cb *conference_peer_list_changed_callback; - tox_dht_get_nodes_response_cb *dht_get_nodes_response_callback; + tox_dht_nodes_response_cb *dht_nodes_response_callback; tox_friend_lossy_packet_cb *friend_lossy_packet_callback_per_pktid[UINT8_MAX + 1]; tox_friend_lossless_packet_cb *friend_lossless_packet_callback_per_pktid[UINT8_MAX + 1]; tox_group_peer_name_cb *group_peer_name_callback; diff --git a/toxcore/tox_test.cc b/toxcore/tox_test.cc index d3fe9ba..23a53b0 100644 --- a/toxcore/tox_test.cc +++ b/toxcore/tox_test.cc @@ -6,6 +6,8 @@ #include #include "crypto_core.h" +#include "tox_log_level.h" +#include "tox_options.h" #include "tox_private.h" namespace {