diff --git a/.cirrus.yml b/.cirrus.yml index 903d98a5..bb477b26 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -27,6 +27,7 @@ bazel-dbg_task: - cd /src/workspace && bazel test -k --build_tag_filters=-haskell --test_tag_filters=-haskell + --remote_http_cache=http://$CIRRUS_HTTP_CACHE_HOST -- //c-toxcore/... -//c-toxcore/auto_tests:tcp_relay_test # TODO(robinlinden): Why does this pass locally but not in Cirrus? @@ -47,13 +48,30 @@ cimple_task: //c-toxcore/... freebsd_task: - container: - image: toxchat/freebsd:latest - cpu: 2 - memory: 4G - kvm: true + freebsd_instance: + image_family: freebsd-14-0 configure_script: + - PAGER=cat ASSUME_ALWAYS_YES=YES pkg install + cmake + git + gmake + googletest + libconfig + libsodium + libvpx + opus + pkgconf - git submodule update --init --recursive - - cd .. && mv cirrus-ci-build /work/c-toxcore && mkdir cirrus-ci-build test_all_script: - - cd /work/c-toxcore && .github/scripts/cmake-freebsd + - | + # TODO(iphydf): Investigate FreeBSD failures on these tests. + sed -Ei -e '/\(dht_getnodes_api\)/s/^/#/' auto_tests/CMakeLists.txt + cmake . \ + -DMIN_LOGGER_LEVEL=TRACE \ + -DMUST_BUILD_TOXAV=ON \ + -DNON_HERMETIC_TESTS=ON \ + -DTEST_TIMEOUT_SECONDS=50 \ + -DUSE_IPV6=OFF \ + -DAUTOTEST=ON + cmake --build . --target install + ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 diff --git a/.clang-tidy b/.clang-tidy index f1aca9f9..d41d6628 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -21,7 +21,7 @@ CheckOptions: - key: readability-identifier-naming.MacroDefinitionCase value: UPPER_CASE - key: readability-identifier-naming.MacroDefinitionIgnoredRegexp - value: "^_.*|nullable|non_null|nullptr|static_assert|ck_.*" + value: "^_.*|bitwise|force|nullable|non_null|nullptr|static_assert|ck_.*" - key: readability-identifier-naming.ParameterCase value: lower_case - key: readability-identifier-naming.StructCase @@ -36,12 +36,14 @@ CheckOptions: value: lower_case - key: llvmlibc-restrict-system-libc-headers.Includes - value: "arpa/inet.h,assert.h,ctype.h,errno.h,fcntl.h,getopt.h,libconfig.h,limits.h,linux/if.h,math.h,netdb.h,netinet/in.h,opus.h,pthread.h,signal.h,sodium/crypto_scalarmult_curve25519.h,sodium.h,sodium/randombytes.h,stdarg.h,stdbool.h,stddef.h,stdint.h,stdio.h,stdlib.h,string.h,sys/ioctl.h,syslog.h,sys/resource.h,sys/socket.h,sys/stat.h,sys/time.h,sys/types.h,time.h,unistd.h,vpx/vp8cx.h,vpx/vp8dx.h,vpx/vpx_decoder.h,vpx/vpx_encoder.h,vpx/vpx_image.h" + value: "alloca.h,arpa/inet.h,assert.h,ctype.h,errno.h,fcntl.h,getopt.h,libconfig.h,limits.h,linux/if.h,math.h,netdb.h,netinet/in.h,opus.h,pthread.h,signal.h,sodium/crypto_scalarmult_curve25519.h,sodium.h,sodium/randombytes.h,stdarg.h,stdbool.h,stddef.h,stdint.h,stdio.h,stdlib.h,string.h,sys/ioctl.h,syslog.h,sys/resource.h,sys/socket.h,sys/stat.h,sys/time.h,sys/types.h,time.h,unistd.h,vpx/vp8cx.h,vpx/vp8dx.h,vpx/vpx_decoder.h,vpx/vpx_encoder.h,vpx/vpx_image.h" - key: hicpp-signed-bitwise.IgnorePositiveIntegerLiterals value: true - key: concurrency-mt-unsafe.FunctionSet value: posix - - key: misc-include-cleaner.IgnoreHeaders - value: "pthread.h;stdbool.h;stddef.h;stdint.;stdint.h;stdint...;cstdint;sodium.*;sys/.*;unistd.h;opus.*;vpx.*;attributes.h;tox_struct.h" - key: readability-function-cognitive-complexity.Threshold value: 153 # TODO(iphydf): Decrease. tox_new is the highest at the moment. + - key: cppcoreguidelines-avoid-do-while.IgnoreMacros + value: true + - key: readability-simplify-boolean-expr.SimplifyDeMorgan + value: false diff --git a/.github/scripts/cmake-windows.sh b/.github/scripts/cmake-windows.sh index ed2f6773..a794ad1e 100644 --- a/.github/scripts/cmake-windows.sh +++ b/.github/scripts/cmake-windows.sh @@ -18,7 +18,7 @@ docker run \ -e ENABLE_ARCH_i686="$i686" \ -e ENABLE_ARCH_x86_64="$x86_64" \ -e ENABLE_TEST=true \ - -e EXTRA_CMAKE_FLAGS="-DBOOTSTRAP_DAEMON=OFF -DMIN_LOGGER_LEVEL=DEBUG -DTEST_TIMEOUT_SECONDS=90 -DAUTOTEST=ON" \ + -e EXTRA_CMAKE_FLAGS="-DBOOTSTRAP_DAEMON=OFF -DMIN_LOGGER_LEVEL=DEBUG -DTEST_TIMEOUT_SECONDS=90 -DAUTOTEST=ON -DUSE_IPV6=OFF" \ -e CMAKE_C_FLAGS="$C_FLAGS" \ -e CMAKE_CXX_FLAGS="$CXX_FLAGS" \ -e CMAKE_EXE_LINKER_FLAGS="$LD_FLAGS" \ @@ -26,4 +26,6 @@ docker run \ -v "$PWD:/toxcore" \ -v "$PWD/result:/prefix" \ --rm \ + -t \ + --pull never \ "toxchat/windows:$WINDOWS_ARCH" diff --git a/.github/scripts/tox-bootstrapd-docker b/.github/scripts/tox-bootstrapd-docker index 48665537..cfb2cb38 100755 --- a/.github/scripts/tox-bootstrapd-docker +++ b/.github/scripts/tox-bootstrapd-docker @@ -3,10 +3,11 @@ set -exu -o pipefail LOCAL="${1:-}" +CHECK="${2:-}" readarray -t FILES <<<"$(git ls-files)" -if ! tar c "${FILES[@]}" | docker build -f other/bootstrap_daemon/docker/Dockerfile -t toxchat/bootstrap-node - 2>&1 | tee docker-build.log; then +if ! tar c "${FILES[@]}" | docker build --build-arg="CHECK=$CHECK" -f other/bootstrap_daemon/docker/Dockerfile -t toxchat/bootstrap-node - 2>&1 | tee docker-build.log; then grep -o "::error.*::[a-f0-9]* /usr/local/bin/tox-bootstrapd" docker-build.log false fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ab9ba1bd..7988ea26 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,16 +15,24 @@ jobs: analysis: strategy: + fail-fast: false matrix: - tool: [autotools, clang-tidy, compcert, cppcheck, doxygen, infer, misra, tcc, tokstyle] + tool: [autotools, clang-tidy, compcert, cppcheck, doxygen, goblint, infer, freebsd, misra, modules, pkgsrc, rpm, slimcc, sparse, tcc, tokstyle] runs-on: ubuntu-latest steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Docker Build - uses: docker/build-push-action@v4 with: - file: other/docker/${{ matrix.tool }}/Dockerfile + driver: docker + - name: Build toxchat/c-toxcore:sources + uses: docker/build-push-action@v5 + with: + file: other/docker/sources/sources.Dockerfile + tags: toxchat/c-toxcore:sources + - name: Docker Build + uses: docker/build-push-action@v5 + with: + file: other/docker/${{ matrix.tool }}/${{ matrix.tool }}.Dockerfile coverage-linux: runs-on: ubuntu-latest @@ -75,7 +83,7 @@ jobs: - name: Build and test run: .github/scripts/cmake-osx - build-msvc: + build-windows-msvc: strategy: matrix: version: [2019, 2022] @@ -102,17 +110,77 @@ jobs: cd _build ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 --build-config Debug - build-windows: - strategy: - matrix: - bits: [32, 64] + build-netbsd: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: submodules: recursive - - name: Cross compilation - run: .github/scripts/cmake-win${{ matrix.bits }} script + - name: Test in NetBSD + id: test + uses: vmactions/netbsd-vm@v1 + with: + usesh: true + copyback: false + prepare: + /usr/sbin/pkg_add + cmake + googletest + libconfig + libopus + libsodium + libvpx + pkg-config + + run: | + # TODO(iphydf): Investigate NetBSD failures on these tests. + sed -Ei -e '/\((TCP|dht_getnodes_api)\)/s/^/#/' auto_tests/CMakeLists.txt + cmake . \ + -DMIN_LOGGER_LEVEL=TRACE \ + -DMUST_BUILD_TOXAV=ON \ + -DNON_HERMETIC_TESTS=ON \ + -DTEST_TIMEOUT_SECONDS=90 \ + -DUSE_IPV6=OFF \ + -DAUTOTEST=ON + cmake --build . --target install + ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 + + build-freebsd: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Test in FreeBSD + id: test + uses: vmactions/freebsd-vm@v1 + with: + usesh: true + copyback: false + prepare: + PAGER=cat ASSUME_ALWAYS_YES=YES pkg install + cmake + git + gmake + googletest + libconfig + libsodium + libvpx + opus + pkgconf + + run: | + # TODO(iphydf): Investigate FreeBSD failures on these tests. + sed -Ei -e '/\(dht_getnodes_api\)/s/^/#/' auto_tests/CMakeLists.txt + cmake . \ + -DMIN_LOGGER_LEVEL=TRACE \ + -DMUST_BUILD_TOXAV=ON \ + -DNON_HERMETIC_TESTS=ON \ + -DTEST_TIMEOUT_SECONDS=50 \ + -DUSE_IPV6=OFF \ + -DAUTOTEST=ON + cmake --build . --target install + ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 mypy: runs-on: ubuntu-latest diff --git a/.github/workflows/coverity-scan.yml b/.github/workflows/coverity-scan.yml index 56776cb0..4813358a 100644 --- a/.github/workflows/coverity-scan.yml +++ b/.github/workflows/coverity-scan.yml @@ -8,7 +8,7 @@ jobs: latest: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: recursive - name: Install libraries diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 3779621d..9b7092fc 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -25,7 +25,9 @@ jobs: with: submodules: recursive - name: Docker Build - run: .github/scripts/tox-bootstrapd-docker local + run: .github/scripts/tox-bootstrapd-docker local "$CHECK" + env: + CHECK: "${{ contains(github.event.pull_request.title, 'chore: Release ') && 'sha256sum' || 'echo' }}" - name: Push latest image to DockerHub if: ${{ github.event_name == 'push' }} run: docker push toxchat/bootstrap-node:latest @@ -46,7 +48,7 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: "{{defaultContext}}:other/bootstrap_daemon/websocket" push: ${{ github.event_name == 'push' }} @@ -67,7 +69,7 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: "." file: .clusterfuzzlite/Dockerfile @@ -88,7 +90,7 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: file: testing/Dockerfile push: ${{ github.event_name == 'push' }} @@ -108,7 +110,7 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: file: other/emscripten/Dockerfile push: ${{ github.event_name == 'push' }} @@ -121,21 +123,14 @@ jobs: steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - with: - driver: docker - 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 toxchat/c-toxcore:sources - uses: docker/build-push-action@v4 - with: - file: other/docker/sources/Dockerfile - tags: toxchat/c-toxcore:sources - name: Build and push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: file: other/docker/esp32/Dockerfile push: ${{ github.event_name == 'push' }} @@ -143,9 +138,15 @@ jobs: cache-from: type=registry,ref=toxchat/c-toxcore:esp32 cache-to: type=inline - docker-win32: + docker-windows-mingw: + strategy: + matrix: + bits: [32, 64] runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 + with: + submodules: recursive - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to DockerHub @@ -154,39 +155,27 @@ jobs: with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push - uses: docker/build-push-action@v4 + - name: Build and store to local Docker daemon + uses: docker/build-push-action@v5 with: - context: "{{defaultContext}}:other/docker/windows" - push: ${{ github.event_name == 'push' }} - tags: toxchat/windows:win32 - cache-from: type=registry,ref=toxchat/windows:win32 - cache-to: type=inline + context: other/docker/windows + load: true + tags: toxchat/windows:win${{ matrix.bits }} + cache-from: type=registry,ref=toxchat/windows:win${{ matrix.bits }} build-args: | - SUPPORT_ARCH_i686=true - SUPPORT_ARCH_x86_64=false + SUPPORT_ARCH_i686=${{ matrix.bits == '32' }} + SUPPORT_ARCH_x86_64=${{ matrix.bits == '64' }} SUPPORT_TEST=true - - docker-win64: - runs-on: ubuntu-latest - steps: - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Login to DockerHub + - name: Push the stored image to Dockerhub if: ${{ github.event_name == 'push' }} - uses: docker/login-action@v3 + uses: docker/build-push-action@v5 with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push - uses: docker/build-push-action@v4 - with: - context: "{{defaultContext}}:other/docker/windows" + context: other/docker/windows push: ${{ github.event_name == 'push' }} - tags: toxchat/windows:win64 - cache-from: type=registry,ref=toxchat/windows:win64 - cache-to: type=inline + tags: toxchat/windows:win${{ matrix.bits }} build-args: | - SUPPORT_ARCH_i686=false - SUPPORT_ARCH_x86_64=true + SUPPORT_ARCH_i686=${{ matrix.bits == '32' }} + SUPPORT_ARCH_x86_64=${{ matrix.bits == '64' }} SUPPORT_TEST=true + - name: Cross-compile + run: .github/scripts/cmake-win${{ matrix.bits }} script diff --git a/.github/workflows/post-submit.yml b/.github/workflows/post-submit.yml index 346d2472..1976d54f 100644 --- a/.github/workflows/post-submit.yml +++ b/.github/workflows/post-submit.yml @@ -11,7 +11,7 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Docker Build - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: file: other/docker/alpine-s390x/Dockerfile @@ -29,14 +29,14 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build toxchat/c-toxcore:sources - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: - file: other/docker/sources/Dockerfile + file: other/docker/sources/sources.Dockerfile tags: toxchat/c-toxcore:sources - name: Build and push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: - file: other/docker/coverage/Dockerfile + file: other/docker/coverage/coverage.Dockerfile push: ${{ github.event_name == 'push' }} tags: toxchat/c-toxcore:coverage cache-from: type=registry,ref=toxchat/c-toxcore:coverage diff --git a/.restyled.yaml b/.restyled.yaml index aecd497b..123ef65e 100644 --- a/.restyled.yaml +++ b/.restyled.yaml @@ -1,20 +1,25 @@ --- exclude: - - "**/*.api.h" - # shfmt doesn't support this file + # shfmt doesn't support this file. - "other/analysis/run-clang-tidy" + # Generated file. + - "CHANGELOG.md" restylers: - astyle: + image: restyled/restyler-astyle:d7967bcb8b622a98524b7df1da1b02652114cf9a arguments: ["--options=other/astyle/astylerc"] include: - - "!**/*.cc" + - "**/*.c" + - "**/*.h" - autopep8 - black - clang-format: - image: restyled/restyler-clang-format:13.0.1 + image: restyled/restyler-clang-format:v16.0.6 include: - "**/*.cc" + - "**/*.hh" + - prettier-markdown - prettier-yaml - reorder-python-imports - shellharden diff --git a/CMakeLists.txt b/CMakeLists.txt index 5eefb821..6d779fa0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,18 +136,20 @@ if(MIN_LOGGER_LEVEL) endif() endif() +option(EXPERIMENTAL_API "Install experimental header file with unstable API" OFF) + option(USE_IPV6 "Use IPv6 in tests" ON) if(NOT USE_IPV6) add_definitions(-DUSE_IPV6=0) endif() -option(BUILD_MISC_TESTS "Build additional tests and utilities" OFF) +option(BUILD_MISC_TESTS "Build additional tests" OFF) option(BUILD_FUN_UTILS "Build additional just for fun utilities" OFF) option(AUTOTEST "Enable autotests (mainly for CI)" OFF) if(AUTOTEST) option(NON_HERMETIC_TESTS "Whether to build and run tests that depend on an internet connection" OFF) - option(PROXY_TEST "Enable proxy test (needs HTTP/SOCKS5 proxy on port 8080/8081)" OFF) + option(PROXY_TEST "Enable proxy test (requires other/proxy/proxy_server.go to be running)" OFF) endif() option(BUILD_TOXAV "Whether to build the tox AV library" ON) @@ -223,6 +225,8 @@ set(toxcore_SOURCES toxcore/ccompat.h toxcore/crypto_core.c toxcore/crypto_core.h + toxcore/crypto_core_pack.c + toxcore/crypto_core_pack.h toxcore/DHT.c toxcore/DHT.h toxcore/events/conference_connected.c @@ -231,6 +235,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/events_alloc.c toxcore/events/events_alloc.h toxcore/events/file_chunk_request.c @@ -356,8 +361,11 @@ 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_private.h^tox) + ${toxcore_SOURCE_DIR}/toxcore/tox_dispatch.h^tox) +if(EXPERIMENTAL_API) + set(toxcore_API_HEADERS ${toxcore_API_HEADERS} + ${toxcore_SOURCE_DIR}/toxcore/tox_private.h^tox) +endif() ################################################################################ # @@ -446,7 +454,7 @@ elseif(TARGET Threads::Threads) set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} Threads::Threads) endif() if(WIN32) - set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} iphlpapi wsock32 ws2_32) + set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} iphlpapi ws2_32) endif() ################################################################################ @@ -526,7 +534,7 @@ endfunction() # The actual unit tests follow. # -if(GTEST_FOUND) +if(TARGET GTest::gtest AND TARGET GTest::gmock) unit_test(toxav ring_buffer) unit_test(toxav rtp) unit_test(toxcore DHT) diff --git a/INSTALL.md b/INSTALL.md index 8bb901bd..3754faac 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,6 +1,8 @@ # Installation instructions -These instructions will guide you through the process of building and installing the toxcore library and its components, as well as getting already pre-built binaries. +These instructions will guide you through the process of building and installing +the toxcore library and its components, as well as getting already pre-built +binaries. ## Table of contents @@ -30,37 +32,44 @@ These instructions will guide you through the process of building and installing #### Main -This repository, although called `toxcore`, in fact contains several libraries besides `toxcore` which complement it, as well as several executables. However, note that although these are separate libraries, at the moment, when building the libraries, they are all merged into a single `toxcore` library. Here is the full list of the main components that can be built using the CMake, their dependencies and descriptions. +This repository, although called `toxcore`, in fact contains several libraries +besides `toxcore` which complement it, as well as several executables. However, +note that although these are separate libraries, at the moment, when building +the libraries, they are all merged into a single `toxcore` library. Here is the +full list of the main components that can be built using the CMake, their +dependencies and descriptions. -| Name | Type | Dependencies | Platform | Description | -|------------------|------------|------------------------------------|----------------|----------------------------------------------------------------------------| -| `toxcore` | Library | libsodium, libm, libpthread, librt | Cross-platform | The main Tox library that provides the messenger functionality. | -| `toxav` | Library | libtoxcore, libopus, libvpx | Cross-platform | Provides audio/video functionality. | -| `toxencryptsave` | Library | libtoxcore, libsodium | Cross-platform | Provides encryption of Tox profiles (savedata), as well as arbitrary data. | -| `DHT_bootstrap` | Executable | libtoxcore | Cross-platform | A simple DHT bootstrap node. | -| `tox-bootstrapd` | Executable | libtoxcore, libconfig | Unix-like | Highly configurable DHT bootstrap node daemon (systemd, SysVinit, Docker). | +| Name | Type | Dependencies | Platform | Description | +| ---------------- | ---------- | ---------------------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `toxcore` | Library | libsodium, libm, libpthread, librt | Cross-platform | The main Tox library that provides the messenger functionality. | +| `toxav` | Library | libtoxcore, libopus, libvpx | Cross-platform | Provides audio/video functionality. | +| `toxencryptsave` | Library | libtoxcore, libsodium | Cross-platform | Provides encryption of Tox profiles (savedata), as well as arbitrary data. | +| `DHT_bootstrap` | Executable | libtoxcore | Cross-platform | A simple DHT bootstrap node. | +| `tox-bootstrapd` | Executable | libtoxcore, libconfig | Unix-like | Highly configurable DHT bootstrap node daemon (systemd, SysVinit, Docker). | | `cmp` | Library | | Cross-platform | C implementation of the MessagePack serialization format. [https://github.com/camgunz/cmp](https://github.com/camgunz/cmp) | #### Secondary -There are some programs that are not built by default which you might find interesting. You need to pass `-DBUILD_FUN_UTILS=ON` to cmake to build them. +There are some programs that are not built by default which you might find +interesting. You need to pass `-DBUILD_FUN_UTILS=ON` to cmake to build them. ##### Vanity key generators Can be used to generate vanity Tox Ids or DHT bootstrap node public keys. -| Name | Type | Dependencies | Platform | Description | -|---------------------------|------------|-----------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `cracker` | Executable | libsodium, OpenMP | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which starts with a specified byte sequence. Multi-threaded. | -| `cracker_simple` | Executable | libsodium | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which starts with a specified byte sequence. Single-threaded. | -| `strkey` | Executable | libsodium | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which contains a specified byte sequence at a specified or any position at all. Single-threaded. | +| Name | Type | Dependencies | Platform | Description | +| ---------------- | ---------- | ----------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `cracker` | Executable | libsodium, OpenMP | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which starts with a specified byte sequence. Multi-threaded. | +| `cracker_simple` | Executable | libsodium | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which starts with a specified byte sequence. Single-threaded. | +| `strkey` | Executable | libsodium | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which contains a specified byte sequence at a specified or any position at all. Single-threaded. | ##### Key file generators -Useful for generating Tox profiles from the output of the vanity key generators, as well as generating random Tox profiles. +Useful for generating Tox profiles from the output of the vanity key generators, +as well as generating random Tox profiles. | Name | Type | Dependencies | Platform | Description | -|---------------------------|------------|-----------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ------------------------- | ---------- | --------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `make-funny-savefile` | Script | python | Cross-platform | Generates a Tox profile file (savedata file) with the provided key pair. | | `create_bootstrap_keys` | Executable | libsodium | Cross-platform | Generates a keys file for tox-bootstrapd with either the provided or a random key pair. | | `create_minimal_savedata` | Executable | libsodium | Cross-platform | Generates a minimal Tox profile file (savedata file) with either the provided or a random key pair, printing the generated Tox Id and secret & public key information. | @@ -69,10 +78,10 @@ Useful for generating Tox profiles from the output of the vanity key generators, ##### Other -| Name | Type | Dependencies | Platform | Description | -|---------------------------|------------|-----------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `bootstrap_node_info` | Script | python3 | Cross-platform | Prints version and Message Of The Day (MOTD) information of the specified DHT bootstrap node, given the node doesn't have those disabled. | -| `sign` | Executable | libsodium | Cross-platform | Signs a file with a ed25519 key. | +| Name | Type | Dependencies | Platform | Description | +| --------------------- | ---------- | ------------ | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `bootstrap_node_info` | Script | python3 | Cross-platform | Prints version and Message Of The Day (MOTD) information of the specified DHT bootstrap node, given the node doesn't have those disabled. | +| `sign` | Executable | libsodium | Cross-platform | Signs a file with a ed25519 key. | ## Building @@ -80,56 +89,78 @@ Useful for generating Tox profiles from the output of the vanity key generators, #### Library dependencies -Library dependencies are listed in the [components](#components) table. The dependencies need to be satisfied for the components to be built. Note that if you don't have a dependency for some component, e.g. you don't have `libopus` installed required for building `toxav` component, building of that component is silently disabled. +Library dependencies are listed in the [components](#components) table. The +dependencies need to be satisfied for the components to be built. Note that if +you don't have a dependency for some component, e.g. you don't have `libopus` +installed required for building `toxav` component, building of that component is +silently disabled. - -Be advised that due to the addition of `cmp` as a submodule, you now also need to initialize the git submodules required by toxcore. This can be done by cloning the repo with the addition of `--recurse-submodules` or by running `git submodule update --init` in the root directory of the repo. +Be advised that due to the addition of `cmp` as a submodule, you now also need +to initialize the git submodules required by toxcore. This can be done by +cloning the repo with the addition of `--recurse-submodules` or by running +`git submodule update --init` in the root directory of the repo. #### Compiler requirements The supported compilers are GCC, Clang and MinGW. -In theory, any compiler that fully supports C99 and accepts GCC flags should work. +In theory, any compiler that fully supports C99 and accepts GCC flags should +work. -There is a partial and experimental support of Microsoft Visual C++ compiler. We welcome any patches that help improve it. +There is a partial and experimental support of Microsoft Visual C++ compiler. We +welcome any patches that help improve it. -You should have a C99 compatible compiler in order to build the main components. The secondary components might require the compiler to support GNU extensions. +You should have a C99 compatible compiler in order to build the main components. +The secondary components might require the compiler to support GNU extensions. #### Build system requirements -To build the main components you need to have CMake of at least 2.8.6 version installed. You also need to have pkg-config installed, the build system uses it to find dependency libraries. +To build the main components you need to have CMake of at least 2.8.6 version +installed. You also need to have pkg-config installed, the build system uses it +to find dependency libraries. -There is some experimental accommodation for building natively on Windows, i.e. without having to use MSYS/Cygwin and pkg-config, but it uses exact hardcoded paths for finding libraries and supports building only of some of toxcore components, so your mileage might vary. +There is some experimental accommodation for building natively on Windows, i.e. +without having to use MSYS/Cygwin and pkg-config, but it uses exact hardcoded +paths for finding libraries and supports building only of some of toxcore +components, so your mileage might vary. ### CMake options There are some options that are available to configure the build. -| Name | Description | Expected Value | Default Value | -|------------------------|-----------------------------------------------------------------------------------------------|---------------------------------------------------------------------------|---------------------------------------------------| -| `AUTOTEST` | Enable autotests (mainly for CI). | ON or OFF | OFF | -| `BOOTSTRAP_DAEMON` | Enable building of tox-bootstrapd, the DHT bootstrap node daemon. For Unix-like systems only. | ON or OFF | ON | -| `BUILD_FUZZ_TESTS` | Build fuzzing harnesses. | ON or OFF | OFF | -| `BUILD_MISC_TESTS` | Build additional tests. | ON or OFF | OFF | -| `BUILD_FUN_UTILS` | Build additional funny utilities. | ON or OFF | OFF | -| `BUILD_TOXAV` | Whether to build the toxav library. | ON or OFF | ON | -| `CMAKE_INSTALL_PREFIX` | Path to where everything should be installed. | Directory path. | Platform-dependent. Refer to CMake documentation. | -| `CMAKE_BUILD_TYPE` | Specifies the build type on single-configuration generators (e.g. make or ninja). | Debug, Release, RelWithDebInfo, MinSizeRel | Empty string. | -| `DHT_BOOTSTRAP` | Enable building of `DHT_bootstrap` | ON or OFF | ON | -| `ENABLE_SHARED` | Build shared (dynamic) libraries for all modules. | ON or OFF | ON | -| `ENABLE_STATIC` | Build static libraries for all modules. | ON or OFF | ON | -| `EXECUTION_TRACE` | Print a function trace during execution (for debugging). | ON or OFF | OFF | -| `FULLY_STATIC` | Build fully static executables. | ON or OFF | OFF | -| `MIN_LOGGER_LEVEL` | Logging level to use. | TRACE, DEBUG, INFO, WARNING, ERROR or nothing (empty string) for default. | Empty string. | -| `MSVC_STATIC_SODIUM` | Whether to link libsodium statically for MSVC. | ON or OFF | OFF | -| `MUST_BUILD_TOXAV` | Fail the build if toxav cannot be built. | ON or OFF | OFF | -| `NON_HERMETIC_TESTS` | Whether to build and run tests that depend on an internet connection. | ON or OFF | OFF | -| `STRICT_ABI` | Enforce strict ABI export in dynamic libraries. | ON or OFF | OFF | -| `TEST_TIMEOUT_SECONDS` | Limit runtime of each test to the number of seconds specified. | Positive number or nothing (empty string). | Empty string. | -| `USE_IPV6` | Use IPv6 in tests. | ON or OFF | ON | +| Name | Description | Expected Value | Default Value | +| ----------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------- | +| `AUTOTEST` | Enable autotests (mainly for CI). | ON or OFF | OFF | +| `BOOTSTRAP_DAEMON` | Enable building of tox-bootstrapd, the DHT bootstrap node daemon. For Unix-like systems only. | ON or OFF | ON | +| `BUILD_FUN_UTILS` | Build additional just for fun utilities. | ON or OFF | OFF | +| `BUILD_FUZZ_TESTS` | Build fuzzing harnesses. | ON or OFF | OFF | +| `BUILD_MISC_TESTS` | Build additional tests. | ON or OFF | OFF | +| `BUILD_TOXAV` | Whether to build the toxav library. | ON or OFF | ON | +| `CMAKE_BUILD_TYPE` | Specifies the build type on single-configuration generators (e.g. make or ninja). | Debug, Release, RelWithDebInfo, MinSizeRel | Empty string. | +| `CMAKE_INSTALL_PREFIX` | Path to where everything should be installed. | Directory path. | Platform-dependent. Refer to CMake documentation. | +| `DHT_BOOTSTRAP` | Enable building of `DHT_bootstrap`. | ON or OFF | ON | +| `ENABLE_SHARED` | Build shared (dynamic) libraries for all modules. | ON or OFF | ON | +| `ENABLE_STATIC` | Build static libraries for all modules. | ON or OFF | ON | +| `EXPERIMENTAL_API` | Install experimental header file with unstable API. | ON or OFF | OFF | +| `FLAT_OUTPUT_STRUCTURE` | Whether to produce output artifacts in {bin,lib}. | ON or OFF | OFF | +| `FULLY_STATIC` | Build fully static executables. | ON or OFF | OFF | +| `MIN_LOGGER_LEVEL` | Logging level to use. | TRACE, DEBUG, INFO, WARNING, ERROR or nothing (empty string) for default. | Empty string. | +| `MSVC_STATIC_SODIUM` | Whether to link libsodium statically for MSVC. | ON or OFF | OFF | +| `MUST_BUILD_TOXAV` | Fail the build if toxav cannot be built. | ON or OFF | OFF | +| `NON_HERMETIC_TESTS` | Whether to build and run tests that depend on an internet connection. | ON or OFF | OFF | +| `PROXY_TEST` | Enable proxy test (requires `other/proxy/proxy_server.go` to be running). | ON or OFF | OFF | +| `STRICT_ABI` | Enforce strict ABI export in dynamic libraries. | ON or OFF | OFF | +| `TEST_TIMEOUT_SECONDS` | Limit runtime of each test to the number of seconds specified. | Positive number or nothing (empty string). | Empty string. | +| `USE_IPV6` | Use IPv6 in tests. | ON or OFF | ON | You can get this list of option using the following commands +```sh +cmake -B _build -LAH +``` + +or + ```sh grep "option(" CMakeLists.txt cmake/* grep "set(.* CACHE" CMakeLists.txt cmake/* @@ -150,11 +181,12 @@ cmake \ ``` ### Building tests + In addition to the integration tests ("autotests") and miscellaneous tests enabled by cmake variables described above, there are unit tests which will be built if the source distribution of gtest (the Google Unit Test framework) is -found by cmake in `c-toxcore/third_party`. This can be achieved by running -'git clone https://github.com/google/googletest` from that directory. +found by cmake in `c-toxcore/third_party`. This can be achieved by running 'git +clone https://github.com/google/googletest` from that directory. ### Build process @@ -170,19 +202,33 @@ make make install ``` +or shorter + +```sh +cmake -B _build +cmake -B _build --target install +``` + #### Windows ##### Building on Windows host ###### Microsoft Visual Studio's Developer Command Prompt -In addition to meeting the [requirements](#requirements), you need a version of Visual Studio (the [community edition](https://www.visualstudio.com/vs/visual-studio-express/) is enough) and a CMake version that's compatible with the Visual Studio version you're using. +In addition to meeting the [requirements](#requirements), you need a version of +Visual Studio (the +[community edition](https://www.visualstudio.com/vs/visual-studio-express/) is +enough) and a CMake version that's compatible with the Visual Studio version +you're using. -You must also ensure that the msvc versions of dependencies you're using are placed in the correct folders. +You must also ensure that the msvc versions of dependencies you're using are +placed in the correct folders. -For libsodium that is `c-toxcore/third_party/libsodium`, and for pthreads-w32, it's `c-toxcore/third_party/pthreads-win32` +For libsodium that is `c-toxcore/third_party/libsodium`, and for pthreads-w32, +it's `c-toxcore/third_party/pthreads-win32` -Once all of this is done, from the **Developer Command Prompt for VS**, simply run +Once all of this is done, from the **Developer Command Prompt for VS**, simply +run ``` mkdir _build @@ -193,22 +239,23 @@ msbuild ALL_BUILD.vcxproj ###### MSYS/Cygwin -Download Cygwin ([32-bit](https://cygwin.com/setup-x86.exe)/[64-bit](https://cygwin.com/setup-x86_64.exe)) +Download Cygwin +([32-bit](https://cygwin.com/setup-x86.exe)/[64-bit](https://cygwin.com/setup-x86_64.exe)) Search and select exactly these packages in Devel category: - - mingw64-i686-gcc-core (32-bit) / mingw64-x86_64-gcc-core (64-bit) - - mingw64-i686-gcc-g++ (32-bit) / mingw64-x86_64-gcc-g++ (64-bit) - - make - - cmake - - libtool - - autoconf - - automake - - tree - - curl - - perl - - yasm - - pkg-config +- mingw64-i686-gcc-core (32-bit) / mingw64-x86_64-gcc-core (64-bit) +- mingw64-i686-gcc-g++ (32-bit) / mingw64-x86_64-gcc-g++ (64-bit) +- make +- cmake +- libtool +- autoconf +- automake +- tree +- curl +- perl +- yasm +- pkg-config To handle Windows EOL correctly run the following in the Cygwin Terminal: @@ -221,18 +268,24 @@ set -o igncr Download toxcore source code and extract it to a folder. -Open Cygwin Terminal in the toxcore folder and run `./other/windows_build_script_toxcore.sh` to start the build process. +Open Cygwin Terminal in the toxcore folder and run +`./other/windows_build_script_toxcore.sh` to start the build process. -Toxcore build result files will appear in `/root/prefix/` relatively to Cygwin folder (default `C:\cygwin64`). - -Dependency versions can be customized in `./other/windows_build_script_toxcore.sh` and described in the section below. +Toxcore build result files will appear in `/root/prefix/` relatively to Cygwin +folder (default `C:\cygwin64`). +Dependency versions can be customized in +`./other/windows_build_script_toxcore.sh` and described in the section below. ##### Cross-compiling from Linux -These cross-compilation instructions were tested on and written for 64-bit Ubuntu 16.04. You could generalize them for any Linux system, the only requirements are that you have Docker version of >= 1.9.0 and you are running 64-bit system. +These cross-compilation instructions were tested on and written for 64-bit +Ubuntu 16.04. You could generalize them for any Linux system, the only +requirements are that you have Docker version of >= 1.9.0 and you are running +64-bit system. -The cross-compilation is fully automated by a parameterized [Dockerfile](/other/docker/windows/Dockerfile). +The cross-compilation is fully automated by a parameterized +[Dockerfile](/other/docker/windows/Dockerfile). Install Docker @@ -243,17 +296,18 @@ apt-get install docker.io Get the toxcore source code and navigate to `other/docker/windows`. -Build the container image based on the Dockerfile. The following options are available to customize the building of the container image. +Build the container image based on the Dockerfile. The following options are +available to customize the building of the container image. -| Name | Description | Expected Value | Default Value | -|-----------------------|----------------------------------------------------------------|-------------------------------------|---------------| -| `SUPPORT_ARCH_i686` | Support building 32-bit toxcore. | "true" or "false" (case sensitive). | true | -| `SUPPORT_ARCH_x86_64` | Support building 64-bit toxcore. | "true" or "false" (case sensitive). | true | -| `SUPPORT_TEST` | Support running toxcore automated tests. | "true" or "false" (case sensitive). | false | -| `CROSS_COMPILE` | Cross-compiling. True for Docker, false for Cygwin. | "true" or "false" (case sensitive). | true | -| `VERSION_OPUS` | Version of libopus to build toxcore with. | Numeric version number. | 1.3.1 | -| `VERSION_SODIUM` | Version of libsodium to build toxcore with. | Numeric version number. | 1.0.18 | -| `VERSION_VPX` | Version of libvpx to build toxcore with. | Numeric version number. | 1.11.0 | +| Name | Description | Expected Value | Default Value | +| -------------------------- | ----------------------------------------------------- | ----------------------------------- | ------------- | +| `SUPPORT_ARCH_i686` | Support building 32-bit toxcore. | "true" or "false" (case sensitive). | true | +| `SUPPORT_ARCH_x86_64` | Support building 64-bit toxcore. | "true" or "false" (case sensitive). | true | +| `SUPPORT_TEST` | Support running toxcore automated tests. | "true" or "false" (case sensitive). | false | +| `VERSION_OPUS` | Version of libopus to build toxcore with. | Numeric version number. | 1.4 | +| `VERSION_SODIUM` | Version of libsodium to build toxcore with. | Numeric version number. | 1.0.19 | +| `VERSION_VPX` | Version of libvpx to build toxcore with. | Numeric version number. | 1.14.0 | +| `ENABLE_HASH_VERIFICATION` | Verify the hashes of the default dependency versions. | "true" or "false" (case sensitive). | true | Example of building a container image with options @@ -265,16 +319,16 @@ docker build \ . ``` -Run the container to build toxcore. The following options are available to customize the running of the container image. +Run the container to build toxcore. The following options are available to +customize the running of the container image. -| Name | Description | Expected Value | Default Value | -|----------------------|--------------------------------------------------------------------------------------------|-------------------------------------|--------------------------------------------------------------------| -| `ALLOW_TEST_FAILURE` | Don't stop if a test suite fails. | "true" or "false" (case sensitive). | `false` | -| `ENABLE_ARCH_i686` | Build 32-bit toxcore. The image should have been built with `SUPPORT_ARCH_i686` enabled. | "true" or "false" (case sensitive). | `true` | -| `ENABLE_ARCH_x86_64` | Build 64-bit toxcore. The image should have been built with `SUPPORT_ARCH_x86_64` enabled. | "true" or "false" (case sensitive). | `true` | -| `ENABLE_TEST` | Run the test suite. The image should have been built with `SUPPORT_TEST` enabled. | "true" or "false" (case sensitive). | `false` | -| `EXTRA_CMAKE_FLAGS` | Extra arguments to pass to the CMake command when building toxcore. | CMake options. | `-DTEST_TIMEOUT_SECONDS=90` | -| `CROSS_COMPILE` | Cross-compiling. True for Docker, false for Cygwin. | "true" or "false" (case sensitive). | `true` | +| Name | Description | Expected Value | Default Value | +| -------------------- | ------------------------------------------------------------------------------------------ | ----------------------------------- | ------------------------------------------ | +| `ALLOW_TEST_FAILURE` | Don't stop if a test suite fails. | "true" or "false" (case sensitive). | `false` | +| `ENABLE_ARCH_i686` | Build 32-bit toxcore. The image should have been built with `SUPPORT_ARCH_i686` enabled. | "true" or "false" (case sensitive). | `true` | +| `ENABLE_ARCH_x86_64` | Build 64-bit toxcore. The image should have been built with `SUPPORT_ARCH_x86_64` enabled. | "true" or "false" (case sensitive). | `true` | +| `ENABLE_TEST` | Run the test suite. The image should have been built with `SUPPORT_TEST` enabled. | "true" or "false" (case sensitive). | `false` | +| `EXTRA_CMAKE_FLAGS` | Extra arguments to pass to the CMake command when building toxcore. | CMake options. | `-DTEST_TIMEOUT_SECONDS=90 -DUSE_IPV6=OFF` | Example of running the container with options @@ -284,14 +338,117 @@ docker run \ -e ALLOW_TEST_FAILURE=true \ -v /path/to/toxcore/sourcecode:/toxcore \ -v /path/to/where/output/build/result:/prefix \ + -t \ --rm \ toxcore ``` -After the build succeeds, you should see the built toxcore libraries in `/path/to/where/output/build/result`. +After the build succeeds, you should see the built toxcore libraries in +`/path/to/where/output/build/result`. + +The file structure should look similar to the following + +``` +result +├── [4.0K] i686 +│   ├── [ 36K] bin +│   │   ├── [636K] DHT_bootstrap.exe +│   │   ├── [572K] cracker.exe +│   │   ├── [359K] cracker_simple.exe +│   │   ├── [378K] create_bootstrap_keys.exe +│   │   ├── [378K] create_minimal_savedata.exe +│   │   ├── [958K] create_savedata.exe +│   │   ├── [ 18K] libtoxcore.def +│   │   ├── [2.6M] libtoxcore.dll +│   │   ├── [ 65K] libtoxcore.exp +│   │   ├── [428K] libtoxcore.lib +│   │   ├── [989K] save-generator.exe +│   │   ├── [381K] sign.exe +│   │   └── [408K] strkey.exe +│   ├── [4.0K] include +│   │   └── [4.0K] tox +│   │   ├── [177K] tox.h +│   │   ├── [ 10K] tox_dispatch.h +│   │   ├── [ 26K] tox_events.h +│   │   ├── [6.4K] tox_private.h +│   │   ├── [ 26K] toxav.h +│   │   └── [ 12K] toxencryptsave.h +│   └── [4.0K] lib +│   ├── [577K] libopus.a +│   ├── [660K] libsodium.a +│   ├── [ 10K] libssp.a +│   ├── [1016K] libtoxcore.a +│   ├── [456K] libtoxcore.dll.a +│   ├── [2.7M] libvpx.a +│   ├── [ 72K] libwinpthread.a +│   └── [4.0K] pkgconfig +│   ├── [ 250] libsodium.pc +│   ├── [ 357] opus.pc +│   ├── [ 247] toxcore.pc +│   └── [ 309] vpx.pc +└── [4.0K] x86_64 + ├── [ 36K] bin + │   ├── [504K] DHT_bootstrap.exe + │   ├── [474K] cracker.exe + │   ├── [277K] cracker_simple.exe + │   ├── [287K] create_bootstrap_keys.exe + │   ├── [288K] create_minimal_savedata.exe + │   ├── [769K] create_savedata.exe + │   ├── [ 18K] libtoxcore.def + │   ├── [2.4M] libtoxcore.dll + │   ├── [ 64K] libtoxcore.exp + │   ├── [420K] libtoxcore.lib + │   ├── [800K] save-generator.exe + │   ├── [289K] sign.exe + │   └── [317K] strkey.exe + ├── [4.0K] include + │   └── [4.0K] tox + │   ├── [177K] tox.h + │   ├── [ 10K] tox_dispatch.h + │   ├── [ 26K] tox_events.h + │   ├── [6.4K] tox_private.h + │   ├── [ 26K] toxav.h + │   └── [ 12K] toxencryptsave.h + └── [4.0K] lib + ├── [697K] libopus.a + ├── [575K] libsodium.a + ├── [ 11K] libssp.a + ├── [905K] libtoxcore.a + ├── [449K] libtoxcore.dll.a + ├── [2.9M] libvpx.a + ├── [ 68K] libwinpthread.a + └── [4.0K] pkgconfig + ├── [ 252] libsodium.pc + ├── [ 359] opus.pc + ├── [ 249] toxcore.pc + └── [ 311] vpx.pc + +12 directories, 60 files +``` + +- `libtoxcore.dll` is the shared library. It is fully self-contained, with no + additional dependencies aside from the Windows OS dlls, and can be used in + MSVC, MinGW, Clang, etc. projects. Despite its name, it provides toxcore, + toxav, toxencryptsave -- all of Tox. +- `libtoxcore.a` is the static library. In order to use it, it needs to be + linked against the other provided .a libraries (but not the .dll.a!) and + additionally -liphlpapi and -lws2_32 Windows dlls. It similarly provides all + of Tox APIs. +- `libtoxcore.dll.a` is the MinGW import library for `libtoxcore.dll`. +- `libtoxcore.lib` is the MSVC import library for `libtoxcore.dll`. +- `libtoxcore.exp` and `libtoxcore.def` are the exported by `libtoxcore` + symbols. +- `*.exe` are statically compiled executables -- `DHT_bootstrap` and + [the fun utils](#secondary). ## Pre-built binaries ### Linux -Toxcore is packaged by at least by the following distributions: ALT Linux, [Arch Linux](https://www.archlinux.org/packages/?q=toxcore), [Fedora](https://apps.fedoraproject.org/packages/toxcore), Mageia, openSUSE, PCLinuxOS, ROSA and Slackware, [according to the information from pkgs.org](https://pkgs.org/download/toxcore). Note that this list might be incomplete and some other distributions might package it too. +Toxcore is packaged by at least by the following distributions: ALT Linux, +[Arch Linux](https://www.archlinux.org/packages/?q=toxcore), +[Fedora](https://apps.fedoraproject.org/packages/toxcore), Mageia, openSUSE, +PCLinuxOS, ROSA and Slackware, +[according to the information from pkgs.org](https://pkgs.org/download/toxcore). +Note that this list might be incomplete and some other distributions might +package it too. diff --git a/README.md b/README.md index cb62273f..e7a2b6ba 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,14 @@ # ![Project Tox](https://raw.github.com/TokTok/c-toxcore/master/other/tox.png "Project Tox") -**Current Coverage:** [![coverage](https://codecov.io/gh/TokTok/c-toxcore/branch/master/graph/badge.svg?token=BRfCKo02De)](https://codecov.io/gh/TokTok/c-toxcore) +**Current Coverage:** +[![coverage](https://codecov.io/gh/TokTok/c-toxcore/branch/master/graph/badge.svg?token=BRfCKo02De)](https://codecov.io/gh/TokTok/c-toxcore) -[**Website**](https://tox.chat) **|** [**Wiki**](https://wiki.tox.chat/) **|** [**Blog**](https://blog.tox.chat/) **|** [**FAQ**](https://wiki.tox.chat/doku.php?id=users:faq) **|** [**Binaries/Downloads**](https://tox.chat/download.html) **|** [**Clients**](https://wiki.tox.chat/doku.php?id=clients) **|** [**Compiling**](/INSTALL.md) +[**Website**](https://tox.chat) **|** [**Wiki**](https://wiki.tox.chat/) **|** +[**Blog**](https://blog.tox.chat/) **|** +[**FAQ**](https://wiki.tox.chat/doku.php?id=users:faq) **|** +[**Binaries/Downloads**](https://tox.chat/download.html) **|** +[**Clients**](https://wiki.tox.chat/doku.php?id=clients) **|** +[**Compiling**](/INSTALL.md) ## What is Tox @@ -16,29 +22,33 @@ and privacy easy to obtain for regular users. It uses ### ![Danger: Experimental](other/tox-warning.png) This is an **experimental** cryptographic network library. It has not been -formally audited by an independent third party that specializes in -cryptography or cryptanalysis. **Use this library at your own risk.** +formally audited by an independent third party that specializes in cryptography +or cryptanalysis. **Use this library at your own risk.** The underlying crypto library [libsodium](https://doc.libsodium.org/) provides reliable encryption, but the security model has not yet been fully specified. -See [issue 210](https://github.com/TokTok/c-toxcore/issues/210) for a -discussion on developing a threat model. See other issues for known weaknesses -(e.g. [issue 426](https://github.com/TokTok/c-toxcore/issues/426) describes -what can happen if your secret key is stolen). +See [issue 210](https://github.com/TokTok/c-toxcore/issues/210) for a discussion +on developing a threat model. See other issues for known weaknesses (e.g. +[issue 426](https://github.com/TokTok/c-toxcore/issues/426) describes what can +happen if your secret key is stolen). ## Toxcore Development Roadmap -The roadmap and changelog are generated from GitHub issues. You may view them -on the website, where they are updated at least once every 24 hours: +The roadmap and changelog are generated from GitHub issues. You may view them on +the website, where they are updated at least once every 24 hours: -- Changelog: https://toktok.ltd/changelog/c-toxcore -- Roadmap: https://toktok.ltd/roadmap/c-toxcore +- Changelog: https://toktok.ltd/changelog/c-toxcore +- Roadmap: https://toktok.ltd/roadmap/c-toxcore ## Installing toxcore Detailed installation instructions can be found in [INSTALL.md](INSTALL.md). -Be advised that due to the addition of `cmp` as a submodule, you now also need to initialize the git submodules required by toxcore. This can be done by cloning the repo with the following command: `git clone --recurse-submodules https://github.com/Toktok/c-toxcore` or by running `git submodule update --init` in the root directory of the repo. +Be advised that due to the addition of `cmp` as a submodule, you now also need +to initialize the git submodules required by toxcore. This can be done by +cloning the repo with the following command: +`git clone --recurse-submodules https://github.com/Toktok/c-toxcore` or by +running `git submodule update --init` in the root directory of the repo. In a nutshell, if you have [libsodium](https://github.com/jedisct1/libsodium) installed, run: @@ -74,17 +84,17 @@ if (err_new != TOX_ERR_NEW_OK) { } ``` -Here, we simply exit the program, but in a real client you will probably want -to do some error handling and proper error reporting to the user. The `NULL` +Here, we simply exit the program, but in a real client you will probably want to +do some error handling and proper error reporting to the user. The `NULL` argument given to the first parameter of `tox_new` is the `Tox_Options`. It -contains various write-once network settings and allows you to load a -previously serialised instance. See [toxcore/tox.h](tox.h) for details. +contains various write-once network settings and allows you to load a previously +serialised instance. See [toxcore/tox.h](tox.h) for details. ### Setting up callbacks -Toxcore works with callbacks that you can register to listen for certain -events. Examples of such events are "friend request received" or "friend sent -a message". Search the API for `tox_callback_*` to find all of them. +Toxcore works with callbacks that you can register to listen for certain events. +Examples of such events are "friend request received" or "friend sent a +message". Search the API for `tox_callback_*` to find all of them. Here, we will set up callbacks for receiving friend requests and receiving messages. We will always accept any friend request (because we're a bot), and @@ -172,3 +182,24 @@ the API documentation in [toxcore/tox.h](toxcore/tox.h) for more information. - [Another echo bot](https://wiki.tox.chat/developers/client_examples/echo_bot) - [minitox](https://github.com/hqwrong/minitox) (A minimal tox client) + +## SAST Tools + +This project uses various tools supporting Static Application Security Testing: + +- [clang-tidy](https://clang.llvm.org/extra/clang-tidy/): A clang-based C++ + "linter" tool. +- [Coverity](https://scan.coverity.com/): A cloud-based static analyzer service + for Java, C/C++, C#, JavaScript, Ruby, or Python that is free for open source + projects. +- [cppcheck](https://cppcheck.sourceforge.io/): A static analyzer for C/C++ + code. +- [cpplint](https://github.com/cpplint/cpplint): Static code checker for C++ +- [goblint](https://goblint.in.tum.de/): A static analyzer for multi-threaded C + programs, specializing in finding concurrency bugs. +- [infer](https://github.com/facebook/infer): A static analyzer for Java, C, + C++, and Objective-C. +- [PVS-Studio](https://pvs-studio.com/en/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source): + A static analyzer for C, C++, C#, and Java code. +- [tokstyle](https://github.com/TokTok/hs-tokstyle): A style checker for TokTok + C projects. diff --git a/auto_tests/BUILD.bazel b/auto_tests/BUILD.bazel index 2a205250..17606caf 100644 --- a/auto_tests/BUILD.bazel +++ b/auto_tests/BUILD.bazel @@ -17,6 +17,8 @@ cc_library( "//c-toxcore/toxcore:Messenger", "//c-toxcore/toxcore:mono_time", "//c-toxcore/toxcore:tox", + "//c-toxcore/toxcore:tox_dispatch", + "//c-toxcore/toxcore:tox_events", ], ) diff --git a/auto_tests/Makefile.inc b/auto_tests/Makefile.inc index 1553445d..6e4882d8 100644 --- a/auto_tests/Makefile.inc +++ b/auto_tests/Makefile.inc @@ -240,6 +240,7 @@ endif EXTRA_DIST += \ - $(top_srcdir)/auto_tests/data/save.tox \ + $(top_srcdir)/auto_tests/data/save.tox.big \ + $(top_srcdir)/auto_tests/data/save.tox.little \ $(top_srcdir)/auto_tests/check_compat.h \ $(top_srcdir)/auto_tests/auto_test_support.h diff --git a/auto_tests/TCP_test.c b/auto_tests/TCP_test.c index f478f3c5..c4ea79b0 100644 --- a/auto_tests/TCP_test.c +++ b/auto_tests/TCP_test.c @@ -45,11 +45,11 @@ static uint16_t ports[NUM_PORTS] = {13215, 33445, 25643}; static void test_basic(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); @@ -266,13 +266,14 @@ static void kill_tcp_con(struct sec_TCP_con *con) static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP_con *con, const uint8_t *data, uint16_t length) { - VLA(uint8_t, packet, sizeof(uint16_t) + length + CRYPTO_MAC_SIZE); + const uint16_t packet_size = sizeof(uint16_t) + length + CRYPTO_MAC_SIZE; + VLA(uint8_t, packet, packet_size); uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE); memcpy(packet, &c_length, sizeof(uint16_t)); int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); - if ((unsigned int)len != (SIZEOF_VLA(packet) - sizeof(uint16_t))) { + if ((unsigned int)len != (packet_size - sizeof(uint16_t))) { return -1; } @@ -282,7 +283,7 @@ static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP localhost.ip = get_loopback(); localhost.port = 0; - ck_assert_msg(net_send(con->ns, logger, con->sock, packet, SIZEOF_VLA(packet), &localhost) == SIZEOF_VLA(packet), + ck_assert_msg(net_send(con->ns, logger, con->sock, packet, packet_size, &localhost) == packet_size, "Failed to send a packet."); return 0; } @@ -303,11 +304,11 @@ static int read_packet_sec_tcp(const Logger *logger, struct sec_TCP_con *con, ui static void test_some(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); @@ -498,11 +499,11 @@ static int oob_data_callback(void *object, const uint8_t *public_key, const uint static void test_client(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); Logger *logger = logger_new(); @@ -524,8 +525,9 @@ static void test_client(void) ip_port_tcp_s.ip = get_loopback(); TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr); - do_tcp_connection(logger, mono_time, conn, nullptr); + // TCP sockets might need a moment before they can be written to. c_sleep(50); + do_tcp_connection(logger, mono_time, conn, nullptr); // The connection status should be unconfirmed here because we have finished // sending our data and are awaiting a response. @@ -559,6 +561,7 @@ static void test_client(void) ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); TCP_Client_Connection *conn2 = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key, f2_secret_key, nullptr); + c_sleep(50); // The client should call this function (defined earlier) during the routing process. routing_response_handler(conn, response_callback, (char *)conn + 2); @@ -581,7 +584,7 @@ static void test_client(void) do_tcp_connection(logger, mono_time, conn2, nullptr); c_sleep(50); - uint8_t data[5] = {1, 2, 3, 4, 5}; + const uint8_t data[5] = {1, 2, 3, 4, 5}; memcpy(oob_pubkey, f2_public_key, CRYPTO_PUBLIC_KEY_SIZE); send_oob_packet(logger, conn2, f_public_key, data, 5); send_routing_request(logger, conn, f2_public_key); @@ -632,11 +635,11 @@ static void test_client(void) // Test how the client handles servers that don't respond. static void test_client_invalid(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); @@ -654,7 +657,7 @@ static void test_client_invalid(void) ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.ip = get_loopback(); TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, - self_public_key, f_public_key, f_secret_key, nullptr); + self_public_key, f_public_key, f_secret_key, nullptr); // Run the client's main loop but not the server. mono_time_update(mono_time); @@ -708,14 +711,13 @@ static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t return 0; } - static void test_tcp_connection(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); @@ -824,11 +826,11 @@ static int tcp_oobdata_callback(void *object, const uint8_t *public_key, unsigne static void test_tcp_connection2(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); diff --git a/auto_tests/announce_test.c b/auto_tests/announce_test.c index f6d22a07..c4f080de 100644 --- a/auto_tests/announce_test.c +++ b/auto_tests/announce_test.c @@ -13,7 +13,7 @@ static void test_bucketnum(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); uint8_t key1[CRYPTO_PUBLIC_KEY_SIZE], key2[CRYPTO_PUBLIC_KEY_SIZE]; random_bytes(rng, key1, sizeof(key1)); @@ -50,11 +50,11 @@ static void test_announce_data(void *object, const uint8_t *data, uint16_t lengt static void test_store_data(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); Logger *log = logger_new(); @@ -120,7 +120,6 @@ static void basic_announce_tests(void) test_store_data(); } - int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); diff --git a/auto_tests/auto_test_support.c b/auto_tests/auto_test_support.c index 21346e58..213e7057 100644 --- a/auto_tests/auto_test_support.c +++ b/auto_tests/auto_test_support.c @@ -5,6 +5,8 @@ #include "../testing/misc_tools.h" #include "../toxcore/Messenger.h" #include "../toxcore/mono_time.h" +#include "../toxcore/tox_dispatch.h" +#include "../toxcore/tox_events.h" #include "../toxcore/tox_struct.h" #include "auto_test_support.h" @@ -23,6 +25,7 @@ Run_Auto_Options default_run_auto_options(void) .graph = GRAPH_COMPLETE, .init_autotox = nullptr, .tcp_port = 33188, + .events = true, }; } @@ -131,7 +134,15 @@ void iterate_all_wait(AutoTox *autotoxes, uint32_t tox_count, uint32_t wait) for (uint32_t i = 0; i < tox_count; ++i) { if (autotoxes[i].alive) { - tox_iterate(autotoxes[i].tox, &autotoxes[i]); + if (autotoxes[i].events) { + Tox_Err_Events_Iterate err; + Tox_Events *events = tox_events_iterate(autotoxes[i].tox, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + tox_dispatch_invoke(autotoxes[i].dispatch, events, &autotoxes[i]); + tox_events_free(events); + } else { + tox_iterate(autotoxes[i].tox, &autotoxes[i]); + } autotoxes[i].clock += wait; } } @@ -181,6 +192,7 @@ void kill_autotox(AutoTox *autotox) ck_assert(autotox->alive); fprintf(stderr, "Killing #%u\n", autotox->index); autotox->alive = false; + tox_dispatch_free(autotox->dispatch); tox_kill(autotox->tox); } @@ -202,6 +214,11 @@ void reload(AutoTox *autotox) tox_options_set_savedata_data(options, autotox->save_state, autotox->save_size); autotox->tox = tox_new_log(options, nullptr, &autotox->index); ck_assert(autotox->tox != nullptr); + autotox->dispatch = tox_dispatch_new(nullptr); + ck_assert(autotox->dispatch != nullptr); + if (autotox->events) { + tox_events_init(autotox->tox); + } tox_options_free(options); set_mono_time_callback(autotox); @@ -212,6 +229,7 @@ static void initialise_autotox(struct Tox_Options *options, AutoTox *autotox, ui Run_Auto_Options *autotest_opts) { autotox->index = index; + autotox->events = autotest_opts->events; Tox_Err_New err = TOX_ERR_NEW_OK; @@ -259,6 +277,12 @@ static void initialise_autotox(struct Tox_Options *options, AutoTox *autotox, ui set_mono_time_callback(autotox); + autotox->dispatch = tox_dispatch_new(nullptr); + ck_assert(autotox->dispatch != nullptr); + if (autotox->events) { + tox_events_init(autotox->tox); + } + autotox->alive = true; autotox->save_state = nullptr; @@ -311,7 +335,7 @@ static void initialise_friend_graph(Graph_Type graph, uint32_t num_toxes, AutoTo } } -static void bootstrap_autotoxes(struct Tox_Options *options, uint32_t tox_count, const Run_Auto_Options *autotest_opts, +static void bootstrap_autotoxes(const Tox_Options *options, uint32_t tox_count, const Run_Auto_Options *autotest_opts, AutoTox *autotoxes) { const bool udp_enabled = options != nullptr ? tox_options_get_udp_enabled(options) : true; @@ -339,7 +363,9 @@ static void bootstrap_autotoxes(struct Tox_Options *options, uint32_t tox_count, } } -void run_auto_test(struct Tox_Options *options, uint32_t tox_count, void test(AutoTox *autotoxes), +typedef void autotox_test_cb(AutoTox *autotoxes); + +void run_auto_test(struct Tox_Options *options, uint32_t tox_count, autotox_test_cb *test, uint32_t state_size, Run_Auto_Options *autotest_opts) { printf("initialising %u toxes\n", tox_count); @@ -371,6 +397,7 @@ void run_auto_test(struct Tox_Options *options, uint32_t tox_count, void test(Au test(autotoxes); for (uint32_t i = 0; i < tox_count; ++i) { + tox_dispatch_free(autotoxes[i].dispatch); tox_kill(autotoxes[i].tox); free(autotoxes[i].state); free(autotoxes[i].save_state); @@ -417,7 +444,6 @@ void print_debug_log(Tox *m, Tox_Log_Level level, const char *file, uint32_t lin } } - void print_debug_logger(void *context, Logger_Level level, const char *file, int line, const char *func, const char *message, void *userdata) { print_debug_log(nullptr, (Tox_Log_Level) level, file, (uint32_t) line, func, message, userdata); @@ -455,4 +481,3 @@ Tox *tox_new_log(struct Tox_Options *options, Tox_Err_New *err, void *log_user_d { return tox_new_log_lan(options, err, log_user_data, false); } - diff --git a/auto_tests/auto_test_support.h b/auto_tests/auto_test_support.h index eab121aa..b9132e16 100644 --- a/auto_tests/auto_test_support.h +++ b/auto_tests/auto_test_support.h @@ -7,9 +7,11 @@ #include "../testing/misc_tools.h" #include "../toxcore/Messenger.h" #include "../toxcore/mono_time.h" +#include "../toxcore/tox_dispatch.h" typedef struct AutoTox { Tox *tox; + Tox_Dispatch *dispatch; uint32_t index; uint64_t clock; @@ -17,6 +19,7 @@ typedef struct AutoTox { size_t save_size; uint8_t *save_state; bool alive; + bool events; void *state; } AutoTox; @@ -42,6 +45,7 @@ typedef struct Run_Auto_Options { Graph_Type graph; void (*init_autotox)(AutoTox *autotox, uint32_t n); uint16_t tcp_port; + bool events; } Run_Auto_Options; Run_Auto_Options default_run_auto_options(void); @@ -57,7 +61,7 @@ void print_debug_log(Tox *m, Tox_Log_Level level, const char *file, uint32_t lin // Use this function when setting the log callback on a Logger object void print_debug_logger(void *context, Logger_Level level, const char *file, int line, - const char *func, const char *message, void *userdata); + const char *func, const char *message, void *userdata); Tox *tox_new_log(struct Tox_Options *options, Tox_Err_New *err, void *log_user_data); Tox *tox_new_log_lan(struct Tox_Options *options, Tox_Err_New *err, void *log_user_data, bool lan_discovery); diff --git a/auto_tests/conference_av_test.c b/auto_tests/conference_av_test.c index c366be42..39383bd7 100644 --- a/auto_tests/conference_av_test.c +++ b/auto_tests/conference_av_test.c @@ -23,10 +23,11 @@ typedef struct State { } State; static void handle_self_connection_status( - Tox *tox, Tox_Connection connection_status, void *user_data) + const Tox_Event_Self_Connection_Status *event, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; + const Tox_Connection connection_status = tox_event_self_connection_status_get_connection_status(event); if (connection_status != TOX_CONNECTION_NONE) { printf("tox #%u: is now connected\n", autotox->index); } else { @@ -35,10 +36,13 @@ static void handle_self_connection_status( } static void handle_friend_connection_status( - Tox *tox, uint32_t friendnumber, Tox_Connection connection_status, void *user_data) + const Tox_Event_Friend_Connection_Status *event, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; + const uint32_t friendnumber = tox_event_friend_connection_status_get_friend_number(event); + const Tox_Connection connection_status = tox_event_friend_connection_status_get_connection_status(event); + if (connection_status != TOX_CONNECTION_NONE) { printf("tox #%u: is now connected to friend %u\n", autotox->index, friendnumber); } else { @@ -70,28 +74,33 @@ static void audio_callback(void *tox, uint32_t groupnumber, uint32_t peernumber, } static void handle_conference_invite( - Tox *tox, uint32_t friendnumber, Tox_Conference_Type type, - const uint8_t *data, size_t length, void *user_data) + const Tox_Event_Conference_Invite *event, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; + + const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event); + const Tox_Conference_Type type = tox_event_conference_invite_get_type(event); + const uint8_t *cookie = tox_event_conference_invite_get_cookie(event); + const size_t length = tox_event_conference_invite_get_cookie_length(event); + ck_assert_msg(type == TOX_CONFERENCE_TYPE_AV, "tox #%u: wrong conference type: %d", autotox->index, type); - ck_assert_msg(toxav_join_av_groupchat(tox, friendnumber, data, length, audio_callback, user_data) == 0, + ck_assert_msg(toxav_join_av_groupchat(autotox->tox, friend_number, cookie, length, audio_callback, user_data) == 0, "tox #%u: failed to join group", autotox->index); } static void handle_conference_connected( - Tox *tox, uint32_t conference_number, void *user_data) + const Tox_Event_Conference_Connected *event, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; - if (state->invited_next || tox_self_get_friend_list_size(tox) <= 1) { + if (state->invited_next || tox_self_get_friend_list_size(autotox->tox) <= 1) { return; } Tox_Err_Conference_Invite err; - tox_conference_invite(tox, 1, 0, &err); + tox_conference_invite(autotox->tox, 1, 0, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox #%u failed to invite next friend: err = %d", autotox->index, err); printf("tox #%u: invited next friend\n", autotox->index); @@ -99,7 +108,7 @@ static void handle_conference_connected( } static bool toxes_are_disconnected_from_group(uint32_t tox_count, AutoTox *autotoxes, - bool *disconnected) + const bool *disconnected) { uint32_t num_disconnected = 0; @@ -138,7 +147,10 @@ static void disconnect_toxes(uint32_t tox_count, AutoTox *autotoxes, do { for (uint32_t i = 0; i < tox_count; ++i) { if (!disconnect_now[i]) { - tox_iterate(autotoxes[i].tox, &autotoxes[i]); + Tox_Err_Events_Iterate err; + Tox_Events *events = tox_events_iterate(autotoxes[i].tox, true, &err); + tox_dispatch_invoke(autotoxes[i].dispatch, events, &autotoxes[i]); + tox_events_free(events); autotoxes[i].clock += 1000; } } @@ -165,7 +177,7 @@ static bool all_connected_to_group(uint32_t tox_count, AutoTox *autotoxes) * returns a random index at which a list of booleans is false * (some such index is required to exist) */ -static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t length) +static uint32_t random_false_index(const Random *rng, const bool *list, const uint32_t length) { uint32_t index; @@ -185,7 +197,7 @@ static bool all_got_audio(AutoTox *autotoxes, const bool *disabled) } for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) { - State *state = (State *)autotoxes[i].state; + const State *state = (const State *)autotoxes[i].state; if (disabled[i] ^ (state->received_audio_num != NUM_AV_GROUP_TOX - num_disabled - 1)) { @@ -291,7 +303,7 @@ static void do_audio(AutoTox *autotoxes, uint32_t iterations) static void run_conference_tests(AutoTox *autotoxes) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); bool disabled[NUM_AV_GROUP_TOX] = {0}; @@ -402,10 +414,10 @@ static void test_groupav(AutoTox *autotoxes) const time_t test_start_time = time(nullptr); for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) { - tox_callback_self_connection_status(autotoxes[i].tox, &handle_self_connection_status); - tox_callback_friend_connection_status(autotoxes[i].tox, &handle_friend_connection_status); - tox_callback_conference_invite(autotoxes[i].tox, &handle_conference_invite); - tox_callback_conference_connected(autotoxes[i].tox, &handle_conference_connected); + tox_events_callback_self_connection_status(autotoxes[i].dispatch, handle_self_connection_status); + tox_events_callback_friend_connection_status(autotoxes[i].dispatch, handle_friend_connection_status); + tox_events_callback_conference_invite(autotoxes[i].dispatch, handle_conference_invite); + tox_events_callback_conference_connected(autotoxes[i].dispatch, handle_conference_connected); } ck_assert_msg(toxav_add_av_groupchat(autotoxes[0].tox, audio_callback, &autotoxes[0]) != UINT32_MAX, @@ -414,7 +426,6 @@ static void test_groupav(AutoTox *autotoxes) ck_assert_msg(tox_conference_invite(autotoxes[0].tox, 0, 0, nullptr) != 0, "failed to invite friend"); ((State *)autotoxes[0].state)->invited_next = true; - printf("waiting for invitations to be made\n"); uint32_t invited_count = 0; diff --git a/auto_tests/conference_double_invite_test.c b/auto_tests/conference_double_invite_test.c index 201dd8f5..06d880a2 100644 --- a/auto_tests/conference_double_invite_test.c +++ b/auto_tests/conference_double_invite_test.c @@ -12,12 +12,16 @@ typedef struct State { #include "auto_test_support.h" static void handle_conference_invite( - Tox *tox, uint32_t friend_number, Tox_Conference_Type type, - const uint8_t *cookie, size_t length, void *user_data) + const Tox_Event_Conference_Invite *event, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; + const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event); + const Tox_Conference_Type type = tox_event_conference_invite_get_type(event); + const uint8_t *cookie = tox_event_conference_invite_get_cookie(event); + const size_t length = tox_event_conference_invite_get_cookie_length(event); + fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n", autotox->index, friend_number, type, (unsigned)length); fprintf(stderr, "tox%u joining conference\n", autotox->index); @@ -26,7 +30,7 @@ static void handle_conference_invite( if (friend_number != -1) { Tox_Err_Conference_Join err; - state->conference = tox_conference_join(tox, friend_number, cookie, length, &err); + state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "attempting to join the conference returned with an error: %d", err); fprintf(stderr, "tox%u joined conference %u\n", autotox->index, state->conference); @@ -37,8 +41,8 @@ static void handle_conference_invite( static void conference_double_invite_test(AutoTox *autotoxes) { // Conference callbacks. - tox_callback_conference_invite(autotoxes[0].tox, handle_conference_invite); - tox_callback_conference_invite(autotoxes[1].tox, handle_conference_invite); + tox_events_callback_conference_invite(autotoxes[0].dispatch, handle_conference_invite); + tox_events_callback_conference_invite(autotoxes[1].dispatch, handle_conference_invite); State *state[2]; state[0] = (State *)autotoxes[0].state; diff --git a/auto_tests/conference_invite_merge_test.c b/auto_tests/conference_invite_merge_test.c index c02c59b4..d0af332d 100644 --- a/auto_tests/conference_invite_merge_test.c +++ b/auto_tests/conference_invite_merge_test.c @@ -12,15 +12,18 @@ typedef struct State { #include "auto_test_support.h" static void handle_conference_invite( - Tox *tox, uint32_t friend_number, Tox_Conference_Type type, - const uint8_t *cookie, size_t length, void *user_data) + const Tox_Event_Conference_Invite *event, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; + const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event); + const uint8_t *cookie = tox_event_conference_invite_get_cookie(event); + const size_t length = tox_event_conference_invite_get_cookie_length(event); + if (friend_number != -1) { Tox_Err_Conference_Join err; - state->conference = tox_conference_join(tox, friend_number, cookie, length, &err); + state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "attempting to join the conference returned with an error: %d", err); fprintf(stderr, "#%u accepted invite to conference %u\n", autotox->index, state->conference); @@ -28,7 +31,7 @@ static void handle_conference_invite( } static void handle_conference_connected( - Tox *tox, uint32_t conference_number, void *user_data) + const Tox_Event_Conference_Connected *event, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; @@ -37,7 +40,7 @@ static void handle_conference_connected( state->connected = true; } -static void wait_connected(AutoTox *autotoxes, AutoTox *autotox, uint32_t friendnumber) +static void wait_connected(AutoTox *autotoxes, const AutoTox *autotox, uint32_t friendnumber) { do { iterate_all_wait(autotoxes, NUM_INVITE_MERGE_TOX, ITERATION_INTERVAL); @@ -95,8 +98,8 @@ static void conference_invite_merge_test(AutoTox *autotoxes) // components will cause a split group to merge for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) { - tox_callback_conference_invite(autotoxes[i].tox, &handle_conference_invite); - tox_callback_conference_connected(autotoxes[i].tox, &handle_conference_connected); + tox_events_callback_conference_invite(autotoxes[i].dispatch, handle_conference_invite); + tox_events_callback_conference_connected(autotoxes[i].dispatch, handle_conference_connected); } State *state2 = (State *)autotoxes[2].state; diff --git a/auto_tests/conference_peer_nick_test.c b/auto_tests/conference_peer_nick_test.c index d1d12979..2ebf8d48 100644 --- a/auto_tests/conference_peer_nick_test.c +++ b/auto_tests/conference_peer_nick_test.c @@ -13,34 +13,39 @@ typedef struct State { #include "auto_test_support.h" static void handle_conference_invite( - Tox *tox, uint32_t friend_number, Tox_Conference_Type type, - const uint8_t *cookie, size_t length, void *user_data) + const Tox_Event_Conference_Invite *event, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; + const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event); + const Tox_Conference_Type type = tox_event_conference_invite_get_type(event); + const uint8_t *cookie = tox_event_conference_invite_get_cookie(event); + const size_t length = tox_event_conference_invite_get_cookie_length(event); + fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n", autotox->index, friend_number, type, (unsigned)length); fprintf(stderr, "tox%u joining conference\n", autotox->index); Tox_Err_Conference_Join err; - state->conference = tox_conference_join(tox, friend_number, cookie, length, &err); + state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "attempting to join the conference returned with an error: %d", err); fprintf(stderr, "tox%u joined conference %u\n", autotox->index, state->conference); state->joined = true; } -static void handle_peer_list_changed(Tox *tox, uint32_t conference_number, void *user_data) +static void handle_peer_list_changed(const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; + const uint32_t conference_number = tox_event_conference_peer_list_changed_get_conference_number(event); fprintf(stderr, "handle_peer_list_changed(#%u, %u, _)\n", autotox->index, conference_number); Tox_Err_Conference_Peer_Query err; - uint32_t const count = tox_conference_peer_count(tox, conference_number, &err); + uint32_t const count = tox_conference_peer_count(autotox->tox, conference_number, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_PEER_QUERY_OK, "failed to get conference peer count: err = %d", err); printf("tox%u has %u peers\n", autotox->index, count); @@ -75,10 +80,10 @@ static void rebuild_peer_list(Tox *tox) static void conference_peer_nick_test(AutoTox *autotoxes) { // Conference callbacks. - tox_callback_conference_invite(autotoxes[0].tox, handle_conference_invite); - tox_callback_conference_invite(autotoxes[1].tox, handle_conference_invite); - tox_callback_conference_peer_list_changed(autotoxes[0].tox, handle_peer_list_changed); - tox_callback_conference_peer_list_changed(autotoxes[1].tox, handle_peer_list_changed); + tox_events_callback_conference_invite(autotoxes[0].dispatch, handle_conference_invite); + tox_events_callback_conference_invite(autotoxes[1].dispatch, handle_conference_invite); + tox_events_callback_conference_peer_list_changed(autotoxes[0].dispatch, handle_peer_list_changed); + tox_events_callback_conference_peer_list_changed(autotoxes[1].dispatch, handle_peer_list_changed); // Set the names of the toxes. tox_self_set_name(autotoxes[0].tox, (const uint8_t *)"test-tox-0", 10, nullptr); diff --git a/auto_tests/conference_simple_test.c b/auto_tests/conference_simple_test.c index 2c445d4b..8cdac7db 100644 --- a/auto_tests/conference_simple_test.c +++ b/auto_tests/conference_simple_test.c @@ -3,11 +3,14 @@ #include "../testing/misc_tools.h" #include "../toxcore/tox.h" +#include "../toxcore/tox_dispatch.h" +#include "../toxcore/tox_events.h" #include "auto_test_support.h" #include "check_compat.h" typedef struct State { uint32_t id; + Tox *tox; bool self_online; bool friend_online; bool invited_next; @@ -20,46 +23,57 @@ typedef struct State { uint32_t peers; } State; -static void handle_self_connection_status(Tox *tox, Tox_Connection connection_status, void *user_data) +static void handle_self_connection_status(const Tox_Event_Self_Connection_Status *event, void *user_data) { State *state = (State *)user_data; + const Tox_Connection connection_status = tox_event_self_connection_status_get_connection_status(event); fprintf(stderr, "self_connection_status(#%u, %d, _)\n", state->id, connection_status); state->self_online = connection_status != TOX_CONNECTION_NONE; } -static void handle_friend_connection_status(Tox *tox, uint32_t friend_number, Tox_Connection connection_status, +static void handle_friend_connection_status(const Tox_Event_Friend_Connection_Status *event, void *user_data) { State *state = (State *)user_data; + const uint32_t friend_number = tox_event_friend_connection_status_get_friend_number(event); + const Tox_Connection connection_status = tox_event_friend_connection_status_get_connection_status(event); fprintf(stderr, "handle_friend_connection_status(#%u, %u, %d, _)\n", state->id, friend_number, connection_status); state->friend_online = connection_status != TOX_CONNECTION_NONE; } -static void handle_conference_invite(Tox *tox, uint32_t friend_number, Tox_Conference_Type type, const uint8_t *cookie, - size_t length, void *user_data) +static void handle_conference_invite(const Tox_Event_Conference_Invite *event, void *user_data) { State *state = (State *)user_data; + const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event); + const Tox_Conference_Type type = tox_event_conference_invite_get_type(event); + const uint8_t *cookie = tox_event_conference_invite_get_cookie(event); + const size_t length = tox_event_conference_invite_get_cookie_length(event); fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n", state->id, friend_number, type, (unsigned)length); fprintf(stderr, "tox%u joining conference\n", state->id); { Tox_Err_Conference_Join err; - state->conference = tox_conference_join(tox, friend_number, cookie, length, &err); + state->conference = tox_conference_join(state->tox, friend_number, cookie, length, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "failed to join a conference: err = %d", err); fprintf(stderr, "tox%u Joined conference %u\n", state->id, state->conference); state->joined = true; } } -static void handle_conference_message(Tox *tox, uint32_t conference_number, uint32_t peer_number, - Tox_Message_Type type, const uint8_t *message, size_t length, void *user_data) +static void handle_conference_message(const Tox_Event_Conference_Message *event, void *user_data) { State *state = (State *)user_data; + const uint32_t conference_number = tox_event_conference_message_get_conference_number(event); + const uint32_t peer_number = tox_event_conference_message_get_peer_number(event); + const Tox_Message_Type type = tox_event_conference_message_get_type(event); + const uint8_t *message = tox_event_conference_message_get_message(event); + const size_t length = tox_event_conference_message_get_message_length(event); + fprintf(stderr, "handle_conference_message(#%u, %u, %u, %d, uint8_t[%u], _)\n", state->id, conference_number, peer_number, type, (unsigned)length); @@ -67,15 +81,16 @@ static void handle_conference_message(Tox *tox, uint32_t conference_number, uint state->received = true; } -static void handle_conference_peer_list_changed(Tox *tox, uint32_t conference_number, void *user_data) +static void handle_conference_peer_list_changed(const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) { State *state = (State *)user_data; + const uint32_t conference_number = tox_event_conference_peer_list_changed_get_conference_number(event); fprintf(stderr, "handle_conference_peer_list_changed(#%u, %u, _)\n", state->id, conference_number); Tox_Err_Conference_Peer_Query err; - uint32_t count = tox_conference_peer_count(tox, conference_number, &err); + uint32_t count = tox_conference_peer_count(state->tox, conference_number, &err); if (err != TOX_ERR_CONFERENCE_PEER_QUERY_OK) { fprintf(stderr, "ERROR: %d\n", err); @@ -86,14 +101,14 @@ static void handle_conference_peer_list_changed(Tox *tox, uint32_t conference_nu state->peers = count; } -static void handle_conference_connected(Tox *tox, uint32_t conference_number, void *user_data) +static void handle_conference_connected(const Tox_Event_Conference_Connected *event, void *user_data) { State *state = (State *)user_data; // We're tox2, so now we invite tox3. if (state->id == 2 && !state->invited_next) { Tox_Err_Conference_Invite err; - tox_conference_invite(tox, 1, state->conference, &err); + tox_conference_invite(state->tox, 1, state->conference, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox2 failed to invite tox3: err = %d", err); state->invited_next = true; @@ -101,6 +116,27 @@ static void handle_conference_connected(Tox *tox, uint32_t conference_number, vo } } +static void iterate_one( + Tox *tox, State *state, const Tox_Dispatch *dispatch) +{ + Tox_Err_Events_Iterate err; + Tox_Events *events = tox_events_iterate(tox, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + tox_dispatch_invoke(dispatch, events, state); + tox_events_free(events); +} + +static void iterate3_wait( + State *state1, State *state2, State *state3, + const Tox_Dispatch *dispatch, int interval) +{ + iterate_one(state1->tox, state1, dispatch); + iterate_one(state2->tox, state2, dispatch); + iterate_one(state3->tox, state3, dispatch); + + c_sleep(interval); +} + int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); @@ -110,64 +146,51 @@ int main(void) State state3 = {3}; // Create toxes. - Tox *tox1 = tox_new_log(nullptr, nullptr, &state1.id); - Tox *tox2 = tox_new_log(nullptr, nullptr, &state2.id); - Tox *tox3 = tox_new_log(nullptr, nullptr, &state3.id); + state1.tox = tox_new_log(nullptr, nullptr, &state1.id); + state2.tox = tox_new_log(nullptr, nullptr, &state2.id); + state3.tox = tox_new_log(nullptr, nullptr, &state3.id); + + tox_events_init(state1.tox); + tox_events_init(state2.tox); + tox_events_init(state3.tox); // tox1 <-> tox2, tox2 <-> tox3 uint8_t key[TOX_PUBLIC_KEY_SIZE]; - tox_self_get_public_key(tox2, key); - tox_friend_add_norequest(tox1, key, nullptr); // tox1 -> tox2 - tox_self_get_public_key(tox1, key); - tox_friend_add_norequest(tox2, key, nullptr); // tox2 -> tox1 - tox_self_get_public_key(tox3, key); - tox_friend_add_norequest(tox2, key, nullptr); // tox2 -> tox3 - tox_self_get_public_key(tox2, key); - tox_friend_add_norequest(tox3, key, nullptr); // tox3 -> tox2 + tox_self_get_public_key(state2.tox, key); + tox_friend_add_norequest(state1.tox, key, nullptr); // tox1 -> tox2 + tox_self_get_public_key(state1.tox, key); + tox_friend_add_norequest(state2.tox, key, nullptr); // tox2 -> tox1 + tox_self_get_public_key(state3.tox, key); + tox_friend_add_norequest(state2.tox, key, nullptr); // tox2 -> tox3 + tox_self_get_public_key(state2.tox, key); + tox_friend_add_norequest(state3.tox, key, nullptr); // tox3 -> tox2 printf("bootstrapping tox2 and tox3 off tox1\n"); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; - tox_self_get_dht_id(tox1, dht_key); - const uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr); + tox_self_get_dht_id(state1.tox, dht_key); + const uint16_t dht_port = tox_self_get_udp_port(state1.tox, nullptr); - tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr); - tox_bootstrap(tox3, "localhost", dht_port, dht_key, nullptr); + tox_bootstrap(state2.tox, "localhost", dht_port, dht_key, nullptr); + tox_bootstrap(state3.tox, "localhost", dht_port, dht_key, nullptr); + + Tox_Dispatch *dispatch = tox_dispatch_new(nullptr); + ck_assert(dispatch != nullptr); // Connection callbacks. - tox_callback_self_connection_status(tox1, handle_self_connection_status); - tox_callback_self_connection_status(tox2, handle_self_connection_status); - tox_callback_self_connection_status(tox3, handle_self_connection_status); - - tox_callback_friend_connection_status(tox1, handle_friend_connection_status); - tox_callback_friend_connection_status(tox2, handle_friend_connection_status); - tox_callback_friend_connection_status(tox3, handle_friend_connection_status); + tox_events_callback_self_connection_status(dispatch, handle_self_connection_status); + tox_events_callback_friend_connection_status(dispatch, handle_friend_connection_status); // Conference callbacks. - tox_callback_conference_invite(tox1, handle_conference_invite); - tox_callback_conference_invite(tox2, handle_conference_invite); - tox_callback_conference_invite(tox3, handle_conference_invite); - - tox_callback_conference_connected(tox1, handle_conference_connected); - tox_callback_conference_connected(tox2, handle_conference_connected); - tox_callback_conference_connected(tox3, handle_conference_connected); - - tox_callback_conference_message(tox1, handle_conference_message); - tox_callback_conference_message(tox2, handle_conference_message); - tox_callback_conference_message(tox3, handle_conference_message); - - tox_callback_conference_peer_list_changed(tox1, handle_conference_peer_list_changed); - tox_callback_conference_peer_list_changed(tox2, handle_conference_peer_list_changed); - tox_callback_conference_peer_list_changed(tox3, handle_conference_peer_list_changed); + tox_events_callback_conference_invite(dispatch, handle_conference_invite); + tox_events_callback_conference_connected(dispatch, handle_conference_connected); + tox_events_callback_conference_message(dispatch, handle_conference_message); + tox_events_callback_conference_peer_list_changed(dispatch, handle_conference_peer_list_changed); // Wait for self connection. fprintf(stderr, "Waiting for toxes to come online\n"); do { - tox_iterate(tox1, &state1); - tox_iterate(tox2, &state2); - tox_iterate(tox3, &state3); - - c_sleep(100); + iterate3_wait(&state1, &state2, &state3, dispatch, 100); } while (!state1.self_online || !state2.self_online || !state3.self_online); fprintf(stderr, "Toxes are online\n"); @@ -176,11 +199,7 @@ int main(void) fprintf(stderr, "Waiting for friends to connect\n"); do { - tox_iterate(tox1, &state1); - tox_iterate(tox2, &state2); - tox_iterate(tox3, &state3); - - c_sleep(100); + iterate3_wait(&state1, &state2, &state3, dispatch, 100); } while (!state1.friend_online || !state2.friend_online || !state3.friend_online); fprintf(stderr, "Friends are connected\n"); @@ -188,7 +207,7 @@ int main(void) { // Create new conference, tox1 is the founder. Tox_Err_Conference_New err; - state1.conference = tox_conference_new(tox1, &err); + state1.conference = tox_conference_new(state1.tox, &err); state1.joined = true; ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK, "failed to create a conference: err = %d", err); fprintf(stderr, "Created conference: id = %u\n", state1.conference); @@ -197,7 +216,7 @@ int main(void) { // Invite friend. Tox_Err_Conference_Invite err; - tox_conference_invite(tox1, 0, state1.conference, &err); + tox_conference_invite(state1.tox, 0, state1.conference, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "failed to invite a friend: err = %d", err); state1.invited_next = true; fprintf(stderr, "tox1 invited tox2\n"); @@ -206,11 +225,7 @@ int main(void) fprintf(stderr, "Waiting for invitation to arrive\n"); do { - tox_iterate(tox1, &state1); - tox_iterate(tox2, &state2); - tox_iterate(tox3, &state3); - - c_sleep(100); + iterate3_wait(&state1, &state2, &state3, dispatch, 100); } while (!state1.joined || !state2.joined || !state3.joined); fprintf(stderr, "Invitations accepted\n"); @@ -218,11 +233,7 @@ int main(void) fprintf(stderr, "Waiting for peers to come online\n"); do { - tox_iterate(tox1, &state1); - tox_iterate(tox2, &state2); - tox_iterate(tox3, &state3); - - c_sleep(100); + iterate3_wait(&state1, &state2, &state3, dispatch, 100); } while (state1.peers == 0 || state2.peers == 0 || state3.peers == 0); fprintf(stderr, "All peers are online\n"); @@ -230,7 +241,7 @@ int main(void) { fprintf(stderr, "tox1 sends a message to the group: \"hello!\"\n"); Tox_Err_Conference_Send_Message err; - tox_conference_send_message(tox1, state1.conference, TOX_MESSAGE_TYPE_NORMAL, + tox_conference_send_message(state1.tox, state1.conference, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)"hello!", 7, &err); if (err != TOX_ERR_CONFERENCE_SEND_MESSAGE_OK) { @@ -242,18 +253,16 @@ int main(void) fprintf(stderr, "Waiting for messages to arrive\n"); do { - tox_iterate(tox1, &state1); - tox_iterate(tox2, &state2); - tox_iterate(tox3, &state3); - + iterate3_wait(&state1, &state2, &state3, dispatch, 100); c_sleep(100); } while (!state2.received || !state3.received); fprintf(stderr, "Messages received. Test complete.\n"); - tox_kill(tox3); - tox_kill(tox2); - tox_kill(tox1); + tox_dispatch_free(dispatch); + tox_kill(state3.tox); + tox_kill(state2.tox); + tox_kill(state1.tox); return 0; } diff --git a/auto_tests/conference_test.c b/auto_tests/conference_test.c index 66edddd8..af1cd288 100644 --- a/auto_tests/conference_test.c +++ b/auto_tests/conference_test.c @@ -56,13 +56,13 @@ static void handle_conference_invite( ck_assert_msg(type == TOX_CONFERENCE_TYPE_TEXT, "tox #%u: wrong conference type: %d", autotox->index, type); Tox_Err_Conference_Join err; - uint32_t g_num = tox_conference_join(tox, friendnumber, data, length, &err); + uint32_t g_num = tox_conference_join(autotox->tox, friendnumber, data, length, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "tox #%u: error joining group: %d", autotox->index, err); ck_assert_msg(g_num == 0, "tox #%u: group number was not 0", autotox->index); // Try joining again. We should only be allowed to join once. - tox_conference_join(tox, friendnumber, data, length, &err); + tox_conference_join(autotox->tox, friendnumber, data, length, &err); ck_assert_msg(err != TOX_ERR_CONFERENCE_JOIN_OK, "tox #%u: joining groupchat twice should be impossible.", autotox->index); } @@ -73,12 +73,12 @@ static void handle_conference_connected( const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; - if (state->invited_next || tox_self_get_friend_list_size(tox) <= 1) { + if (state->invited_next || tox_self_get_friend_list_size(autotox->tox) <= 1) { return; } Tox_Err_Conference_Invite err; - tox_conference_invite(tox, 1, 0, &err); + tox_conference_invite(autotox->tox, 1, 0, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox #%u failed to invite next friend: err = %d", autotox->index, err); printf("tox #%u: invited next friend\n", autotox->index); @@ -97,7 +97,7 @@ static void handle_conference_message( } static bool toxes_are_disconnected_from_group(uint32_t tox_count, AutoTox *autotoxes, - bool *disconnected) + const bool *disconnected) { uint32_t num_disconnected = 0; @@ -174,12 +174,11 @@ static bool names_propagated(uint32_t tox_count, AutoTox *autotoxes) return true; } - /** * returns a random index at which a list of booleans is false * (some such index is required to exist) */ -static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t length) +static uint32_t random_false_index(const Random *rng, const bool *list, const uint32_t length) { uint32_t index; @@ -192,7 +191,7 @@ static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t static void run_conference_tests(AutoTox *autotoxes) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); /* disabling name change propagation check for now, as it occasionally * fails due to disconnections too short to trigger freezing */ @@ -357,7 +356,6 @@ static void test_many_group(AutoTox *autotoxes) nullptr) != 0, "failed to set group title"); - printf("waiting for invitations to be made\n"); uint32_t invited_count = 0; @@ -435,6 +433,7 @@ int main(void) Run_Auto_Options options = default_run_auto_options(); options.graph = GRAPH_LINEAR; + options.events = false; run_auto_test(nullptr, NUM_GROUP_TOX, test_many_group, sizeof(State), &options); return 0; diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 4c4f3a6d..83f8c525 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -125,7 +125,7 @@ static void test_fast_known(void) static void test_endtoend(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); // Test 100 random messages and keypairs @@ -192,7 +192,7 @@ static void test_endtoend(void) static void test_large_data(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); uint8_t k[CRYPTO_SHARED_KEY_SIZE]; uint8_t n[CRYPTO_NONCE_SIZE]; @@ -236,7 +236,7 @@ static void test_large_data(void) static void test_large_data_symmetric(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE]; @@ -271,10 +271,10 @@ static void test_large_data_symmetric(void) static void test_very_large_data(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - uint8_t nonce[CRYPTO_NONCE_SIZE] = {0}; + const uint8_t nonce[CRYPTO_NONCE_SIZE] = {0}; uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t sk[CRYPTO_SECRET_KEY_SIZE]; crypto_new_keypair(rng, pk, sk); @@ -316,7 +316,7 @@ static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num) static void test_increment_nonce(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); uint8_t n[CRYPTO_NONCE_SIZE]; diff --git a/auto_tests/data/save.tox b/auto_tests/data/save.tox.big similarity index 54% rename from auto_tests/data/save.tox rename to auto_tests/data/save.tox.big index 03430c8e..dc5fc418 100644 Binary files a/auto_tests/data/save.tox and b/auto_tests/data/save.tox.big differ diff --git a/auto_tests/data/save.tox.little b/auto_tests/data/save.tox.little new file mode 100644 index 00000000..e5e0de36 Binary files /dev/null and b/auto_tests/data/save.tox.little differ diff --git a/auto_tests/dht_getnodes_api_test.c b/auto_tests/dht_getnodes_api_test.c index 3b54f1cc..3a118088 100644 --- a/auto_tests/dht_getnodes_api_test.c +++ b/auto_tests/dht_getnodes_api_test.c @@ -72,12 +72,16 @@ static bool all_nodes_crawled(const AutoTox *autotoxes, uint32_t num_toxes, uint return true; } -static void getnodes_response_cb(Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port, void *user_data) +static void getnodes_response_cb(const Tox_Event_Dht_Get_Nodes_Response *event, void *user_data) { ck_assert(user_data != nullptr); - AutoTox *autotoxes = (AutoTox *)user_data; - State *state = (State *)autotoxes->state; + 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); if (node_crawled(state->nodes, state->num_nodes, public_key)) { return; @@ -97,7 +101,7 @@ static void getnodes_response_cb(Tox *tox, const uint8_t *public_key, const char // ask new node to give us their close nodes to every public key for (size_t i = 0; i < NUM_TOXES; ++i) { - tox_dht_get_nodes(tox, public_key, ip, port, state->public_key_list[i], nullptr); + tox_dht_get_nodes(autotox->tox, public_key, ip, port, state->public_key_list[i], nullptr); } } @@ -121,13 +125,12 @@ 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_callback_dht_get_nodes_response(autotoxes[i].tox, getnodes_response_cb); + tox_events_callback_dht_get_nodes_response(autotoxes[i].dispatch, getnodes_response_cb); printf("Peer %zu dht closenode count total/announce-capable: %d/%d\n", - i, - tox_dht_get_num_closelist(autotoxes[i].tox), - tox_dht_get_num_closelist_announce_capable(autotoxes[i].tox) - ); + i, + tox_dht_get_num_closelist(autotoxes[i].tox), + tox_dht_get_num_closelist_announce_capable(autotoxes[i].tox)); } while (!all_nodes_crawled(autotoxes, NUM_TOXES, public_key_list)) { diff --git a/auto_tests/encryptsave_test.c b/auto_tests/encryptsave_test.c index 2a3b5fbe..e433e410 100644 --- a/auto_tests/encryptsave_test.c +++ b/auto_tests/encryptsave_test.c @@ -168,7 +168,7 @@ static void test_keys(void) ck_assert(encrypted2a != nullptr); uint8_t *in_plaintext2a = (uint8_t *)malloc(plaintext_length2a); ck_assert(in_plaintext2a != nullptr); - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); random_bytes(rng, in_plaintext2a, plaintext_length2a); ret = tox_pass_encrypt(in_plaintext2a, plaintext_length2a, key_char, 12, encrypted2a, &encerr); @@ -184,7 +184,6 @@ static void test_keys(void) free(in_plaintext2a); free(out_plaintext2a); - uint8_t encrypted2[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH]; ret = tox_pass_encrypt(string, 44, key_char, 12, encrypted2, &encerr); ck_assert_msg(ret, "generic failure 3: %d", encerr); diff --git a/auto_tests/file_streaming_test.c b/auto_tests/file_streaming_test.c index fdb3d2cb..fa4f210a 100644 --- a/auto_tests/file_streaming_test.c +++ b/auto_tests/file_streaming_test.c @@ -53,7 +53,7 @@ static void tox_file_receive(Tox *tox, uint32_t friend_number, uint32_t file_num ck_assert_msg(memcmp(file_id, file_cmp_id, TOX_FILE_ID_LENGTH) == 0, "bad file_id"); - uint8_t empty[TOX_FILE_ID_LENGTH] = {0}; + const uint8_t empty[TOX_FILE_ID_LENGTH] = {0}; ck_assert_msg(memcmp(empty, file_cmp_id, TOX_FILE_ID_LENGTH) != 0, "empty file_id"); @@ -126,7 +126,6 @@ static void tox_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t fi Tox_Err_File_Send_Chunk error; tox_file_send_chunk(tox, friend_number, file_number, position, f_data, length, &error); - ck_assert_msg(error == TOX_ERR_FILE_SEND_CHUNK_OK, "could not send chunk, error num=%d pos=%d len=%d", (int)error, (int)position, (int)length); @@ -134,7 +133,6 @@ static void tox_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t fi sending_pos += length; } - static uint8_t num; static bool file_recv; static void write_file(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, const uint8_t *data, @@ -209,7 +207,6 @@ static void file_transfer_test(void) file_accepted = file_size = sendf_ok = size_recv = 0; file_recv = 0; max_sending = UINT64_MAX; - uint64_t totalf_size = 100 * 1024 * 1024; printf("Starting file streaming transfer test.\n"); @@ -224,10 +221,10 @@ static void file_transfer_test(void) tox_callback_file_chunk_request(tox2, tox_file_chunk_request); tox_callback_file_recv_control(tox3, file_print_control); tox_callback_file_recv(tox3, tox_file_receive); - totalf_size = UINT64_MAX; + const uint64_t totalf_size = UINT64_MAX; Tox_File_Number fnum = tox_file_send( - tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr, - (const uint8_t *)"Gentoo.exe", sizeof("Gentoo.exe"), nullptr); + tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr, + (const uint8_t *)"Gentoo.exe", sizeof("Gentoo.exe"), nullptr); ck_assert_msg(fnum != UINT32_MAX, "tox_new_file_sender fail"); Tox_Err_File_Get gfierr; diff --git a/auto_tests/file_transfer_test.c b/auto_tests/file_transfer_test.c index 522717fa..a443b027 100644 --- a/auto_tests/file_transfer_test.c +++ b/auto_tests/file_transfer_test.c @@ -26,10 +26,16 @@ #define TOX_LOCALHOST "127.0.0.1" #endif -static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) +static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata) { + Tox *tox = (Tox *)userdata; + + const uint8_t *public_key = tox_event_friend_request_get_public_key(event); + const uint8_t *data = tox_event_friend_request_get_message(event); + const size_t length = tox_event_friend_request_get_message_length(event); + if (length == 7 && memcmp("Gentoo", data, 7) == 0) { - tox_friend_add_norequest(m, public_key, nullptr); + tox_friend_add_norequest(tox, public_key, nullptr); } } @@ -39,9 +45,17 @@ static uint64_t sending_pos; static uint8_t file_cmp_id[TOX_FILE_ID_LENGTH]; static uint32_t file_accepted; static uint64_t file_size; -static void tox_file_receive(Tox *tox, uint32_t friend_number, uint32_t file_number, uint32_t kind, uint64_t filesize, - const uint8_t *filename, size_t filename_length, void *userdata) +static void tox_file_receive(const Tox_Event_File_Recv *event, void *userdata) { + Tox *state_tox = (Tox *)userdata; + + const uint32_t friend_number = tox_event_file_recv_get_friend_number(event); + const uint32_t file_number = tox_event_file_recv_get_file_number(event); + const uint32_t kind = tox_event_file_recv_get_kind(event); + const uint64_t filesize = tox_event_file_recv_get_file_size(event); + const uint8_t *filename = tox_event_file_recv_get_filename(event); + const size_t filename_length = tox_event_file_recv_get_filename_length(event); + ck_assert_msg(kind == TOX_FILE_KIND_DATA, "bad kind"); ck_assert_msg(filename_length == sizeof("Gentoo.exe") @@ -49,11 +63,11 @@ static void tox_file_receive(Tox *tox, uint32_t friend_number, uint32_t file_num uint8_t file_id[TOX_FILE_ID_LENGTH]; - ck_assert_msg(tox_file_get_file_id(tox, friend_number, file_number, file_id, nullptr), "tox_file_get_file_id error"); + ck_assert_msg(tox_file_get_file_id(state_tox, friend_number, file_number, file_id, nullptr), "tox_file_get_file_id error"); ck_assert_msg(memcmp(file_id, file_cmp_id, TOX_FILE_ID_LENGTH) == 0, "bad file_id"); - uint8_t empty[TOX_FILE_ID_LENGTH] = {0}; + const uint8_t empty[TOX_FILE_ID_LENGTH] = {0}; ck_assert_msg(memcmp(empty, file_cmp_id, TOX_FILE_ID_LENGTH) != 0, "empty file_id"); @@ -64,7 +78,7 @@ static void tox_file_receive(Tox *tox, uint32_t friend_number, uint32_t file_num Tox_Err_File_Seek err_s; - ck_assert_msg(tox_file_seek(tox, friend_number, file_number, 1337, &err_s), "tox_file_seek error"); + ck_assert_msg(tox_file_seek(state_tox, friend_number, file_number, 1337, &err_s), "tox_file_seek error"); ck_assert_msg(err_s == TOX_ERR_FILE_SEEK_OK, "tox_file_seek wrong error"); @@ -74,21 +88,24 @@ static void tox_file_receive(Tox *tox, uint32_t friend_number, uint32_t file_num Tox_Err_File_Control error; - ck_assert_msg(tox_file_control(tox, friend_number, file_number, TOX_FILE_CONTROL_RESUME, &error), + ck_assert_msg(tox_file_control(state_tox, friend_number, file_number, TOX_FILE_CONTROL_RESUME, &error), "tox_file_control failed. %i", error); ++file_accepted; Tox_Err_File_Seek err_s; - ck_assert_msg(!tox_file_seek(tox, friend_number, file_number, 1234, &err_s), "tox_file_seek no error"); + ck_assert_msg(!tox_file_seek(state_tox, friend_number, file_number, 1234, &err_s), "tox_file_seek no error"); ck_assert_msg(err_s == TOX_ERR_FILE_SEEK_DENIED, "tox_file_seek wrong error"); } static uint32_t sendf_ok; -static void file_print_control(Tox *tox, uint32_t friend_number, uint32_t file_number, Tox_File_Control control, +static void file_print_control(const Tox_Event_File_Recv_Control *event, void *userdata) { + const uint32_t file_number = tox_event_file_recv_control_get_file_number(event); + const Tox_File_Control control = tox_event_file_recv_control_get_control(event); + /* First send file num is 0.*/ if (file_number == 0 && control == TOX_FILE_CONTROL_RESUME) { sendf_ok = 1; @@ -99,12 +116,18 @@ static uint64_t max_sending; static bool m_send_reached; static uint8_t sending_num; static bool file_sending_done; -static void tox_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, - size_t length, void *user_data) +static void tox_file_chunk_request(const Tox_Event_File_Chunk_Request *event, void *user_data) { + Tox *state_tox = (Tox *)user_data; + + const uint32_t friend_number = tox_event_file_chunk_request_get_friend_number(event); + const uint32_t file_number = tox_event_file_chunk_request_get_file_number(event); + const uint64_t position = tox_event_file_chunk_request_get_position(event); + size_t length = tox_event_file_chunk_request_get_length(event); + ck_assert_msg(sendf_ok, "didn't get resume control"); - ck_assert_msg(sending_pos == position, "bad position %lu", (unsigned long)position); + ck_assert_msg(sending_pos == position, "bad position %lu (should be %lu)", (unsigned long)position, (unsigned long)sending_pos); if (length == 0) { ck_assert_msg(!file_sending_done, "file sending already done"); @@ -124,8 +147,7 @@ static void tox_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t fi memset(f_data, sending_num, length); Tox_Err_File_Send_Chunk error; - tox_file_send_chunk(tox, friend_number, file_number, position, f_data, length, &error); - + tox_file_send_chunk(state_tox, friend_number, file_number, position, f_data, length, &error); ck_assert_msg(error == TOX_ERR_FILE_SEND_CHUNK_OK, "could not send chunk, error num=%d pos=%d len=%d", (int)error, (int)position, (int)length); @@ -134,12 +156,14 @@ static void tox_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t fi sending_pos += length; } - static uint8_t num; static bool file_recv; -static void write_file(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, const uint8_t *data, - size_t length, void *user_data) +static void write_file(const Tox_Event_File_Recv_Chunk *event, void *user_data) { + const uint64_t position = tox_event_file_recv_chunk_get_position(event); + const uint8_t *data = tox_event_file_recv_chunk_get_data(event); + const size_t length = tox_event_file_recv_chunk_get_data_length(event); + ck_assert_msg(size_recv == position, "bad position"); if (length == 0) { @@ -156,6 +180,17 @@ static void write_file(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uin size_recv += length; } +static void iterate_and_dispatch(const Tox_Dispatch *dispatch, Tox *tox) +{ + Tox_Err_Events_Iterate err; + Tox_Events *events; + + events = tox_events_iterate(tox, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + tox_dispatch_invoke(dispatch, events, tox); + tox_events_free(events); +} + static void file_transfer_test(void) { printf("Starting test: few_clients\n"); @@ -171,7 +206,19 @@ static void file_transfer_test(void) ck_assert_msg(tox1 && tox2 && tox3, "Failed to create 3 tox instances"); - tox_callback_friend_request(tox2, accept_friend_request); + tox_events_init(tox1); + tox_events_init(tox2); + tox_events_init(tox3); + + Tox_Dispatch *dispatch1 = tox_dispatch_new(nullptr); + ck_assert(dispatch1 != nullptr); + Tox_Dispatch *dispatch2 = tox_dispatch_new(nullptr); + ck_assert(dispatch2 != nullptr); + Tox_Dispatch *dispatch3 = tox_dispatch_new(nullptr); + ck_assert(dispatch3 != nullptr); + + tox_events_callback_friend_request(dispatch2, accept_friend_request); + uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(tox2, address); uint32_t test = tox_friend_add(tox3, address, (const uint8_t *)"Gentoo", 7, nullptr); @@ -187,9 +234,9 @@ static void file_transfer_test(void) printf("Waiting for toxes to come online\n"); do { - tox_iterate(tox1, nullptr); - tox_iterate(tox2, nullptr); - tox_iterate(tox3, nullptr); + iterate_and_dispatch(dispatch1, tox1); + iterate_and_dispatch(dispatch2, tox2); + iterate_and_dispatch(dispatch3, tox3); printf("Connections: self (%d, %d, %d), friends (%d, %d)\n", tox_self_get_connection_status(tox1), @@ -210,11 +257,11 @@ static void file_transfer_test(void) file_recv = 0; max_sending = UINT64_MAX; uint64_t f_time = time(nullptr); - tox_callback_file_recv_chunk(tox3, write_file); - tox_callback_file_recv_control(tox2, file_print_control); - tox_callback_file_chunk_request(tox2, tox_file_chunk_request); - tox_callback_file_recv_control(tox3, file_print_control); - tox_callback_file_recv(tox3, tox_file_receive); + tox_events_callback_file_recv_chunk(dispatch3, write_file); + tox_events_callback_file_recv_control(dispatch2, file_print_control); + tox_events_callback_file_chunk_request(dispatch2, tox_file_chunk_request); + tox_events_callback_file_recv_control(dispatch3, file_print_control); + tox_events_callback_file_recv(dispatch3, tox_file_receive); uint64_t totalf_size = 100 * 1024 * 1024; uint32_t fnum = tox_file_send(tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr, (const uint8_t *)"Gentoo.exe", sizeof("Gentoo.exe"), nullptr); @@ -231,9 +278,9 @@ static void file_transfer_test(void) const size_t max_iterations = INT16_MAX; for (size_t i = 0; i < max_iterations; i++) { - tox_iterate(tox1, nullptr); - tox_iterate(tox2, nullptr); - tox_iterate(tox3, nullptr); + iterate_and_dispatch(dispatch1, tox1); + iterate_and_dispatch(dispatch2, tox2); + iterate_and_dispatch(dispatch3, tox3); if (file_sending_done) { ck_assert_msg(sendf_ok && file_recv && totalf_size == file_size && size_recv == file_size && sending_pos == size_recv @@ -274,11 +321,11 @@ static void file_transfer_test(void) sendf_ok = 0; size_recv = 0; file_recv = 0; - tox_callback_file_recv_chunk(tox3, write_file); - tox_callback_file_recv_control(tox2, file_print_control); - tox_callback_file_chunk_request(tox2, tox_file_chunk_request); - tox_callback_file_recv_control(tox3, file_print_control); - tox_callback_file_recv(tox3, tox_file_receive); + tox_events_callback_file_recv_chunk(dispatch3, write_file); + tox_events_callback_file_recv_control(dispatch2, file_print_control); + tox_events_callback_file_chunk_request(dispatch2, tox_file_chunk_request); + tox_events_callback_file_recv_control(dispatch3, file_print_control); + tox_events_callback_file_recv(dispatch3, tox_file_receive); totalf_size = 0; fnum = tox_file_send(tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr, (const uint8_t *)"Gentoo.exe", sizeof("Gentoo.exe"), nullptr); @@ -298,9 +345,9 @@ static void file_transfer_test(void) c_sleep(min_u32(tox1_interval, min_u32(tox2_interval, tox3_interval))); - tox_iterate(tox1, nullptr); - tox_iterate(tox2, nullptr); - tox_iterate(tox3, nullptr); + iterate_and_dispatch(dispatch1, tox1); + iterate_and_dispatch(dispatch2, tox2); + iterate_and_dispatch(dispatch3, tox3); } while (!file_sending_done); ck_assert_msg(sendf_ok && file_recv && totalf_size == file_size && size_recv == file_size @@ -312,9 +359,12 @@ static void file_transfer_test(void) printf("file_transfer_test succeeded, took %llu seconds\n", time(nullptr) - cur_time); - tox_kill(tox1); - tox_kill(tox2); + tox_dispatch_free(dispatch3); + tox_dispatch_free(dispatch2); + tox_dispatch_free(dispatch1); tox_kill(tox3); + tox_kill(tox2); + tox_kill(tox1); } int main(void) diff --git a/auto_tests/forwarding_test.c b/auto_tests/forwarding_test.c index f9c82784..75e330a7 100644 --- a/auto_tests/forwarding_test.c +++ b/auto_tests/forwarding_test.c @@ -47,8 +47,8 @@ static void test_forwarded_request_cb(void *object, const IP_Port *forwarder, const uint8_t *sendback, uint16_t sendback_length, const uint8_t *data, uint16_t length, void *userdata) { - Test_Data *test_data = (Test_Data *)object; - uint8_t *index = (uint8_t *)userdata; + const Test_Data *test_data = (const Test_Data *)object; + const uint8_t *index = (const uint8_t *)userdata; if (length != 12 || memcmp("hello: ", data, 8) != 0) { printf("[%u] got unexpected data of length %d\n", *index, length); @@ -66,7 +66,7 @@ static void test_forwarded_response_cb(void *object, const uint8_t *data, uint16_t length, void *userdata) { Test_Data *test_data = (Test_Data *)object; - uint8_t *index = (uint8_t *)userdata; + const uint8_t *index = (const uint8_t *)userdata; if (length != 12 || memcmp("reply: ", data, 8) != 0) { printf("[%u] got unexpected data of length %d\n", *index, length); @@ -104,9 +104,9 @@ typedef struct Forwarding_Subtox { static Forwarding_Subtox *new_forwarding_subtox(const Memory *mem, bool no_udp, uint32_t *index, uint16_t port) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); Forwarding_Subtox *subtox = (Forwarding_Subtox *)calloc(1, sizeof(Forwarding_Subtox)); @@ -152,11 +152,11 @@ static void kill_forwarding_subtox(const Memory *mem, Forwarding_Subtox *subtox) static void test_forwarding(void) { - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); uint32_t index[NUM_FORWARDER]; @@ -317,7 +317,6 @@ static void test_forwarding(void) } } - for (uint32_t i = 0; i < NUM_FORWARDER; ++i) { kill_forwarding_subtox(mem, subtoxes[i]); } @@ -325,7 +324,6 @@ static void test_forwarding(void) tox_kill(relay); } - int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); diff --git a/auto_tests/friend_request_spam_test.c b/auto_tests/friend_request_spam_test.c index 8916f250..59520d8f 100644 --- a/auto_tests/friend_request_spam_test.c +++ b/auto_tests/friend_request_spam_test.c @@ -22,12 +22,18 @@ typedef struct State { bool unused; } State; -static void accept_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *data, size_t length, +static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata) { + AutoTox *autotox = (AutoTox *)userdata; + + const uint8_t *public_key = tox_event_friend_request_get_public_key(event); + const uint8_t *data = tox_event_friend_request_get_message(event); + const size_t length = tox_event_friend_request_get_message_length(event); + ck_assert_msg(length == sizeof(FR_MESSAGE) && memcmp(FR_MESSAGE, data, sizeof(FR_MESSAGE)) == 0, "unexpected friend request message"); - tox_friend_add_norequest(tox, public_key, nullptr); + tox_friend_add_norequest(autotox->tox, public_key, nullptr); } static void test_friend_request(AutoTox *autotoxes) @@ -35,7 +41,7 @@ static void test_friend_request(AutoTox *autotoxes) const time_t con_time = time(nullptr); printf("All toxes add tox1 as friend.\n"); - tox_callback_friend_request(autotoxes[0].tox, accept_friend_request); + tox_events_callback_friend_request(autotoxes[0].dispatch, accept_friend_request); uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(autotoxes[0].tox, address); diff --git a/auto_tests/friend_request_test.c b/auto_tests/friend_request_test.c index 8fe8f292..7dfc5bf8 100644 --- a/auto_tests/friend_request_test.c +++ b/auto_tests/friend_request_test.c @@ -15,12 +15,36 @@ #define FR_MESSAGE "Gentoo" -static void accept_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *data, size_t length, +static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata) { + Tox *state_tox = (Tox *)userdata; + + const uint8_t *public_key = tox_event_friend_request_get_public_key(event); + const uint8_t *data = tox_event_friend_request_get_message(event); + const size_t length = tox_event_friend_request_get_message_length(event); + ck_assert_msg(length == sizeof(FR_MESSAGE) && memcmp(FR_MESSAGE, data, sizeof(FR_MESSAGE)) == 0, "unexpected friend request message"); - tox_friend_add_norequest(tox, public_key, nullptr); + tox_friend_add_norequest(state_tox, public_key, nullptr); +} + +static void iterate2_wait(const Tox_Dispatch *dispatch, Tox *tox1, Tox *tox2) +{ + Tox_Err_Events_Iterate err; + Tox_Events *events; + + events = tox_events_iterate(tox1, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + tox_dispatch_invoke(dispatch, events, tox1); + tox_events_free(events); + + events = tox_events_iterate(tox2, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + tox_dispatch_invoke(dispatch, events, tox2); + tox_events_free(events); + + c_sleep(ITERATION_INTERVAL); } static void test_friend_request(void) @@ -33,6 +57,9 @@ static void test_friend_request(void) ck_assert_msg(tox1 && tox2, "failed to create 2 tox instances"); + tox_events_init(tox1); + tox_events_init(tox2); + printf("Bootstrapping tox2 off tox1.\n"); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(tox1, dht_key); @@ -40,11 +67,11 @@ static void test_friend_request(void) tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr); - do { - tox_iterate(tox1, nullptr); - tox_iterate(tox2, nullptr); + Tox_Dispatch *dispatch = tox_dispatch_new(nullptr); + ck_assert(dispatch != nullptr); - c_sleep(ITERATION_INTERVAL); + do { + iterate2_wait(dispatch, tox1, tox2); } while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE || tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE); @@ -52,7 +79,7 @@ static void test_friend_request(void) const time_t con_time = time(nullptr); printf("Tox1 adds tox2 as friend, tox2 accepts.\n"); - tox_callback_friend_request(tox2, accept_friend_request); + tox_events_callback_friend_request(dispatch, accept_friend_request); uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(tox2, address); @@ -61,16 +88,14 @@ static void test_friend_request(void) ck_assert_msg(test == 0, "failed to add friend error code: %u", test); do { - tox_iterate(tox1, nullptr); - tox_iterate(tox2, nullptr); - - c_sleep(ITERATION_INTERVAL); + iterate2_wait(dispatch, tox1, tox2); } while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP || tox_friend_get_connection_status(tox2, 0, nullptr) != TOX_CONNECTION_UDP); printf("Tox clients connected took %lu seconds.\n", (unsigned long)(time(nullptr) - con_time)); printf("friend_request_test succeeded, took %lu seconds.\n", (unsigned long)(time(nullptr) - cur_time)); + tox_dispatch_free(dispatch); tox_kill(tox1); tox_kill(tox2); } diff --git a/auto_tests/group_general_test.c b/auto_tests/group_general_test.c index 06663041..a4a4a0fe 100644 --- a/auto_tests/group_general_test.c +++ b/auto_tests/group_general_test.c @@ -43,7 +43,7 @@ typedef struct State { #define PEER_LIMIT 20 -static void print_ip(Tox *tox, uint32_t groupnumber, uint32_t peer_id) +static void print_ip(const Tox *tox, uint32_t groupnumber, uint32_t peer_id) { Tox_Err_Group_Peer_Query err; size_t length = tox_group_peer_get_ip_address_size(tox, groupnumber, peer_id, &err); @@ -81,32 +81,35 @@ static bool all_group_peers_connected(AutoTox *autotoxes, uint32_t tox_count, ui return true; } -static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, void *user_data) +static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); State *state = (State *)autotox->state; + const uint32_t groupnumber = tox_event_group_peer_join_get_group_number(event); + const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event); + // we do a connection test here for fun Tox_Err_Group_Peer_Query pq_err; - TOX_CONNECTION connection_status = tox_group_peer_get_connection_status(tox, groupnumber, peer_id, &pq_err); + Tox_Connection connection_status = tox_group_peer_get_connection_status(autotox->tox, groupnumber, peer_id, &pq_err); ck_assert(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(connection_status != TOX_CONNECTION_NONE); - Tox_Group_Role role = tox_group_peer_get_role(tox, groupnumber, peer_id, &pq_err); + Tox_Group_Role role = tox_group_peer_get_role(autotox->tox, groupnumber, peer_id, &pq_err); ck_assert_msg(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK, "%d", pq_err); - Tox_User_Status status = tox_group_peer_get_status(tox, groupnumber, peer_id, &pq_err); + Tox_User_Status status = tox_group_peer_get_status(autotox->tox, groupnumber, peer_id, &pq_err); ck_assert_msg(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK, "%d", pq_err); - size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &pq_err); + size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, groupnumber, peer_id, &pq_err); char peer_name[TOX_MAX_NAME_LENGTH + 1]; ck_assert(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH); - tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &pq_err); + tox_group_peer_get_name(autotox->tox, groupnumber, peer_id, (uint8_t *)peer_name, &pq_err); ck_assert(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK); peer_name[peer_name_len] = 0; @@ -137,35 +140,37 @@ static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t pee } fprintf(stderr, "%s joined with IP: ", peer_name); - print_ip(tox, groupnumber, peer_id); + print_ip(autotox->tox, groupnumber, peer_id); state->peer_id = peer_id; ++state->peer_joined_count; } -static void group_peer_self_join_handler(Tox *tox, uint32_t groupnumber, void *user_data) +static void group_peer_self_join_handler(const Tox_Event_Group_Self_Join *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); State *state = (State *)autotox->state; + const uint32_t groupnumber = tox_event_group_self_join_get_group_number(event); + // make sure we see our own correct peer state on join callback Tox_Err_Group_Self_Query sq_err; - size_t self_length = tox_group_self_get_name_size(tox, groupnumber, &sq_err); + size_t self_length = tox_group_self_get_name_size(autotox->tox, groupnumber, &sq_err); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); uint8_t self_name[TOX_MAX_NAME_LENGTH]; - tox_group_self_get_name(tox, groupnumber, self_name, &sq_err); + tox_group_self_get_name(autotox->tox, groupnumber, self_name, &sq_err); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); - TOX_USER_STATUS self_status = tox_group_self_get_status(tox, groupnumber, &sq_err); + Tox_User_Status self_status = tox_group_self_get_status(autotox->tox, groupnumber, &sq_err); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); - Tox_Group_Role self_role = tox_group_self_get_role(tox, groupnumber, &sq_err); + Tox_Group_Role self_role = tox_group_self_get_role(autotox->tox, groupnumber, &sq_err); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); if (state->is_founder) { @@ -185,36 +190,37 @@ static void group_peer_self_join_handler(Tox *tox, uint32_t groupnumber, void *u uint8_t group_name[GROUP_NAME_LEN]; uint8_t topic[TOX_GROUP_MAX_TOPIC_LENGTH]; - ck_assert(tox_group_get_peer_limit(tox, groupnumber, nullptr) == PEER_LIMIT); - ck_assert(tox_group_get_name_size(tox, groupnumber, nullptr) == GROUP_NAME_LEN); - ck_assert(tox_group_get_topic_size(tox, groupnumber, nullptr) == TOPIC_LEN); + ck_assert(tox_group_get_peer_limit(autotox->tox, groupnumber, nullptr) == PEER_LIMIT); + ck_assert(tox_group_get_name_size(autotox->tox, groupnumber, nullptr) == GROUP_NAME_LEN); + ck_assert(tox_group_get_topic_size(autotox->tox, groupnumber, nullptr) == TOPIC_LEN); - Tox_Err_Group_State_Queries query_err; - tox_group_get_name(tox, groupnumber, group_name, &query_err); - ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", query_err); + Tox_Err_Group_State_Query query_err; + tox_group_get_name(autotox->tox, groupnumber, group_name, &query_err); + ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "%d", query_err); ck_assert(memcmp(group_name, GROUP_NAME, GROUP_NAME_LEN) == 0); - tox_group_get_topic(tox, groupnumber, topic, &query_err); - ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", query_err); + tox_group_get_topic(autotox->tox, groupnumber, topic, &query_err); + ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "%d", query_err); ck_assert(memcmp(topic, TOPIC, TOPIC_LEN) == 0); - uint32_t peer_id = tox_group_self_get_peer_id(tox, groupnumber, nullptr); + uint32_t peer_id = tox_group_self_get_peer_id(autotox->tox, groupnumber, nullptr); fprintf(stderr, "self joined with IP: "); - print_ip(tox, groupnumber, peer_id); + print_ip(autotox->tox, groupnumber, peer_id); ++state->self_joined_count; } -static void group_peer_exit_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, Tox_Group_Exit_Type exit_type, - const uint8_t *name, size_t name_length, const uint8_t *part_message, - size_t length, void *user_data) +static void group_peer_exit_handler(const Tox_Event_Group_Peer_Exit *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); State *state = (State *)autotox->state; + const uint8_t *part_message = tox_event_group_peer_exit_get_part_message(event); + const size_t length = tox_event_group_peer_exit_get_part_message_length(event); + ++state->peer_exit_count; // first exit is a disconnect. second is a real exit with a part message @@ -224,14 +230,16 @@ static void group_peer_exit_handler(Tox *tox, uint32_t groupnumber, uint32_t pee } } -static void group_peer_name_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *name, - size_t length, void *user_data) +static void group_peer_name_handler(const Tox_Event_Group_Peer_Name *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); State *state = (State *)autotox->state; + const uint8_t *name = tox_event_group_peer_name_get_name(event); + const size_t length = tox_event_group_peer_name_get_name_length(event); + // note: we already test the name_get api call elsewhere ck_assert(length == PEER0_NICK2_LEN); @@ -240,7 +248,7 @@ static void group_peer_name_handler(Tox *tox, uint32_t groupnumber, uint32_t pee state->peer_nick = true; } -static void group_peer_status_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_USER_STATUS status, +static void group_peer_status_handler(const Tox_Event_Group_Peer_Status *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; @@ -248,8 +256,12 @@ static void group_peer_status_handler(Tox *tox, uint32_t groupnumber, uint32_t p State *state = (State *)autotox->state; + const uint32_t groupnumber = tox_event_group_peer_status_get_group_number(event); + const uint32_t peer_id = tox_event_group_peer_status_get_peer_id(event); + const Tox_User_Status status = tox_event_group_peer_status_get_status(event); + Tox_Err_Group_Peer_Query err; - TOX_USER_STATUS cur_status = tox_group_peer_get_status(tox, groupnumber, peer_id, &err); + Tox_User_Status cur_status = tox_group_peer_get_status(autotox->tox, groupnumber, peer_id, &err); ck_assert_msg(cur_status == status, "%d, %d", cur_status, status); ck_assert(status == TOX_USER_STATUS_BUSY); @@ -264,15 +276,15 @@ static void group_announce_test(AutoTox *autotoxes) Tox *tox0 = autotoxes[0].tox; Tox *tox1 = autotoxes[1].tox; State *state0 = (State *)autotoxes[0].state; - State *state1 = (State *)autotoxes[1].state; + const State *state1 = (const State *)autotoxes[1].state; - tox_callback_group_peer_join(tox0, group_peer_join_handler); - tox_callback_group_peer_join(tox1, group_peer_join_handler); - tox_callback_group_self_join(tox0, group_peer_self_join_handler); - tox_callback_group_self_join(tox1, group_peer_self_join_handler); - tox_callback_group_peer_name(tox1, group_peer_name_handler); - tox_callback_group_peer_status(tox1, group_peer_status_handler); - tox_callback_group_peer_exit(tox1, group_peer_exit_handler); + tox_events_callback_group_peer_join(autotoxes[0].dispatch, group_peer_join_handler); + tox_events_callback_group_peer_join(autotoxes[1].dispatch, group_peer_join_handler); + tox_events_callback_group_self_join(autotoxes[0].dispatch, group_peer_self_join_handler); + tox_events_callback_group_self_join(autotoxes[1].dispatch, group_peer_self_join_handler); + tox_events_callback_group_peer_name(autotoxes[1].dispatch, group_peer_name_handler); + tox_events_callback_group_peer_status(autotoxes[1].dispatch, group_peer_status_handler); + tox_events_callback_group_peer_exit(autotoxes[1].dispatch, group_peer_exit_handler); // tox0 makes new group. Tox_Err_Group_New err_new; @@ -286,19 +298,19 @@ static void group_announce_test(AutoTox *autotoxes) iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); // changes the state (for sync check purposes) - Tox_Err_Group_Founder_Set_Peer_Limit limit_set_err; - tox_group_founder_set_peer_limit(tox0, groupnumber, PEER_LIMIT, &limit_set_err); - ck_assert_msg(limit_set_err == TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK, "failed to set peer limit: %d", limit_set_err); + Tox_Err_Group_Set_Peer_Limit limit_set_err; + tox_group_set_peer_limit(tox0, groupnumber, PEER_LIMIT, &limit_set_err); + ck_assert_msg(limit_set_err == TOX_ERR_GROUP_SET_PEER_LIMIT_OK, "failed to set peer limit: %d", limit_set_err); Tox_Err_Group_Topic_Set tp_err; tox_group_set_topic(tox0, groupnumber, (const uint8_t *)TOPIC, TOPIC_LEN, &tp_err); ck_assert(tp_err == TOX_ERR_GROUP_TOPIC_SET_OK); // get the chat id of the new group. - Tox_Err_Group_State_Queries err_id; + Tox_Err_Group_State_Query err_id; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; tox_group_get_chat_id(tox0, groupnumber, chat_id, &err_id); - ck_assert(err_id == TOX_ERR_GROUP_STATE_QUERIES_OK); + ck_assert(err_id == TOX_ERR_GROUP_STATE_QUERY_OK); // tox1 joins it. Tox_Err_Group_Join err_join; @@ -343,7 +355,7 @@ static void group_announce_test(AutoTox *autotoxes) iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); - TOX_USER_STATUS self_status = tox_group_self_get_status(tox0, groupnumber, &sq_err); + Tox_User_Status self_status = tox_group_self_get_status(tox0, groupnumber, &sq_err); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(self_status == TOX_USER_STATUS_BUSY); @@ -429,10 +441,12 @@ static void group_announce_test(AutoTox *autotoxes) tox_group_leave(tox1, groupnumber, nullptr, 0, &err_exit); ck_assert(err_exit == TOX_ERR_GROUP_LEAVE_OK); - num_groups1 = tox_group_get_number_groups(tox0); - num_groups2 = tox_group_get_number_groups(tox1); + while (num_groups1 != 0 || num_groups2 != 0) { + num_groups1 = tox_group_get_number_groups(tox0); + num_groups2 = tox_group_get_number_groups(tox1); - ck_assert(num_groups1 == num_groups2 && num_groups2 == 0); + iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); + } printf("All tests passed!\n"); } diff --git a/auto_tests/group_invite_test.c b/auto_tests/group_invite_test.c index b83bed5e..a37b744a 100644 --- a/auto_tests/group_invite_test.c +++ b/auto_tests/group_invite_test.c @@ -51,13 +51,15 @@ static bool group_has_full_graph(const AutoTox *autotoxes, uint32_t group_number return true; } -static void group_join_fail_handler(Tox *tox, uint32_t group_number, Tox_Group_Join_Fail fail_type, void *user_data) +static void group_join_fail_handler(const Tox_Event_Group_Join_Fail *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); State *state = (State *)autotox->state; + const Tox_Group_Join_Fail fail_type = tox_event_group_join_fail_get_fail_type(event); + switch (fail_type) { case TOX_GROUP_JOIN_FAIL_PEER_LIMIT: { state->peer_limit_fail = true; @@ -79,7 +81,7 @@ static void group_join_fail_handler(Tox *tox, uint32_t group_number, Tox_Group_J } } -static void group_self_join_handler(Tox *tox, uint32_t group_number, void *user_data) +static void group_self_join_handler(const Tox_Event_Group_Self_Join *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); @@ -89,7 +91,7 @@ static void group_self_join_handler(Tox *tox, uint32_t group_number, void *user_ state->connected = true; } -static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t peer_id, void *user_data) +static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); @@ -105,9 +107,9 @@ static void group_invite_test(AutoTox *autotoxes) ck_assert_msg(NUM_GROUP_TOXES > 7, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES); for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { - tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler); - tox_callback_group_join_fail(autotoxes[i].tox, group_join_fail_handler); - tox_callback_group_self_join(autotoxes[i].tox, group_self_join_handler); + tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler); + tox_events_callback_group_join_fail(autotoxes[i].dispatch, group_join_fail_handler); + tox_events_callback_group_self_join(autotoxes[i].dispatch, group_self_join_handler); } Tox *tox0 = autotoxes[0].tox; @@ -118,12 +120,12 @@ static void group_invite_test(AutoTox *autotoxes) Tox *tox5 = autotoxes[5].tox; Tox *tox6 = autotoxes[6].tox; - State *state0 = (State *)autotoxes[0].state; - State *state2 = (State *)autotoxes[2].state; - State *state3 = (State *)autotoxes[3].state; - State *state4 = (State *)autotoxes[4].state; - State *state5 = (State *)autotoxes[5].state; - State *state6 = (State *)autotoxes[6].state; + const State *state0 = (const State *)autotoxes[0].state; + const State *state2 = (const State *)autotoxes[2].state; + const State *state3 = (const State *)autotoxes[3].state; + const State *state4 = (const State *)autotoxes[4].state; + const State *state5 = (const State *)autotoxes[5].state; + const State *state6 = (const State *)autotoxes[6].state; Tox_Err_Group_New new_err; uint32_t groupnumber = tox_group_new(tox0, TOX_GROUP_PRIVACY_STATE_PUBLIC, (const uint8_t *)"test", 4, @@ -132,11 +134,11 @@ static void group_invite_test(AutoTox *autotoxes) iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); - Tox_Err_Group_State_Queries id_err; + Tox_Err_Group_State_Query id_err; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; tox_group_get_chat_id(tox0, groupnumber, chat_id, &id_err); - ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", id_err); + ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "%d", id_err); // peer 1 joins public group with no password Tox_Err_Group_Join join_err; @@ -150,9 +152,9 @@ static void group_invite_test(AutoTox *autotoxes) printf("Peer 1 joined group\n"); // founder sets a password - Tox_Err_Group_Founder_Set_Password pass_set_err; - tox_group_founder_set_password(tox0, groupnumber, (const uint8_t *)PASSWORD, PASS_LEN, &pass_set_err); - ck_assert_msg(pass_set_err == TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK, "%d", pass_set_err); + Tox_Err_Group_Set_Password pass_set_err; + tox_group_set_password(tox0, groupnumber, (const uint8_t *)PASSWORD, PASS_LEN, &pass_set_err); + ck_assert_msg(pass_set_err == TOX_ERR_GROUP_SET_PASSWORD_OK, "%d", pass_set_err); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000); @@ -177,9 +179,9 @@ static void group_invite_test(AutoTox *autotoxes) printf("Peer 3 successfully blocked with invalid password\n"); // founder sets peer limit to 1 - Tox_Err_Group_Founder_Set_Peer_Limit limit_set_err; - tox_group_founder_set_peer_limit(tox0, groupnumber, 1, &limit_set_err); - ck_assert_msg(limit_set_err == TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK, "%d", limit_set_err); + Tox_Err_Group_Set_Peer_Limit limit_set_err; + tox_group_set_peer_limit(tox0, groupnumber, 1, &limit_set_err); + ck_assert_msg(limit_set_err == TOX_ERR_GROUP_SET_PEER_LIMIT_OK, "%d", limit_set_err); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000); @@ -194,11 +196,11 @@ static void group_invite_test(AutoTox *autotoxes) printf("Peer 4 successfully blocked from joining full group\n"); // founder removes password and increases peer limit to 100 - tox_group_founder_set_password(tox0, groupnumber, nullptr, 0, &pass_set_err); - ck_assert_msg(pass_set_err == TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK, "%d", pass_set_err); + tox_group_set_password(tox0, groupnumber, nullptr, 0, &pass_set_err); + ck_assert_msg(pass_set_err == TOX_ERR_GROUP_SET_PASSWORD_OK, "%d", pass_set_err); - tox_group_founder_set_peer_limit(tox0, groupnumber, 100, &limit_set_err); - ck_assert_msg(limit_set_err == TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK, "%d", limit_set_err); + tox_group_set_peer_limit(tox0, groupnumber, 100, &limit_set_err); + ck_assert_msg(limit_set_err == TOX_ERR_GROUP_SET_PEER_LIMIT_OK, "%d", limit_set_err); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000); @@ -213,9 +215,9 @@ static void group_invite_test(AutoTox *autotoxes) printf("Peer 5 successfully joined the group\n"); // founder makes group private - Tox_Err_Group_Founder_Set_Privacy_State priv_err; - tox_group_founder_set_privacy_state(tox0, groupnumber, TOX_GROUP_PRIVACY_STATE_PRIVATE, &priv_err); - ck_assert_msg(priv_err == TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK, "%d", priv_err); + Tox_Err_Group_Set_Privacy_State priv_err; + tox_group_set_privacy_state(tox0, groupnumber, TOX_GROUP_PRIVACY_STATE_PRIVATE, &priv_err); + ck_assert_msg(priv_err == TOX_ERR_GROUP_SET_PRIVACY_STATE_OK, "%d", priv_err); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000); @@ -231,8 +233,8 @@ static void group_invite_test(AutoTox *autotoxes) printf("Peer 6 failed to join private group via chat ID\n"); // founder makes group public again - tox_group_founder_set_privacy_state(tox0, groupnumber, TOX_GROUP_PRIVACY_STATE_PUBLIC, &priv_err); - ck_assert_msg(priv_err == TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK, "%d", priv_err); + tox_group_set_privacy_state(tox0, groupnumber, TOX_GROUP_PRIVACY_STATE_PUBLIC, &priv_err); + ck_assert_msg(priv_err == TOX_ERR_GROUP_SET_PRIVACY_STATE_OK, "%d", priv_err); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); diff --git a/auto_tests/group_message_test.c b/auto_tests/group_message_test.c index a8e20f99..608cebf8 100644 --- a/auto_tests/group_message_test.c +++ b/auto_tests/group_message_test.c @@ -19,7 +19,7 @@ typedef struct State { bool peer_joined; bool message_sent; bool message_received; - uint32_t pseudo_msg_id; + Tox_Group_Message_Id pseudo_msg_id; bool private_message_received; size_t custom_packets_received; size_t custom_private_packets_received; @@ -71,28 +71,37 @@ static uint16_t get_message_checksum(const uint8_t *message, uint16_t length) return sum; } -static void group_invite_handler(Tox *tox, uint32_t friend_number, const uint8_t *invite_data, size_t length, - const uint8_t *group_name, size_t group_name_length, void *user_data) +static void group_invite_handler(const Tox_Event_Group_Invite *event, void *user_data) { + AutoTox *autotox = (AutoTox *)user_data; + ck_assert(autotox != nullptr); + + const uint32_t friend_number = tox_event_group_invite_get_friend_number(event); + const uint8_t *invite_data = tox_event_group_invite_get_invite_data(event); + const size_t length = tox_event_group_invite_get_invite_data_length(event); + printf("invite arrived; accepting\n"); Tox_Err_Group_Invite_Accept err_accept; - tox_group_invite_accept(tox, friend_number, invite_data, length, (const uint8_t *)PEER0_NICK, PEER0_NICK_LEN, + tox_group_invite_accept(autotox->tox, friend_number, invite_data, length, (const uint8_t *)PEER0_NICK, PEER0_NICK_LEN, nullptr, 0, &err_accept); ck_assert(err_accept == TOX_ERR_GROUP_INVITE_ACCEPT_OK); } -static void group_join_fail_handler(Tox *tox, uint32_t groupnumber, Tox_Group_Join_Fail fail_type, void *user_data) +static void group_join_fail_handler(const Tox_Event_Group_Join_Fail *event, void *user_data) { + const Tox_Group_Join_Fail fail_type = tox_event_group_join_fail_get_fail_type(event); printf("join failed: %d\n", fail_type); } -static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, void *user_data) +static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); State *state = (State *)autotox->state; + const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event); + ck_assert_msg(state->peer_joined == false, "Peer timedout"); printf("peer %u joined, sending message\n", peer_id); @@ -100,9 +109,16 @@ static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t pee state->peer_id = peer_id; } -static void group_custom_private_packet_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *data, - size_t length, void *user_data) +static void group_custom_private_packet_handler(const Tox_Event_Group_Custom_Private_Packet *event, void *user_data) { + AutoTox *autotox = (AutoTox *)user_data; + ck_assert(autotox != nullptr); + + const uint32_t groupnumber = tox_event_group_custom_private_packet_get_group_number(event); + const uint32_t peer_id = tox_event_group_custom_private_packet_get_peer_id(event); + const uint8_t *data = tox_event_group_custom_private_packet_get_data(event); + const size_t length = tox_event_group_custom_private_packet_get_data_length(event); + ck_assert_msg(length == TEST_CUSTOM_PRIVATE_PACKET_LEN, "Failed to receive custom private packet. Invalid length: %zu\n", length); @@ -111,25 +127,25 @@ static void group_custom_private_packet_handler(Tox *tox, uint32_t groupnumber, message_buf[length] = 0; Tox_Err_Group_Peer_Query q_err; - size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err); + size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, groupnumber, peer_id, &q_err); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH); char peer_name[TOX_MAX_NAME_LENGTH + 1]; - tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err); + tox_group_peer_get_name(autotox->tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err); peer_name[peer_name_len] = 0; ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0); Tox_Err_Group_Self_Query s_err; - size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err); + size_t self_name_len = tox_group_self_get_name_size(autotox->tox, groupnumber, &s_err); ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH); char self_name[TOX_MAX_NAME_LENGTH + 1]; - tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err); + tox_group_self_get_name(autotox->tox, groupnumber, (uint8_t *)self_name, &s_err); self_name[self_name_len] = 0; ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); @@ -138,17 +154,21 @@ static void group_custom_private_packet_handler(Tox *tox, uint32_t groupnumber, printf("%s sent custom private packet to %s: %s\n", peer_name, self_name, message_buf); ck_assert(memcmp(message_buf, TEST_CUSTOM_PRIVATE_PACKET, length) == 0); - AutoTox *autotox = (AutoTox *)user_data; - ck_assert(autotox != nullptr); - State *state = (State *)autotox->state; ++state->custom_private_packets_received; } -static void group_custom_packet_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *data, - size_t length, void *user_data) +static void group_custom_packet_handler(const Tox_Event_Group_Custom_Packet *event, void *user_data) { + AutoTox *autotox = (AutoTox *)user_data; + ck_assert(autotox != nullptr); + + const uint32_t groupnumber = tox_event_group_custom_packet_get_group_number(event); + const uint32_t peer_id = tox_event_group_custom_packet_get_peer_id(event); + const uint8_t *data = tox_event_group_custom_packet_get_data(event); + const size_t length = tox_event_group_custom_packet_get_data_length(event); + ck_assert_msg(length == TEST_CUSTOM_PACKET_LEN, "Failed to receive custom packet. Invalid length: %zu\n", length); char message_buf[TOX_MAX_CUSTOM_PACKET_SIZE + 1]; @@ -156,25 +176,25 @@ static void group_custom_packet_handler(Tox *tox, uint32_t groupnumber, uint32_t message_buf[length] = 0; Tox_Err_Group_Peer_Query q_err; - size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err); + size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, groupnumber, peer_id, &q_err); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH); char peer_name[TOX_MAX_NAME_LENGTH + 1]; - tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err); + tox_group_peer_get_name(autotox->tox, groupnumber, peer_id, (uint8_t *)peer_name, &q_err); peer_name[peer_name_len] = 0; ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0); Tox_Err_Group_Self_Query s_err; - size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err); + size_t self_name_len = tox_group_self_get_name_size(autotox->tox, groupnumber, &s_err); ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH); char self_name[TOX_MAX_NAME_LENGTH + 1]; - tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err); + tox_group_self_get_name(autotox->tox, groupnumber, (uint8_t *)self_name, &s_err); self_name[self_name_len] = 0; ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); @@ -183,32 +203,39 @@ static void group_custom_packet_handler(Tox *tox, uint32_t groupnumber, uint32_t printf("%s sent custom packet to %s: %s\n", peer_name, self_name, message_buf); ck_assert(memcmp(message_buf, TEST_CUSTOM_PACKET, length) == 0); - AutoTox *autotox = (AutoTox *)user_data; - ck_assert(autotox != nullptr); - State *state = (State *)autotox->state; ++state->custom_packets_received; } -static void group_custom_packet_large_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *data, - size_t length, void *user_data) +static void group_custom_packet_large_handler(const Tox_Event_Group_Custom_Packet *event, void *user_data) { + AutoTox *autotox = (AutoTox *)user_data; + ck_assert(autotox != nullptr); + + const uint8_t *data = tox_event_group_custom_packet_get_data(event); + const size_t length = tox_event_group_custom_packet_get_data_length(event); + ck_assert_msg(length == TEST_CUSTOM_PACKET_LARGE_LEN, "Failed to receive large custom packet. Invalid length: %zu\n", length); ck_assert(memcmp(data, TEST_CUSTOM_PACKET_LARGE, length) == 0); - AutoTox *autotox = (AutoTox *)user_data; - ck_assert(autotox != nullptr); - State *state = (State *)autotox->state; ++state->custom_packets_received; } -static void group_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type, - const uint8_t *message, size_t length, uint32_t pseudo_msg_id, void *user_data) +static void group_message_handler(const Tox_Event_Group_Message *event, void *user_data) { + AutoTox *autotox = (AutoTox *)user_data; + ck_assert(autotox != nullptr); + + const uint32_t groupnumber = tox_event_group_message_get_group_number(event); + const uint32_t peer_id = tox_event_group_message_get_peer_id(event); + const uint8_t *message = tox_event_group_message_get_message(event); + const size_t length = tox_event_group_message_get_message_length(event); + const uint32_t pseudo_msg_id = tox_event_group_message_get_message_id(event); + ck_assert(!(length == IGNORE_MESSAGE_LEN && memcmp(message, IGNORE_MESSAGE, length) == 0)); ck_assert_msg(length == TEST_MESSAGE_LEN, "Failed to receive message. Invalid length: %zu\n", length); @@ -217,25 +244,25 @@ static void group_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_ message_buf[length] = 0; Tox_Err_Group_Peer_Query q_err; - size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err); + size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, groupnumber, peer_id, &q_err); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH); char peer_name[TOX_MAX_NAME_LENGTH + 1]; - tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err); + tox_group_peer_get_name(autotox->tox, groupnumber, peer_id, (uint8_t *)peer_name, &q_err); peer_name[peer_name_len] = 0; ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0); Tox_Err_Group_Self_Query s_err; - size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err); + size_t self_name_len = tox_group_self_get_name_size(autotox->tox, groupnumber, &s_err); ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH); char self_name[TOX_MAX_NAME_LENGTH + 1]; - tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err); + tox_group_self_get_name(autotox->tox, groupnumber, (uint8_t *)self_name, &s_err); self_name[self_name_len] = 0; ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); @@ -244,19 +271,24 @@ static void group_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_ printf("%s sent message to %s:(id:%u) %s\n", peer_name, self_name, pseudo_msg_id, message_buf); ck_assert(memcmp(message_buf, TEST_MESSAGE, length) == 0); - AutoTox *autotox = (AutoTox *)user_data; - ck_assert(autotox != nullptr); - State *state = (State *)autotox->state; state->message_received = true; - state->pseudo_msg_id = pseudo_msg_id; } -static void group_private_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type, - const uint8_t *message, size_t length, void *user_data) +static void group_private_message_handler(const Tox_Event_Group_Private_Message *event, void *user_data) { + AutoTox *autotox = (AutoTox *)user_data; + ck_assert(autotox != nullptr); + + const uint32_t groupnumber = tox_event_group_private_message_get_group_number(event); + const uint32_t peer_id = tox_event_group_private_message_get_peer_id(event); + const Tox_Message_Type type = tox_event_group_private_message_get_type(event); + const uint8_t *message = tox_event_group_private_message_get_message(event); + const size_t length = tox_event_group_private_message_get_message_length(event); + const Tox_Group_Message_Id pseudo_msg_id = tox_event_group_private_message_get_message_id(event); + ck_assert_msg(length == TEST_PRIVATE_MESSAGE_LEN, "Failed to receive message. Invalid length: %zu\n", length); char message_buf[TOX_GROUP_MAX_MESSAGE_LENGTH + 1]; @@ -264,46 +296,46 @@ static void group_private_message_handler(Tox *tox, uint32_t groupnumber, uint32 message_buf[length] = 0; Tox_Err_Group_Peer_Query q_err; - size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err); + size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, groupnumber, peer_id, &q_err); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH); char peer_name[TOX_MAX_NAME_LENGTH + 1]; - tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err); + tox_group_peer_get_name(autotox->tox, groupnumber, peer_id, (uint8_t *)peer_name, &q_err); peer_name[peer_name_len] = 0; ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0); Tox_Err_Group_Self_Query s_err; - size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err); + size_t self_name_len = tox_group_self_get_name_size(autotox->tox, groupnumber, &s_err); ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH); char self_name[TOX_MAX_NAME_LENGTH + 1]; - tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err); + tox_group_self_get_name(autotox->tox, groupnumber, (uint8_t *)self_name, &s_err); self_name[self_name_len] = 0; ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(memcmp(self_name, PEER1_NICK, self_name_len) == 0); - printf("%s sent private action to %s: %s\n", peer_name, self_name, message_buf); + printf("%s sent private action to %s:(id: %u) %s\n", peer_name, self_name, pseudo_msg_id, message_buf); ck_assert(memcmp(message_buf, TEST_PRIVATE_MESSAGE, length) == 0); ck_assert(type == TOX_MESSAGE_TYPE_ACTION); - AutoTox *autotox = (AutoTox *)user_data; - ck_assert(autotox != nullptr); - State *state = (State *)autotox->state; state->private_message_received = true; + state->pseudo_msg_id = pseudo_msg_id; } -static void group_message_handler_lossless_test(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type, - const uint8_t *message, size_t length, uint32_t pseudo_msg_id, void *user_data) +static void group_message_handler_lossless_test(const Tox_Event_Group_Message *event, void *user_data) { + const uint8_t *message = tox_event_group_message_get_message(event); + const size_t length = tox_event_group_message_get_message_length(event); + AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); @@ -325,10 +357,11 @@ static void group_message_handler_lossless_test(Tox *tox, uint32_t groupnumber, state->lossless_check = true; } } -static void group_message_handler_wraparound_test(Tox *tox, uint32_t groupnumber, uint32_t peer_id, - TOX_MESSAGE_TYPE type, - const uint8_t *message, size_t length, uint32_t pseudo_msg_id, void *user_data) +static void group_message_handler_wraparound_test(const Tox_Event_Group_Message *event, void *user_data) { + const uint8_t *message = tox_event_group_message_get_message(event); + const size_t length = tox_event_group_message_get_message_length(event); + AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); @@ -352,11 +385,11 @@ static void group_message_test(AutoTox *autotoxes) { ck_assert_msg(NUM_GROUP_TOXES >= 2, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES); - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); Tox *tox0 = autotoxes[0].tox; - Tox *tox1 = autotoxes[1].tox; + const Tox *tox1 = autotoxes[1].tox; State *state0 = (State *)autotoxes[0].state; State *state1 = (State *)autotoxes[1].state; @@ -365,15 +398,15 @@ static void group_message_test(AutoTox *autotoxes) state0->pseudo_msg_id = 0; state1->pseudo_msg_id = 1; - tox_callback_group_invite(tox1, group_invite_handler); - tox_callback_group_join_fail(tox1, group_join_fail_handler); - tox_callback_group_peer_join(tox1, group_peer_join_handler); - tox_callback_group_join_fail(tox0, group_join_fail_handler); - tox_callback_group_peer_join(tox0, group_peer_join_handler); - tox_callback_group_message(tox0, group_message_handler); - tox_callback_group_custom_packet(tox0, group_custom_packet_handler); - tox_callback_group_custom_private_packet(tox0, group_custom_private_packet_handler); - tox_callback_group_private_message(tox0, group_private_message_handler); + tox_events_callback_group_invite(autotoxes[1].dispatch, group_invite_handler); + tox_events_callback_group_join_fail(autotoxes[1].dispatch, group_join_fail_handler); + tox_events_callback_group_peer_join(autotoxes[1].dispatch, group_peer_join_handler); + tox_events_callback_group_join_fail(autotoxes[0].dispatch, group_join_fail_handler); + tox_events_callback_group_peer_join(autotoxes[0].dispatch, group_peer_join_handler); + tox_events_callback_group_message(autotoxes[0].dispatch, group_message_handler); + tox_events_callback_group_custom_packet(autotoxes[0].dispatch, group_custom_packet_handler); + tox_events_callback_group_custom_private_packet(autotoxes[0].dispatch, group_custom_private_packet_handler); + tox_events_callback_group_private_message(autotoxes[0].dispatch, group_private_message_handler); Tox_Err_Group_Send_Message err_send; @@ -396,14 +429,15 @@ static void group_message_test(AutoTox *autotoxes) if (state1->peer_joined && !state1->message_sent) { state1->pseudo_msg_id = tox_group_send_message( - tox1, group_number, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)TEST_MESSAGE, - TEST_MESSAGE_LEN, &err_send); + tox1, group_number, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)TEST_MESSAGE, + TEST_MESSAGE_LEN, &err_send); ck_assert(err_send == TOX_ERR_GROUP_SEND_MESSAGE_OK); state1->message_sent = true; } } - ck_assert_msg(state0->pseudo_msg_id == state1->pseudo_msg_id, "id0:%u id1:%u", state0->pseudo_msg_id, state1->pseudo_msg_id); + ck_assert_msg(state0->pseudo_msg_id == state1->pseudo_msg_id, "id0:%u id1:%u", + state0->pseudo_msg_id, state1->pseudo_msg_id); // Make sure we're still connected to each friend Tox_Connection conn_1 = tox_friend_get_connection_status(tox0, 0, nullptr); @@ -428,14 +462,23 @@ static void group_message_test(AutoTox *autotoxes) tox_group_set_ignore(tox0, group_number, state0->peer_id, false, &ig_err); ck_assert_msg(ig_err == TOX_ERR_GROUP_SET_IGNORE_OK, "%d", ig_err); - fprintf(stderr, "Sending private message...\n"); + fprintf(stderr, "Sending private action...\n"); - // tox0 sends a private action to tox1 + // tox1 sends a private action to tox0 Tox_Err_Group_Send_Private_Message m_err; - tox_group_send_private_message(tox1, group_number, state1->peer_id, TOX_MESSAGE_TYPE_ACTION, - (const uint8_t *)TEST_PRIVATE_MESSAGE, TEST_PRIVATE_MESSAGE_LEN, &m_err); + state1->pseudo_msg_id = tox_group_send_private_message(tox1, group_number, state1->peer_id, + TOX_MESSAGE_TYPE_ACTION, (const uint8_t *)TEST_PRIVATE_MESSAGE, + TEST_PRIVATE_MESSAGE_LEN, &m_err); + ck_assert_msg(m_err == TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_OK, "%d", m_err); + while (!state0->private_message_received) { + iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); + } + + ck_assert_msg(state0->pseudo_msg_id == state1->pseudo_msg_id, "id0:%u id1:%u", + state0->pseudo_msg_id, state1->pseudo_msg_id); + fprintf(stderr, "Sending custom packets...\n"); // tox0 sends a lossless and lossy custom packet to tox1 @@ -464,15 +507,14 @@ static void group_message_test(AutoTox *autotoxes) ck_assert_msg(cperr == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK, "%d", cperr); - while (!state0->private_message_received || state0->custom_packets_received < 2 - || state0->custom_private_packets_received < 2) { + while (state0->custom_packets_received < 2 || state0->custom_private_packets_received < 2) { iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); } // tox0 sends a large max sized lossy custom packet // overwrite callback for larger packet - tox_callback_group_custom_packet(tox0, group_custom_packet_large_handler); + tox_events_callback_group_custom_packet(autotoxes[0].dispatch, group_custom_packet_large_handler); tox_group_send_custom_packet(tox1, group_number, false, (const uint8_t *)TEST_CUSTOM_PACKET_LARGE, TEST_CUSTOM_PACKET_LARGE_LEN, &c_err); @@ -486,7 +528,7 @@ static void group_message_test(AutoTox *autotoxes) fprintf(stderr, "Doing lossless packet test...\n"); - tox_callback_group_message(tox1, group_message_handler_lossless_test); + tox_events_callback_group_message(autotoxes[1].dispatch, group_message_handler_lossless_test); state1->last_msg_recv = -1; // lossless and packet splitting/reassembly test @@ -517,7 +559,7 @@ static void group_message_test(AutoTox *autotoxes) } state1->last_msg_recv = -1; - tox_callback_group_message(tox1, group_message_handler_wraparound_test); + tox_events_callback_group_message(autotoxes[1].dispatch, group_message_handler_wraparound_test); fprintf(stderr, "Doing wraparound test...\n"); diff --git a/auto_tests/group_moderation_test.c b/auto_tests/group_moderation_test.c index 6f10ef76..58dac414 100644 --- a/auto_tests/group_moderation_test.c +++ b/auto_tests/group_moderation_test.c @@ -19,13 +19,13 @@ #define GROUP_NAME_LEN (sizeof(GROUP_NAME) - 1) typedef struct Peer { - char name[TOX_MAX_NAME_LENGTH]; + char name[TOX_MAX_NAME_LENGTH + 1]; size_t name_length; uint32_t peer_id; } Peer; typedef struct State { - char self_name[TOX_MAX_NAME_LENGTH]; + char self_name[TOX_MAX_NAME_LENGTH + 1]; size_t self_name_length; uint32_t group_number; @@ -38,7 +38,6 @@ typedef struct State { char mod_name1[TOX_MAX_NAME_LENGTH]; char mod_name2[TOX_MAX_NAME_LENGTH]; - bool observer_check; size_t observer_event_count; char observer_name1[TOX_MAX_NAME_LENGTH]; @@ -53,7 +52,7 @@ typedef struct State { static bool all_peers_connected(AutoTox *autotoxes) { for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { - State *state = (State *)autotoxes[i].state; + const State *state = (const State *)autotoxes[i].state; if (state->num_peers != NUM_GROUP_TOXES - 1) { return false; @@ -146,7 +145,7 @@ static size_t get_state_index_by_nick(const AutoTox *autotoxes, size_t num_peers ck_assert(name != nullptr && name_length <= TOX_MAX_NAME_LENGTH); for (size_t i = 0; i < num_peers; ++i) { - State *state = (State *)autotoxes[i].state; + const State *state = (const State *)autotoxes[i].state; if (memcmp(state->self_name, name, name_length) == 0) { return i; @@ -156,29 +155,33 @@ static size_t get_state_index_by_nick(const AutoTox *autotoxes, size_t num_peers ck_assert_msg(0, "Failed to find index"); } -static void group_join_fail_handler(Tox *tox, uint32_t group_number, Tox_Group_Join_Fail fail_type, void *user_data) +static void group_join_fail_handler(const Tox_Event_Group_Join_Fail *event, void *user_data) { + const Tox_Group_Join_Fail fail_type = tox_event_group_join_fail_get_fail_type(event); fprintf(stderr, "Failed to join group: %d", fail_type); } -static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t peer_id, void *user_data) +static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); State *state = (State *)autotox->state; + const uint32_t group_number = tox_event_group_peer_join_get_group_number(event); + const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event); + ck_assert(state->group_number == group_number); char peer_name[TOX_MAX_NAME_LENGTH + 1]; Tox_Err_Group_Peer_Query q_err; - size_t peer_name_len = tox_group_peer_get_name_size(tox, group_number, peer_id, &q_err); + size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, group_number, peer_id, &q_err); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH); - tox_group_peer_get_name(tox, group_number, peer_id, (uint8_t *) peer_name, &q_err); + tox_group_peer_get_name(autotox->tox, group_number, peer_id, (uint8_t *) peer_name, &q_err); peer_name[peer_name_len] = 0; ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); @@ -193,7 +196,7 @@ static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t pe ck_assert(state->num_peers < NUM_GROUP_TOXES); } -static void handle_mod(State *state, const char *peer_name, size_t peer_name_len, Tox_Group_Role role) +static void handle_mod(State *state, const char *peer_name, size_t peer_name_len) { if (state->mod_event_count == 0) { ck_assert(memcmp(peer_name, state->mod_name1, peer_name_len) == 0); @@ -205,10 +208,9 @@ static void handle_mod(State *state, const char *peer_name, size_t peer_name_len ++state->mod_event_count; state->mod_check = true; - ck_assert(role == TOX_GROUP_ROLE_MODERATOR); } -static void handle_observer(State *state, const char *peer_name, size_t peer_name_len, Tox_Group_Role role) +static void handle_observer(State *state, const char *peer_name, size_t peer_name_len) { if (state->observer_event_count == 0) { ck_assert(memcmp(peer_name, state->observer_name1, peer_name_len) == 0); @@ -220,10 +222,9 @@ static void handle_observer(State *state, const char *peer_name, size_t peer_nam ++state->observer_event_count; state->observer_check = true; - ck_assert(role == TOX_GROUP_ROLE_OBSERVER); } -static void handle_user(State *state, const char *peer_name, size_t peer_name_len, Tox_Group_Role role) +static void handle_user(State *state, const char *peer_name, size_t peer_name_len) { // event 1: observer1 gets promoted back to user // event 2: observer2 gets promoted to moderator @@ -243,23 +244,25 @@ static void handle_user(State *state, const char *peer_name, size_t peer_name_le ++state->user_event_count; state->user_check = true; - ck_assert(role == TOX_GROUP_ROLE_USER); } -static void group_mod_event_handler(Tox *tox, uint32_t group_number, uint32_t source_peer_id, uint32_t target_peer_id, - Tox_Group_Mod_Event mod_type, void *user_data) +static void group_mod_event_handler(const Tox_Event_Group_Moderation *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); State *state = (State *)autotox->state; + const uint32_t group_number = tox_event_group_moderation_get_group_number(event); + const uint32_t target_peer_id = tox_event_group_moderation_get_target_peer_id(event); + const Tox_Group_Mod_Event mod_type = tox_event_group_moderation_get_mod_type(event); + ck_assert(state->group_number == group_number); char peer_name[TOX_MAX_NAME_LENGTH + 1]; Tox_Err_Group_Peer_Query q_err; - size_t peer_name_len = tox_group_peer_get_name_size(tox, group_number, target_peer_id, &q_err); + size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, group_number, target_peer_id, &q_err); if (q_err == TOX_ERR_GROUP_PEER_QUERY_PEER_NOT_FOUND) { // may occurr on sync attempts return; @@ -268,12 +271,13 @@ static void group_mod_event_handler(Tox *tox, uint32_t group_number, uint32_t so ck_assert_msg(q_err == TOX_ERR_GROUP_PEER_QUERY_OK, "error %d", q_err); ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH); - tox_group_peer_get_name(tox, group_number, target_peer_id, (uint8_t *) peer_name, &q_err); + tox_group_peer_get_name(autotox->tox, group_number, target_peer_id, (uint8_t *) peer_name, &q_err); peer_name[peer_name_len] = 0; ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); - Tox_Group_Role role = tox_group_peer_get_role(tox, group_number, target_peer_id, &q_err); + Tox_Group_Role role = tox_group_peer_get_role(autotox->tox, group_number, target_peer_id, &q_err); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); + ck_assert(role <= TOX_GROUP_ROLE_OBSERVER); fprintf(stderr, "tox%u: got moderator event %d (%s), role = %s\n", autotox->index, mod_type, tox_group_mod_event_to_string(mod_type), @@ -281,17 +285,17 @@ static void group_mod_event_handler(Tox *tox, uint32_t group_number, uint32_t so switch (mod_type) { case TOX_GROUP_MOD_EVENT_MODERATOR: { - handle_mod(state, peer_name, peer_name_len, role); + handle_mod(state, peer_name, peer_name_len); break; } case TOX_GROUP_MOD_EVENT_OBSERVER: { - handle_observer(state, peer_name, peer_name_len, role); + handle_observer(state, peer_name, peer_name_len); break; } case TOX_GROUP_MOD_EVENT_USER: { - handle_user(state, peer_name, peer_name_len, role); + handle_user(state, peer_name, peer_name_len); break; } @@ -314,7 +318,7 @@ static void check_self_role(AutoTox *autotoxes, uint32_t peer_id, Tox_Group_Role Tox_Err_Group_Self_Query sq_err; for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { - State *state = (State *)autotoxes[i].state; + const State *state = (const State *)autotoxes[i].state; uint32_t self_peer_id = tox_group_self_get_peer_id(autotoxes[i].tox, state->group_number, &sq_err); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); @@ -378,13 +382,13 @@ static void voice_state_message_test(AutoTox *autotox, Tox_Group_Voice_State voi static bool all_peers_got_voice_state_change(AutoTox *autotoxes, uint32_t num_toxes, Tox_Group_Voice_State expected_voice_state) { - Tox_Err_Group_State_Queries query_err; + Tox_Err_Group_State_Query query_err; for (uint32_t i = 0; i < num_toxes; ++i) { const State *state = (State *)autotoxes[i].state; Tox_Group_Voice_State voice_state = tox_group_get_voice_state(autotoxes[i].tox, state->group_number, &query_err); - ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK); + ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); if (voice_state != expected_voice_state) { return false; @@ -398,10 +402,10 @@ static void check_voice_state(AutoTox *autotoxes, uint32_t num_toxes) { // founder sets voice state to Moderator const State *state = (State *)autotoxes[0].state; - Tox_Err_Group_Founder_Set_Voice_State voice_set_err; - tox_group_founder_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_MODERATOR, - &voice_set_err); - ck_assert(voice_set_err == TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK); + Tox_Err_Group_Set_Voice_State voice_set_err; + tox_group_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_MODERATOR, + &voice_set_err); + ck_assert(voice_set_err == TOX_ERR_GROUP_SET_VOICE_STATE_OK); for (uint32_t i = 0; i < num_toxes; ++i) { do { @@ -411,8 +415,8 @@ static void check_voice_state(AutoTox *autotoxes, uint32_t num_toxes) voice_state_message_test(&autotoxes[i], TOX_GROUP_VOICE_STATE_MODERATOR); } - tox_group_founder_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_FOUNDER, &voice_set_err); - ck_assert(voice_set_err == TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK); + tox_group_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_FOUNDER, &voice_set_err); + ck_assert(voice_set_err == TOX_ERR_GROUP_SET_VOICE_STATE_OK); for (uint32_t i = 0; i < num_toxes; ++i) { do { @@ -422,8 +426,8 @@ static void check_voice_state(AutoTox *autotoxes, uint32_t num_toxes) voice_state_message_test(&autotoxes[i], TOX_GROUP_VOICE_STATE_FOUNDER); } - tox_group_founder_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_ALL, &voice_set_err); - ck_assert(voice_set_err == TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK); + tox_group_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_ALL, &voice_set_err); + ck_assert(voice_set_err == TOX_ERR_GROUP_SET_VOICE_STATE_OK); for (uint32_t i = 0; i < num_toxes; ++i) { do { @@ -447,9 +451,9 @@ static void group_moderation_test(AutoTox *autotoxes) snprintf(state->self_name, sizeof(state->self_name), "peer_%zu", i); state->self_name[name_length] = 0; - tox_callback_group_join_fail(autotoxes[i].tox, group_join_fail_handler); - tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler); - tox_callback_group_moderation(autotoxes[i].tox, group_mod_event_handler); + tox_events_callback_group_join_fail(autotoxes[i].dispatch, group_join_fail_handler); + tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler); + tox_events_callback_group_moderation(autotoxes[i].dispatch, group_mod_event_handler); } iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); @@ -468,11 +472,11 @@ static void group_moderation_test(AutoTox *autotoxes) ck_assert_msg(err_new == TOX_ERR_GROUP_NEW_OK, "Failed to create group. error: %d\n", err_new); /* Founder gets chat ID */ - Tox_Err_Group_State_Queries id_err; + Tox_Err_Group_State_Query id_err; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; tox_group_get_chat_id(tox0, state0->group_number, chat_id, &id_err); - ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get chat ID. error: %d", id_err); + ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get chat ID. error: %d", id_err); fprintf(stderr, "Peers attemping to join DHT group via the chat ID\n"); @@ -512,7 +516,7 @@ static void group_moderation_test(AutoTox *autotoxes) /* all peers should be user role except founder */ for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) { - State *state = (State *)autotoxes[i].state; + const State *state = (const State *)autotoxes[i].state; self_role = tox_group_self_get_role(autotoxes[i].tox, state->group_number, &sq_err); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(self_role == TOX_GROUP_ROLE_USER); @@ -521,9 +525,9 @@ static void group_moderation_test(AutoTox *autotoxes) /* founder sets first peer to moderator */ fprintf(stderr, "Founder setting %s to moderator\n", state0->peers[0].name); - Tox_Err_Group_Mod_Set_Role role_err; - tox_group_mod_set_role(tox0, state0->group_number, state0->peers[0].peer_id, TOX_GROUP_ROLE_MODERATOR, &role_err); - ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err); + Tox_Err_Group_Set_Role role_err; + tox_group_set_role(tox0, state0->group_number, state0->peers[0].peer_id, TOX_GROUP_ROLE_MODERATOR, &role_err); + ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err); // manually flag the role setter because they don't get a callback state0->mod_check = true; @@ -537,8 +541,8 @@ static void group_moderation_test(AutoTox *autotoxes) /* founder sets second and third peer to observer */ fprintf(stderr, "Founder setting %s to observer\n", state0->peers[1].name); - tox_group_mod_set_role(tox0, state0->group_number, state0->peers[1].peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err); - ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set observer. error: %d", role_err); + tox_group_set_role(tox0, state0->group_number, state0->peers[1].peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err); + ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set observer. error: %d", role_err); state0->observer_check = true; ++state0->observer_event_count; @@ -548,8 +552,8 @@ static void group_moderation_test(AutoTox *autotoxes) fprintf(stderr, "Founder setting %s to observer\n", state0->peers[2].name); - tox_group_mod_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err); - ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set observer. error: %d", role_err); + tox_group_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err); + ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set observer. error: %d", role_err); state0->observer_check = true; ++state0->observer_event_count; @@ -574,8 +578,8 @@ static void group_moderation_test(AutoTox *autotoxes) fprintf(stderr, "%s is promoting %s back to user\n", state1->self_name, state0->peers[1].name); - tox_group_mod_set_role(tox1, state1->group_number, obs_peer_id, TOX_GROUP_ROLE_USER, &role_err); - ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to promote observer back to user. error: %d", + tox_group_set_role(tox1, state1->group_number, obs_peer_id, TOX_GROUP_ROLE_USER, &role_err); + ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to promote observer back to user. error: %d", role_err); state1->user_check = true; @@ -587,8 +591,8 @@ static void group_moderation_test(AutoTox *autotoxes) /* founder assigns third peer to moderator (this triggers two events: user and moderator) */ fprintf(stderr, "Founder setting %s to moderator\n", state0->peers[2].name); - tox_group_mod_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_MODERATOR, &role_err); - ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err); + tox_group_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_MODERATOR, &role_err); + ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err); state0->mod_check = true; ++state0->mod_event_count; @@ -600,18 +604,27 @@ static void group_moderation_test(AutoTox *autotoxes) /* moderator attempts to demote and kick founder */ uint32_t founder_peer_id = get_peer_id_by_nick(state1->peers, NUM_GROUP_TOXES - 1, state0->self_name); - tox_group_mod_set_role(tox1, state1->group_number, founder_peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err); - ck_assert_msg(role_err != TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Mod set founder to observer"); + tox_group_set_role(tox1, state1->group_number, founder_peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err); + ck_assert_msg(role_err != TOX_ERR_GROUP_SET_ROLE_OK, "Mod set founder to observer"); - Tox_Err_Group_Mod_Kick_Peer k_err; - tox_group_mod_kick_peer(tox1, state1->group_number, founder_peer_id, &k_err); - ck_assert_msg(k_err != TOX_ERR_GROUP_MOD_KICK_PEER_OK, "Mod kicked founder"); + Tox_Err_Group_Kick_Peer k_err; + tox_group_kick_peer(tox1, state1->group_number, founder_peer_id, &k_err); + ck_assert_msg(k_err != TOX_ERR_GROUP_KICK_PEER_OK, "Mod kicked founder"); + + /* the moderator about to be kicked changes the topic to trigger the founder to + * re-sign and redistribute it after the kick. + */ + const State *state_x = (const State *)autotoxes[idx].state; + Tox *tox_x = autotoxes[idx].tox; + Tox_Err_Group_Topic_Set topic_err; + tox_group_set_topic(tox_x, state_x->group_number, nullptr, 0, &topic_err); + ck_assert(topic_err == TOX_ERR_GROUP_TOPIC_SET_OK); /* founder kicks moderator (this triggers two events: user and kick) */ fprintf(stderr, "Founder is kicking %s\n", state0->peers[0].name); - tox_group_mod_kick_peer(tox0, state0->group_number, state0->peers[0].peer_id, &k_err); - ck_assert_msg(k_err == TOX_ERR_GROUP_MOD_KICK_PEER_OK, "Failed to kick peer. error: %d", k_err); + tox_group_kick_peer(tox0, state0->group_number, state0->peers[0].peer_id, &k_err); + ck_assert_msg(k_err == TOX_ERR_GROUP_KICK_PEER_OK, "Failed to kick peer. error: %d", k_err); state0->kick_check = true; check_mod_event(autotoxes, NUM_GROUP_TOXES, TOX_GROUP_MOD_EVENT_KICK); @@ -619,9 +632,8 @@ static void group_moderation_test(AutoTox *autotoxes) fprintf(stderr, "All peers successfully received kick event\n"); fprintf(stderr, "Founder is demoting moderator to user\n"); - - tox_group_mod_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_USER, &role_err); - ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to demote peer 3 to User. error: %d", role_err); + tox_group_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_USER, &role_err); + ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to demote peer 3 to User. error: %d", role_err); state0->user_check = true; ++state0->user_event_count; diff --git a/auto_tests/group_save_test.c b/auto_tests/group_save_test.c index aea898dc..26b41d07 100644 --- a/auto_tests/group_save_test.c +++ b/auto_tests/group_save_test.c @@ -26,17 +26,23 @@ typedef struct State { #define PEER0_NICK_LEN (sizeof(PEER0_NICK) -1) #define NEW_USER_STATUS TOX_USER_STATUS_BUSY -static void group_invite_handler(Tox *tox, uint32_t friend_number, const uint8_t *invite_data, size_t length, - const uint8_t *group_name, size_t group_name_length, void *user_data) +static void group_invite_handler(const Tox_Event_Group_Invite *event, void *user_data) { + AutoTox *autotox = (AutoTox *)user_data; + ck_assert(autotox != nullptr); + + const uint32_t friend_number = tox_event_group_invite_get_friend_number(event); + const uint8_t *invite_data = tox_event_group_invite_get_invite_data(event); + const size_t length = tox_event_group_invite_get_invite_data_length(event); + Tox_Err_Group_Invite_Accept err_accept; - tox_group_invite_accept(tox, friend_number, invite_data, length, (const uint8_t *)"test2", 5, + tox_group_invite_accept(autotox->tox, friend_number, invite_data, length, (const uint8_t *)"test2", 5, nullptr, 0, &err_accept); ck_assert(err_accept == TOX_ERR_GROUP_INVITE_ACCEPT_OK); } -static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t peer_id, void *user_data) +static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); @@ -52,28 +58,28 @@ static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t pe */ static int has_correct_group_state(const Tox *tox, uint32_t group_number, const uint8_t *expected_chat_id) { - Tox_Err_Group_State_Queries query_err; + Tox_Err_Group_State_Query query_err; Tox_Group_Privacy_State priv_state = tox_group_get_privacy_state(tox, group_number, &query_err); - ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK); + ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); if (priv_state != NEW_PRIV_STATE) { return -1; } size_t pass_len = tox_group_get_password_size(tox, group_number, &query_err); - ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK); + ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); uint8_t password[TOX_GROUP_MAX_PASSWORD_SIZE]; tox_group_get_password(tox, group_number, password, &query_err); - ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK); + ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); if (pass_len != PASS_LEN || memcmp(password, PASSWORD, pass_len) != 0) { return -2; } size_t gname_len = tox_group_get_name_size(tox, group_number, &query_err); - ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK); + ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); uint8_t group_name[TOX_GROUP_MAX_GROUP_NAME_LENGTH]; tox_group_get_name(tox, group_number, group_name, &query_err); @@ -87,17 +93,17 @@ static int has_correct_group_state(const Tox *tox, uint32_t group_number, const } Tox_Group_Topic_Lock topic_lock = tox_group_get_topic_lock(tox, group_number, &query_err); - ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK); + ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); if (topic_lock != TOX_GROUP_TOPIC_LOCK_DISABLED) { return -5; } - Tox_Err_Group_State_Queries id_err; + Tox_Err_Group_State_Query id_err; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; tox_group_get_chat_id(tox, group_number, chat_id, &id_err); - ck_assert(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK); + ck_assert(id_err == TOX_ERR_GROUP_STATE_QUERY_OK); if (memcmp(chat_id, expected_chat_id, TOX_GROUP_CHAT_ID_SIZE) != 0) { return -6; @@ -120,7 +126,7 @@ static int has_correct_self_state(const Tox *tox, uint32_t group_number, const u return -1; } - TOX_USER_STATUS self_status = tox_group_self_get_status(tox, group_number, &sq_err); + Tox_User_Status self_status = tox_group_self_get_status(tox, group_number, &sq_err); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); if (self_status != NEW_USER_STATUS) { @@ -151,8 +157,8 @@ static void group_save_test(AutoTox *autotoxes) ck_assert_msg(NUM_GROUP_TOXES > 1, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES); for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { - tox_callback_group_invite(autotoxes[i].tox, group_invite_handler); - tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler); + tox_events_callback_group_invite(autotoxes[i].dispatch, group_invite_handler); + tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler); } Tox *tox0 = autotoxes[0].tox; @@ -168,9 +174,9 @@ static void group_save_test(AutoTox *autotoxes) uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; - Tox_Err_Group_State_Queries id_err; + Tox_Err_Group_State_Query id_err; tox_group_get_chat_id(tox0, group_number, chat_id, &id_err); - ck_assert(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK); + ck_assert(id_err == TOX_ERR_GROUP_STATE_QUERY_OK); uint8_t founder_pk[TOX_GROUP_PEER_PUBLIC_KEY_SIZE]; @@ -178,7 +184,6 @@ static void group_save_test(AutoTox *autotoxes) tox_group_self_get_public_key(tox0, group_number, founder_pk, &sq_err); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); - Tox_Err_Group_Invite_Friend err_invite; tox_group_invite_friend(tox0, group_number, 0, &err_invite); @@ -195,21 +200,21 @@ static void group_save_test(AutoTox *autotoxes) tox_group_set_topic(tox0, group_number, (const uint8_t *)TOPIC, TOPIC_LEN, &top_err); ck_assert(top_err == TOX_ERR_GROUP_TOPIC_SET_OK); - Tox_Err_Group_Founder_Set_Topic_Lock lock_set_err; - tox_group_founder_set_topic_lock(tox0, group_number, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err); - ck_assert(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK); + Tox_Err_Group_Set_Topic_Lock lock_set_err; + tox_group_set_topic_lock(tox0, group_number, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err); + ck_assert(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK); - Tox_Err_Group_Founder_Set_Privacy_State priv_err; - tox_group_founder_set_privacy_state(tox0, group_number, NEW_PRIV_STATE, &priv_err); - ck_assert(priv_err == TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK); + Tox_Err_Group_Set_Privacy_State priv_err; + tox_group_set_privacy_state(tox0, group_number, NEW_PRIV_STATE, &priv_err); + ck_assert(priv_err == TOX_ERR_GROUP_SET_PRIVACY_STATE_OK); - Tox_Err_Group_Founder_Set_Password pass_set_err; - tox_group_founder_set_password(tox0, group_number, (const uint8_t *)PASSWORD, PASS_LEN, &pass_set_err); - ck_assert(pass_set_err == TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK); + Tox_Err_Group_Set_Password pass_set_err; + tox_group_set_password(tox0, group_number, (const uint8_t *)PASSWORD, PASS_LEN, &pass_set_err); + ck_assert(pass_set_err == TOX_ERR_GROUP_SET_PASSWORD_OK); - Tox_Err_Group_Founder_Set_Peer_Limit limit_set_err; - tox_group_founder_set_peer_limit(tox0, group_number, PEER_LIMIT, &limit_set_err); - ck_assert(limit_set_err == TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK); + Tox_Err_Group_Set_Peer_Limit limit_set_err; + tox_group_set_peer_limit(tox0, group_number, PEER_LIMIT, &limit_set_err); + ck_assert(limit_set_err == TOX_ERR_GROUP_SET_PEER_LIMIT_OK); // change self state Tox_Err_Group_Self_Name_Set n_err; @@ -241,8 +246,8 @@ static void group_save_test(AutoTox *autotoxes) ck_assert(options != nullptr); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); - tox_options_set_savedata_data(options, save, save_length); + tox_options_set_experimental_groups_persistence(options, true); Tox *new_tox = tox_new_log(options, nullptr, nullptr); @@ -278,7 +283,11 @@ int main(void) Run_Auto_Options autotest_opts = default_run_auto_options(); autotest_opts.graph = GRAPH_COMPLETE; - run_auto_test(nullptr, NUM_GROUP_TOXES, group_save_test, sizeof(State), &autotest_opts); + Tox_Options *opts = tox_options_new(nullptr); + ck_assert(opts != nullptr); + tox_options_set_experimental_groups_persistence(opts, true); + run_auto_test(opts, NUM_GROUP_TOXES, group_save_test, sizeof(State), &autotest_opts); + tox_options_free(opts); return 0; } diff --git a/auto_tests/group_state_test.c b/auto_tests/group_state_test.c index c506f802..bcbe7cd6 100644 --- a/auto_tests/group_state_test.c +++ b/auto_tests/group_state_test.c @@ -60,66 +60,97 @@ static bool all_group_peers_connected(const AutoTox *autotoxes, uint32_t tox_cou return true; } -static void group_topic_lock_handler(Tox *tox, uint32_t groupnumber, Tox_Group_Topic_Lock topic_lock, +static void group_topic_lock_handler(const Tox_Event_Group_Topic_Lock *event, void *user_data) { - Tox_Err_Group_State_Queries err; - Tox_Group_Topic_Lock current_topic_lock = tox_group_get_topic_lock(tox, groupnumber, &err); + const AutoTox *autotox = (const AutoTox *)user_data; + ck_assert(autotox != nullptr); - ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK); + const uint32_t groupnumber = tox_event_group_topic_lock_get_group_number(event); + const Tox_Group_Topic_Lock topic_lock = tox_event_group_topic_lock_get_topic_lock(event); + + Tox_Err_Group_State_Query err; + Tox_Group_Topic_Lock current_topic_lock = tox_group_get_topic_lock(autotox->tox, groupnumber, &err); + + ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert_msg(current_topic_lock == topic_lock, "topic locks don't match in callback: %d %d", topic_lock, current_topic_lock); } -static void group_voice_state_handler(Tox *tox, uint32_t groupnumber, Tox_Group_Voice_State voice_state, +static void group_voice_state_handler(const Tox_Event_Group_Voice_State *event, void *user_data) { - Tox_Err_Group_State_Queries err; - Tox_Group_Voice_State current_voice_state = tox_group_get_voice_state(tox, groupnumber, &err); + const AutoTox *autotox = (const AutoTox *)user_data; + ck_assert(autotox != nullptr); - ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK); + const uint32_t groupnumber = tox_event_group_voice_state_get_group_number(event); + const Tox_Group_Voice_State voice_state = tox_event_group_voice_state_get_voice_state(event); + + Tox_Err_Group_State_Query err; + Tox_Group_Voice_State current_voice_state = tox_group_get_voice_state(autotox->tox, groupnumber, &err); + + ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert_msg(current_voice_state == voice_state, "voice states don't match in callback: %d %d", voice_state, current_voice_state); } -static void group_privacy_state_handler(Tox *tox, uint32_t groupnumber, Tox_Group_Privacy_State privacy_state, +static void group_privacy_state_handler(const Tox_Event_Group_Privacy_State *event, void *user_data) { - Tox_Err_Group_State_Queries err; - Tox_Group_Privacy_State current_pstate = tox_group_get_privacy_state(tox, groupnumber, &err); + const AutoTox *autotox = (const AutoTox *)user_data; + ck_assert(autotox != nullptr); - ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK); + const uint32_t groupnumber = tox_event_group_privacy_state_get_group_number(event); + const Tox_Group_Privacy_State privacy_state = tox_event_group_privacy_state_get_privacy_state(event); + + Tox_Err_Group_State_Query err; + Tox_Group_Privacy_State current_pstate = tox_group_get_privacy_state(autotox->tox, groupnumber, &err); + + ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert_msg(current_pstate == privacy_state, "privacy states don't match in callback"); } -static void group_peer_limit_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_limit, void *user_data) +static void group_peer_limit_handler(const Tox_Event_Group_Peer_Limit *event, void *user_data) { - Tox_Err_Group_State_Queries err; - uint32_t current_plimit = tox_group_get_peer_limit(tox, groupnumber, &err); + const AutoTox *autotox = (const AutoTox *)user_data; + ck_assert(autotox != nullptr); - ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK); + const uint32_t groupnumber = tox_event_group_peer_limit_get_group_number(event); + const uint32_t peer_limit = tox_event_group_peer_limit_get_peer_limit(event); + + Tox_Err_Group_State_Query err; + uint32_t current_plimit = tox_group_get_peer_limit(autotox->tox, groupnumber, &err); + + ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert_msg(peer_limit == current_plimit, "Peer limits don't match in callback: %u, %u\n", peer_limit, current_plimit); } -static void group_password_handler(Tox *tox, uint32_t groupnumber, const uint8_t *password, size_t length, +static void group_password_handler(const Tox_Event_Group_Password *event, void *user_data) { - Tox_Err_Group_State_Queries err; - size_t curr_pwlength = tox_group_get_password_size(tox, groupnumber, &err); + AutoTox *autotox = (AutoTox *)user_data; + ck_assert(autotox != nullptr); - ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK); + const uint32_t groupnumber = tox_event_group_password_get_group_number(event); + const uint8_t *password = tox_event_group_password_get_password(event); + const size_t length = tox_event_group_password_get_password_length(event); + + Tox_Err_Group_State_Query err; + size_t curr_pwlength = tox_group_get_password_size(autotox->tox, groupnumber, &err); + + ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(length == curr_pwlength); uint8_t current_password[TOX_GROUP_MAX_PASSWORD_SIZE]; - tox_group_get_password(tox, groupnumber, current_password, &err); + tox_group_get_password(autotox->tox, groupnumber, current_password, &err); - ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK); + ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert_msg(memcmp(current_password, password, length) == 0, "Passwords don't match: %s, %s", password, current_password); } -static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t peer_id, void *user_data) +static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); @@ -137,24 +168,24 @@ static int check_group_state(const Tox *tox, uint32_t groupnumber, uint32_t peer Tox_Group_Privacy_State priv_state, Tox_Group_Voice_State voice_state, const uint8_t *password, size_t pass_len, Tox_Group_Topic_Lock topic_lock) { - Tox_Err_Group_State_Queries query_err; + Tox_Err_Group_State_Query query_err; Tox_Group_Privacy_State my_priv_state = tox_group_get_privacy_state(tox, groupnumber, &query_err); - ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get privacy state: %d", query_err); + ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get privacy state: %d", query_err); if (my_priv_state != priv_state) { return -1; } uint32_t my_peer_limit = tox_group_get_peer_limit(tox, groupnumber, &query_err); - ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get peer limit: %d", query_err); + ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get peer limit: %d", query_err); if (my_peer_limit != peer_limit) { return -2; } size_t my_pass_len = tox_group_get_password_size(tox, groupnumber, &query_err); - ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get password size: %d", query_err); + ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get password size: %d", query_err); if (my_pass_len != pass_len) { return -5; @@ -163,10 +194,10 @@ static int check_group_state(const Tox *tox, uint32_t groupnumber, uint32_t peer if (password != nullptr && my_pass_len > 0) { ck_assert(my_pass_len <= TOX_GROUP_MAX_PASSWORD_SIZE); - uint8_t my_pass[TOX_GROUP_MAX_PASSWORD_SIZE]; + uint8_t my_pass[TOX_GROUP_MAX_PASSWORD_SIZE + 1]; tox_group_get_password(tox, groupnumber, my_pass, &query_err); my_pass[my_pass_len] = 0; - ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get password: %d", query_err); + ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get password: %d", query_err); if (memcmp(my_pass, password, my_pass_len) != 0) { return -6; @@ -175,7 +206,7 @@ static int check_group_state(const Tox *tox, uint32_t groupnumber, uint32_t peer /* Group name should never change */ size_t my_gname_len = tox_group_get_name_size(tox, groupnumber, &query_err); - ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get group name size: %d", query_err); + ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get group name size: %d", query_err); if (my_gname_len != GROUP_NAME_LEN) { return -7; @@ -183,7 +214,7 @@ static int check_group_state(const Tox *tox, uint32_t groupnumber, uint32_t peer ck_assert(my_gname_len <= TOX_GROUP_MAX_GROUP_NAME_LENGTH); - uint8_t my_gname[TOX_GROUP_MAX_GROUP_NAME_LENGTH]; + uint8_t my_gname[TOX_GROUP_MAX_GROUP_NAME_LENGTH + 1]; tox_group_get_name(tox, groupnumber, my_gname, &query_err); my_gname[my_gname_len] = 0; @@ -192,14 +223,14 @@ static int check_group_state(const Tox *tox, uint32_t groupnumber, uint32_t peer } Tox_Group_Topic_Lock current_topic_lock = tox_group_get_topic_lock(tox, groupnumber, &query_err); - ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get topic lock: %d", query_err); + ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get topic lock: %d", query_err); if (current_topic_lock != topic_lock) { return -9; } Tox_Group_Voice_State current_voice_state = tox_group_get_voice_state(tox, groupnumber, &query_err); - ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get voice state: %d", query_err); + ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get voice state: %d", query_err); if (current_voice_state != voice_state) { return -10; @@ -213,26 +244,26 @@ static void set_group_state(Tox *tox, uint32_t groupnumber, uint32_t peer_limit, Tox_Group_Topic_Lock topic_lock) { - Tox_Err_Group_Founder_Set_Peer_Limit limit_set_err; - tox_group_founder_set_peer_limit(tox, groupnumber, peer_limit, &limit_set_err); - ck_assert_msg(limit_set_err == TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK, "failed to set peer limit: %d", limit_set_err); + Tox_Err_Group_Set_Peer_Limit limit_set_err; + tox_group_set_peer_limit(tox, groupnumber, peer_limit, &limit_set_err); + ck_assert_msg(limit_set_err == TOX_ERR_GROUP_SET_PEER_LIMIT_OK, "failed to set peer limit: %d", limit_set_err); - Tox_Err_Group_Founder_Set_Privacy_State priv_err; - tox_group_founder_set_privacy_state(tox, groupnumber, priv_state, &priv_err); - ck_assert_msg(priv_err == TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK, "failed to set privacy state: %d", priv_err); + Tox_Err_Group_Set_Privacy_State priv_err; + tox_group_set_privacy_state(tox, groupnumber, priv_state, &priv_err); + ck_assert_msg(priv_err == TOX_ERR_GROUP_SET_PRIVACY_STATE_OK, "failed to set privacy state: %d", priv_err); - Tox_Err_Group_Founder_Set_Password pass_set_err; - tox_group_founder_set_password(tox, groupnumber, password, pass_len, &pass_set_err); - ck_assert_msg(pass_set_err == TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK, "failed to set password: %d", pass_set_err); + Tox_Err_Group_Set_Password pass_set_err; + tox_group_set_password(tox, groupnumber, password, pass_len, &pass_set_err); + ck_assert_msg(pass_set_err == TOX_ERR_GROUP_SET_PASSWORD_OK, "failed to set password: %d", pass_set_err); - Tox_Err_Group_Founder_Set_Topic_Lock lock_set_err; - tox_group_founder_set_topic_lock(tox, groupnumber, topic_lock, &lock_set_err); - ck_assert_msg(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, "failed to set topic lock: %d", + Tox_Err_Group_Set_Topic_Lock lock_set_err; + tox_group_set_topic_lock(tox, groupnumber, topic_lock, &lock_set_err); + ck_assert_msg(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, "failed to set topic lock: %d", lock_set_err); - Tox_Err_Group_Founder_Set_Voice_State voice_set_err; - tox_group_founder_set_voice_state(tox, groupnumber, voice_state, &voice_set_err); - ck_assert_msg(voice_set_err == TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK, "failed to set voice state: %d", + Tox_Err_Group_Set_Voice_State voice_set_err; + tox_group_set_voice_state(tox, groupnumber, voice_state, &voice_set_err); + ck_assert_msg(voice_set_err == TOX_ERR_GROUP_SET_VOICE_STATE_OK, "failed to set voice state: %d", voice_set_err); } @@ -241,12 +272,12 @@ static void group_state_test(AutoTox *autotoxes) ck_assert_msg(NUM_GROUP_TOXES >= 3, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES); for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { - tox_callback_group_privacy_state(autotoxes[i].tox, group_privacy_state_handler); - tox_callback_group_peer_limit(autotoxes[i].tox, group_peer_limit_handler); - tox_callback_group_password(autotoxes[i].tox, group_password_handler); - tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler); - tox_callback_group_voice_state(autotoxes[i].tox, group_voice_state_handler); - tox_callback_group_topic_lock(autotoxes[i].tox, group_topic_lock_handler); + tox_events_callback_group_privacy_state(autotoxes[i].dispatch, group_privacy_state_handler); + tox_events_callback_group_peer_limit(autotoxes[i].dispatch, group_peer_limit_handler); + tox_events_callback_group_password(autotoxes[i].dispatch, group_password_handler); + tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler); + tox_events_callback_group_voice_state(autotoxes[i].dispatch, group_voice_state_handler); + tox_events_callback_group_topic_lock(autotoxes[i].dispatch, group_topic_lock_handler); } Tox *tox0 = autotoxes[0].tox; @@ -263,11 +294,11 @@ static void group_state_test(AutoTox *autotoxes) (const uint8_t *)PASSWORD, PASS_LEN, TOX_GROUP_TOPIC_LOCK_ENABLED); /* Founder gets the Chat ID and implicitly shares it publicly */ - Tox_Err_Group_State_Queries id_err; + Tox_Err_Group_State_Query id_err; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; tox_group_get_chat_id(tox0, groupnum, chat_id, &id_err); - ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "tox_group_get_chat_id failed %d", id_err); + ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "tox_group_get_chat_id failed %d", id_err); /* All other peers join the group using the Chat ID and password */ for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) { diff --git a/auto_tests/group_sync_test.c b/auto_tests/group_sync_test.c index d635f76f..146c2258 100644 --- a/auto_tests/group_sync_test.c +++ b/auto_tests/group_sync_test.c @@ -96,38 +96,42 @@ static void peers_cleanup(Peers *peers) free(peers); } -static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t peer_id, void *user_data) +static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); State *state = (State *)autotox->state; + const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event); + ck_assert(add_peer(state->peers, peer_id) == 0); } -static void group_peer_exit_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, Tox_Group_Exit_Type exit_type, - const uint8_t *name, size_t name_length, const uint8_t *part_message, - size_t length, void *user_data) +static void group_peer_exit_handler(const Tox_Event_Group_Peer_Exit *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); State *state = (State *)autotox->state; + const uint32_t peer_id = tox_event_group_peer_exit_get_peer_id(event); + ck_assert(del_peer(state->peers, peer_id) == 0); } -static void group_topic_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *topic, - size_t length, void *user_data) +static void group_topic_handler(const Tox_Event_Group_Topic *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); State *state = (State *)autotox->state; + const uint8_t *topic = tox_event_group_topic_get_topic(event); + const size_t length = tox_event_group_topic_get_topic_length(event); + ck_assert(length <= TOX_GROUP_MAX_TOPIC_LENGTH); memcpy(state->callback_topic, (const char *)topic, length); @@ -201,7 +205,7 @@ static void role_spam(const Random *rng, AutoTox *autotoxes, uint32_t num_peers, int64_t peer_id = state0->peers->peer_ids[idx]; if (peer_id >= 0) { - tox_group_mod_set_role(tox0, groupnumber, (uint32_t)peer_id, f_role, nullptr); + tox_group_set_role(tox0, groupnumber, (uint32_t)peer_id, f_role, nullptr); } // mods randomly promote or demote one of the non-mods @@ -218,7 +222,7 @@ static void role_spam(const Random *rng, AutoTox *autotoxes, uint32_t num_peers, peer_id = state_j->peers->peer_ids[i]; if (peer_id >= 0) { - tox_group_mod_set_role(autotoxes[j].tox, groupnumber, (uint32_t)peer_id, role, nullptr); + tox_group_set_role(autotoxes[j].tox, groupnumber, (uint32_t)peer_id, role, nullptr); } } } @@ -260,14 +264,14 @@ static bool all_peers_have_same_topic(const AutoTox *autotoxes, uint32_t num_pee { uint8_t expected_topic[TOX_GROUP_MAX_TOPIC_LENGTH]; - Tox_Err_Group_State_Queries query_err; + Tox_Err_Group_State_Query query_err; size_t expected_topic_length = tox_group_get_topic_size(autotoxes[0].tox, groupnumber, &query_err); - ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK); + ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); tox_group_get_topic(autotoxes[0].tox, groupnumber, expected_topic, &query_err); - ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK); + ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); const State *state0 = (const State *)autotoxes[0].state; @@ -282,7 +286,7 @@ static bool all_peers_have_same_topic(const AutoTox *autotoxes, uint32_t num_pee for (size_t i = 1; i < num_peers; ++i) { size_t topic_length = tox_group_get_topic_size(autotoxes[i].tox, groupnumber, &query_err); - ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK); + ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); if (topic_length != expected_topic_length) { return false; @@ -291,7 +295,7 @@ static bool all_peers_have_same_topic(const AutoTox *autotoxes, uint32_t num_pee uint8_t topic[TOX_GROUP_MAX_TOPIC_LENGTH]; tox_group_get_topic(autotoxes[i].tox, groupnumber, topic, &query_err); - ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK); + ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); if (memcmp(expected_topic, (const char *)topic, topic_length) != 0) { return false; @@ -331,13 +335,13 @@ static void topic_spam(const Random *rng, AutoTox *autotoxes, uint32_t num_peers static void group_sync_test(AutoTox *autotoxes) { ck_assert(NUM_GROUP_TOXES >= 5); - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { - tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler); - tox_callback_group_topic(autotoxes[i].tox, group_topic_handler); - tox_callback_group_peer_exit(autotoxes[i].tox, group_peer_exit_handler); + tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler); + tox_events_callback_group_topic(autotoxes[i].dispatch, group_topic_handler); + tox_events_callback_group_peer_exit(autotoxes[i].dispatch, group_peer_exit_handler); State *state = (State *)autotoxes[i].state; state->peers = (Peers *)calloc(1, sizeof(Peers)); @@ -356,11 +360,11 @@ static void group_sync_test(AutoTox *autotoxes) fprintf(stderr, "tox0 creats new group and invites all his friends"); - Tox_Err_Group_State_Queries id_err; + Tox_Err_Group_State_Query id_err; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; tox_group_get_chat_id(tox0, groupnumber, chat_id, &id_err); - ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", id_err); + ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "%d", id_err); for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) { Tox_Err_Group_Join join_err; @@ -375,9 +379,9 @@ static void group_sync_test(AutoTox *autotoxes) fprintf(stderr, "%d peers joined the group\n", NUM_GROUP_TOXES); - Tox_Err_Group_Founder_Set_Topic_Lock lock_set_err; - tox_group_founder_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err); - ck_assert_msg(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, "failed to disable topic lock: %d", + Tox_Err_Group_Set_Topic_Lock lock_set_err; + tox_group_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err); + ck_assert_msg(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, "failed to disable topic lock: %d", lock_set_err); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); @@ -388,8 +392,8 @@ static void group_sync_test(AutoTox *autotoxes) iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); - tox_group_founder_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_ENABLED, &lock_set_err); - ck_assert_msg(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, "failed to enable topic lock: %d", + tox_group_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_ENABLED, &lock_set_err); + ck_assert_msg(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, "failed to enable topic lock: %d", lock_set_err); do { @@ -398,12 +402,12 @@ static void group_sync_test(AutoTox *autotoxes) && !all_peers_see_same_roles(autotoxes, NUM_GROUP_TOXES, groupnumber) && state0->peers->num_peers != NUM_GROUP_TOXES - 1); - Tox_Err_Group_Mod_Set_Role role_err; + Tox_Err_Group_Set_Role role_err; for (size_t i = 0; i < state0->peers->num_peers; ++i) { - tox_group_mod_set_role(tox0, groupnumber, (uint32_t)state0->peers->peer_ids[i], TOX_GROUP_ROLE_MODERATOR, - &role_err); - ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err); + tox_group_set_role(tox0, groupnumber, (uint32_t)state0->peers->peer_ids[i], TOX_GROUP_ROLE_MODERATOR, + &role_err); + ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err); } fprintf(stderr, "founder enabled topic lock and set all peers to moderator role\n"); @@ -419,9 +423,9 @@ static void group_sync_test(AutoTox *autotoxes) fprintf(stderr, "founder demoting %u moderators to user\n", num_demoted); for (size_t i = 0; i < num_demoted; ++i) { - tox_group_mod_set_role(tox0, groupnumber, (uint32_t)state0->peers->peer_ids[i], TOX_GROUP_ROLE_USER, - &role_err); - ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set user. error: %d", role_err); + tox_group_set_role(tox0, groupnumber, (uint32_t)state0->peers->peer_ids[i], TOX_GROUP_ROLE_USER, + &role_err); + ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set user. error: %d", role_err); } do { diff --git a/auto_tests/group_tcp_test.c b/auto_tests/group_tcp_test.c index 78a339d8..9bb7ebcb 100644 --- a/auto_tests/group_tcp_test.c +++ b/auto_tests/group_tcp_test.c @@ -19,32 +19,43 @@ typedef struct State { uint32_t peer_id[NUM_GROUP_TOXES - 1]; } State; -static void group_invite_handler(Tox *tox, uint32_t friend_number, const uint8_t *invite_data, size_t length, - const uint8_t *group_name, size_t group_name_length, void *user_data) +static void group_invite_handler(const Tox_Event_Group_Invite *event, void *user_data) { + AutoTox *autotox = (AutoTox *)user_data; + ck_assert(autotox != nullptr); + + const uint32_t friend_number = tox_event_group_invite_get_friend_number(event); + const uint8_t *invite_data = tox_event_group_invite_get_invite_data(event); + const size_t length = tox_event_group_invite_get_invite_data_length(event); + printf("Accepting friend invite\n"); Tox_Err_Group_Invite_Accept err_accept; - tox_group_invite_accept(tox, friend_number, invite_data, length, (const uint8_t *)"test", 4, + tox_group_invite_accept(autotox->tox, friend_number, invite_data, length, (const uint8_t *)"test", 4, nullptr, 0, &err_accept); ck_assert(err_accept == TOX_ERR_GROUP_INVITE_ACCEPT_OK); } -static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, void *user_data) +static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) { AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); State *state = (State *)autotox->state; + + const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event); + fprintf(stderr, "joined: %zu, %u\n", state->num_peers, peer_id); ck_assert_msg(state->num_peers < NUM_GROUP_TOXES - 1, "%zu", state->num_peers); state->peer_id[state->num_peers++] = peer_id; } -static void group_private_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type, - const uint8_t *message, size_t length, void *user_data) +static void group_private_message_handler(const Tox_Event_Group_Private_Message *event, void *user_data) { + const uint8_t *message = tox_event_group_private_message_get_message(event); + const size_t length = tox_event_group_private_message_get_message_length(event); + AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); @@ -58,9 +69,11 @@ static void group_private_message_handler(Tox *tox, uint32_t groupnumber, uint32 state->got_code = true; } -static void group_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type, - const uint8_t *message, size_t length, uint32_t message_id, void *user_data) +static void group_message_handler(const Tox_Event_Group_Message *event, void *user_data) { + const uint8_t *message = tox_event_group_message_get_message(event); + const size_t length = tox_event_group_message_get_message_length(event); + AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); @@ -133,12 +146,12 @@ static void group_tcp_test(AutoTox *autotoxes) State *state1 = (State *)autotoxes[1].state; for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { - tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler); - tox_callback_group_private_message(autotoxes[i].tox, group_private_message_handler); + tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler); + tox_events_callback_group_private_message(autotoxes[i].dispatch, group_private_message_handler); } - tox_callback_group_message(autotoxes[1].tox, group_message_handler); - tox_callback_group_invite(autotoxes[1].tox, group_invite_handler); + tox_events_callback_group_message(autotoxes[1].dispatch, group_message_handler); + tox_events_callback_group_invite(autotoxes[1].dispatch, group_invite_handler); Tox_Err_Group_New new_err; uint32_t groupnumber = tox_group_new(autotoxes[0].tox, TOX_GROUP_PRIVACY_STATE_PUBLIC, (const uint8_t *)"test", 4, @@ -147,11 +160,11 @@ static void group_tcp_test(AutoTox *autotoxes) iterate_group(autotoxes, NUM_GROUP_TOXES, GROUP_ITERATION_INTERVAL); - Tox_Err_Group_State_Queries id_err; + Tox_Err_Group_State_Query id_err; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; tox_group_get_chat_id(autotoxes[0].tox, groupnumber, chat_id, &id_err); - ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", id_err); + ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "%d", id_err); printf("Tox 0 created new group...\n"); @@ -168,7 +181,6 @@ static void group_tcp_test(AutoTox *autotoxes) printf("%d peers successfully joined. Waiting for code...\n", NUM_GROUP_TOXES); printf("Tox 0 sending secret code to all peers\n"); - for (size_t i = 0; i < NUM_GROUP_TOXES - 1; ++i) { Tox_Err_Group_Send_Private_Message perr; diff --git a/auto_tests/group_topic_test.c b/auto_tests/group_topic_test.c index 60f78acf..c8d84cb7 100644 --- a/auto_tests/group_topic_test.c +++ b/auto_tests/group_topic_test.c @@ -55,8 +55,11 @@ static bool all_group_peers_connected(const AutoTox *autotoxes, uint32_t tox_cou return true; } -static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, void *user_data) +static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) { + //const uint32_t group_number = tox_event_group_peer_join_get_group_number(event); + const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event); + AutoTox *autotox = (AutoTox *)user_data; ck_assert(autotox != nullptr); @@ -65,28 +68,41 @@ static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t pee state->peer_id = peer_id; } -static void group_topic_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *topic, - size_t length, void *user_data) +static void group_topic_handler(const Tox_Event_Group_Topic *event, void *user_data) { - ck_assert(length <= TOX_GROUP_MAX_TOPIC_LENGTH); + AutoTox *autotox = (AutoTox *)user_data; + ck_assert(autotox != nullptr); - Tox_Err_Group_State_Queries query_err; + const uint32_t group_number = tox_event_group_topic_get_group_number(event); + //const uint32_t peer_id = tox_event_group_topic_get_peer_id(event); + const uint8_t *topic = tox_event_group_topic_get_topic(event); + const uint32_t topic_length = tox_event_group_topic_get_topic_length(event); + + ck_assert(topic_length <= TOX_GROUP_MAX_TOPIC_LENGTH); + + Tox_Err_Group_State_Query query_err; uint8_t topic2[TOX_GROUP_MAX_TOPIC_LENGTH]; - tox_group_get_topic(tox, groupnumber, topic2, &query_err); - ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK); + tox_group_get_topic(autotox->tox, group_number, topic2, &query_err); + ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); - size_t topic_length = tox_group_get_topic_size(tox, groupnumber, &query_err); - ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK); - ck_assert_msg(topic_length == length && memcmp(topic, topic2, length) == 0, + size_t topic_length_getter = tox_group_get_topic_size(autotox->tox, group_number, &query_err); + ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); + ck_assert_msg(topic_length_getter == topic_length && memcmp(topic, topic2, topic_length) == 0, "topic differs in callback: %s, %s", topic, topic2); } -static void group_topic_lock_handler(Tox *tox, uint32_t groupnumber, Tox_Group_Topic_Lock topic_lock, void *user_data) +static void group_topic_lock_handler(const Tox_Event_Group_Topic_Lock *event, void *user_data) { - Tox_Err_Group_State_Queries err; - Tox_Group_Topic_Lock current_lock = tox_group_get_topic_lock(tox, groupnumber, &err); + const AutoTox *autotox = (const AutoTox *)user_data; + ck_assert(autotox != nullptr); - ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK); + const uint32_t group_number = tox_event_group_topic_lock_get_group_number(event); + const Tox_Group_Topic_Lock topic_lock = tox_event_group_topic_lock_get_topic_lock(event); + + Tox_Err_Group_State_Query err; + Tox_Group_Topic_Lock current_lock = tox_group_get_topic_lock(autotox->tox, group_number, &err); + + ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert_msg(topic_lock == current_lock, "topic locks differ in callback"); } @@ -107,10 +123,10 @@ static bool set_topic(Tox *tox, uint32_t groupnumber, const char *topic, size_t */ static int check_topic(const Tox *tox, uint32_t groupnumber, const char *expected_topic, size_t expected_length) { - Tox_Err_Group_State_Queries query_err; + Tox_Err_Group_State_Query query_err; size_t topic_length = tox_group_get_topic_size(tox, groupnumber, &query_err); - if (query_err != TOX_ERR_GROUP_STATE_QUERIES_OK) { + if (query_err != TOX_ERR_GROUP_STATE_QUERY_OK) { return -1; } @@ -121,7 +137,7 @@ static int check_topic(const Tox *tox, uint32_t groupnumber, const char *expecte uint8_t topic[TOX_GROUP_MAX_TOPIC_LENGTH]; tox_group_get_topic(tox, groupnumber, topic, &query_err); - if (query_err != TOX_ERR_GROUP_STATE_QUERIES_OK) { + if (query_err != TOX_ERR_GROUP_STATE_QUERY_OK) { return -3; } @@ -140,9 +156,9 @@ static void wait_topic_lock(AutoTox *autotoxes, uint32_t groupnumber, Tox_Group_ uint32_t count = 0; for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { - Tox_Err_Group_State_Queries err; + Tox_Err_Group_State_Query err; Tox_Group_Topic_Lock topic_lock = tox_group_get_topic_lock(autotoxes[i].tox, groupnumber, &err); - ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK); + ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK); if (topic_lock == expected_lock) { ++count; @@ -205,17 +221,18 @@ static void group_topic_test(AutoTox *autotoxes) { ck_assert_msg(NUM_GROUP_TOXES >= 3, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES); - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); Tox *tox0 = autotoxes[0].tox; + Tox_Dispatch *dispatch0 = autotoxes[0].dispatch; const State *state0 = (const State *)autotoxes[0].state; - tox_callback_group_peer_join(tox0, group_peer_join_handler); + tox_events_callback_group_peer_join(dispatch0, group_peer_join_handler); for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { - tox_callback_group_topic(autotoxes[i].tox, group_topic_handler); - tox_callback_group_topic_lock(autotoxes[i].tox, group_topic_lock_handler); + tox_events_callback_group_topic(autotoxes[i].dispatch, group_topic_handler); + tox_events_callback_group_topic_lock(autotoxes[i].dispatch, group_topic_lock_handler); } /* Tox1 creates a group and is the founder of a newly created group */ @@ -233,11 +250,11 @@ static void group_topic_test(AutoTox *autotoxes) ck_assert_msg(s_ret, "Founder failed to set topic"); /* Founder gets the Chat ID and implicitly shares it publicly */ - Tox_Err_Group_State_Queries id_err; + Tox_Err_Group_State_Query id_err; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; tox_group_get_chat_id(tox0, groupnumber, chat_id, &id_err); - ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "tox_group_get_chat_id failed %d", id_err); + ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "tox_group_get_chat_id failed %d", id_err); /* All other peers join the group using the Chat ID */ for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) { @@ -257,9 +274,9 @@ static void group_topic_test(AutoTox *autotoxes) wait_state_topic(autotoxes, groupnumber, TOPIC, TOPIC_LEN); /* Founder disables topic lock */ - Tox_Err_Group_Founder_Set_Topic_Lock lock_set_err; - tox_group_founder_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err); - ck_assert_msg(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, "failed to disable topic lock: %d", + Tox_Err_Group_Set_Topic_Lock lock_set_err; + tox_group_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err); + ck_assert_msg(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, "failed to disable topic lock: %d", lock_set_err); fprintf(stderr, "Topic lock disabled\n"); @@ -273,9 +290,9 @@ static void group_topic_test(AutoTox *autotoxes) ck_assert_msg(change_count == NUM_GROUP_TOXES, "%u peers changed the topic with topic lock disabled", change_count); /* founder silences the last peer he saw join */ - Tox_Err_Group_Mod_Set_Role merr; - tox_group_mod_set_role(tox0, groupnumber, state0->peer_id, TOX_GROUP_ROLE_OBSERVER, &merr); - ck_assert_msg(merr == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set %u to observer role: %d", state0->peer_id, merr); + Tox_Err_Group_Set_Role merr; + tox_group_set_role(tox0, groupnumber, state0->peer_id, TOX_GROUP_ROLE_OBSERVER, &merr); + ck_assert_msg(merr == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set %u to observer role: %d", state0->peer_id, merr); fprintf(stderr, "Random peer is set to observer\n"); @@ -287,8 +304,8 @@ static void group_topic_test(AutoTox *autotoxes) ck_assert_msg(change_count == NUM_GROUP_TOXES - 1, "%u peers changed the topic with a silenced peer", change_count); /* Founder enables topic lock and sets topic back to original */ - tox_group_founder_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_ENABLED, &lock_set_err); - ck_assert_msg(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, "failed to enable topic lock: %d", + tox_group_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_ENABLED, &lock_set_err); + ck_assert_msg(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, "failed to enable topic lock: %d", lock_set_err); fprintf(stderr, "Topic lock enabled\n"); diff --git a/auto_tests/lossless_packet_test.c b/auto_tests/lossless_packet_test.c index 9d3f824c..91a6a59f 100644 --- a/auto_tests/lossless_packet_test.c +++ b/auto_tests/lossless_packet_test.c @@ -18,13 +18,17 @@ typedef struct State { #define LOSSLESS_PACKET_FILLER 160 -static void handle_lossless_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data) +static void handle_lossless_packet(const Tox_Event_Friend_Lossless_Packet *event, void *user_data) { + //const uint32_t friend_number = tox_event_friend_lossless_packet_get_friend_number(event); + const uint8_t *data = tox_event_friend_lossless_packet_get_data(event); + const uint32_t data_length = tox_event_friend_lossless_packet_get_data_length(event); + uint8_t *cmp_packet = (uint8_t *)malloc(tox_max_custom_packet_size()); ck_assert(cmp_packet != nullptr); memset(cmp_packet, LOSSLESS_PACKET_FILLER, tox_max_custom_packet_size()); - if (length == tox_max_custom_packet_size() && memcmp(data, cmp_packet, tox_max_custom_packet_size()) == 0) { + if (data_length == tox_max_custom_packet_size() && memcmp(data, cmp_packet, tox_max_custom_packet_size()) == 0) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; state->custom_packet_received = true; @@ -35,7 +39,7 @@ static void handle_lossless_packet(Tox *tox, uint32_t friend_number, const uint8 static void test_lossless_packet(AutoTox *autotoxes) { - tox_callback_friend_lossless_packet(autotoxes[1].tox, &handle_lossless_packet); + tox_events_callback_friend_lossless_packet(autotoxes[1].dispatch, &handle_lossless_packet); const size_t packet_size = tox_max_custom_packet_size() + 1; uint8_t *packet = (uint8_t *)malloc(packet_size); ck_assert(packet != nullptr); diff --git a/auto_tests/lossy_packet_test.c b/auto_tests/lossy_packet_test.c index 30745410..200977d1 100644 --- a/auto_tests/lossy_packet_test.c +++ b/auto_tests/lossy_packet_test.c @@ -18,13 +18,17 @@ typedef struct State { #define LOSSY_PACKET_FILLER 200 -static void handle_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data) +static void handle_lossy_packet(const Tox_Event_Friend_Lossy_Packet *event, void *user_data) { + //const uint32_t friend_number = tox_event_friend_lossy_packet_get_friend_number(event); + const uint8_t *data = tox_event_friend_lossy_packet_get_data(event); + const uint32_t data_length = tox_event_friend_lossy_packet_get_data_length(event); + uint8_t *cmp_packet = (uint8_t *)malloc(tox_max_custom_packet_size()); ck_assert(cmp_packet != nullptr); memset(cmp_packet, LOSSY_PACKET_FILLER, tox_max_custom_packet_size()); - if (length == tox_max_custom_packet_size() && memcmp(data, cmp_packet, tox_max_custom_packet_size()) == 0) { + if (data_length == tox_max_custom_packet_size() && memcmp(data, cmp_packet, tox_max_custom_packet_size()) == 0) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; state->custom_packet_received = true; @@ -35,7 +39,7 @@ static void handle_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_t static void test_lossy_packet(AutoTox *autotoxes) { - tox_callback_friend_lossy_packet(autotoxes[1].tox, &handle_lossy_packet); + tox_events_callback_friend_lossy_packet(autotoxes[1].dispatch, &handle_lossy_packet); const size_t packet_size = tox_max_custom_packet_size() + 1; uint8_t *packet = (uint8_t *)malloc(packet_size); ck_assert(packet != nullptr); diff --git a/auto_tests/network_test.c b/auto_tests/network_test.c index df3b625a..76cb94a1 100644 --- a/auto_tests/network_test.c +++ b/auto_tests/network_test.c @@ -20,7 +20,7 @@ static void test_addr_resolv_localhost(void) errno = 0; #endif - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); const char localhost[] = "localhost"; diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c index 8a5a821c..3a81df41 100644 --- a/auto_tests/onion_test.c +++ b/auto_tests/onion_test.c @@ -37,7 +37,7 @@ static void do_onion(Mono_Time *mono_time, Onion *onion) static int handled_test_1; static int handle_test_1(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { - Onion *onion = (Onion *)object; + const Onion *onion = (const Onion *)object; const char req_message[] = "Install Gentoo"; uint8_t req_packet[1 + sizeof(req_message)]; @@ -99,7 +99,7 @@ static uint8_t test_3_pub_key[CRYPTO_PUBLIC_KEY_SIZE]; static uint8_t test_3_ping_id[CRYPTO_SHA256_SIZE]; static int handle_test_3(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { - Onion *onion = (Onion *)object; + const Onion *onion = (const Onion *)object; if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) { return 1; @@ -118,7 +118,6 @@ static int handle_test_3(void *object, const IP_Port *source, const uint8_t *pac return 1; } - if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0) { return 1; } @@ -135,7 +134,7 @@ static int handle_test_3(void *object, const IP_Port *source, const uint8_t *pac static int handle_test_3_old(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { - Onion *onion = (Onion *)object; + const Onion *onion = (const Onion *)object; if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) { return 1; @@ -154,7 +153,6 @@ static int handle_test_3_old(void *object, const IP_Port *source, const uint8_t return 1; } - if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0) { return 1; } @@ -171,7 +169,7 @@ static uint8_t nonce[CRYPTO_NONCE_SIZE]; static int handled_test_4; static int handle_test_4(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { - Onion *onion = (Onion *)object; + const Onion *onion = (const Onion *)object; if (length != (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + sizeof("Install gentoo") + CRYPTO_MAC_SIZE)) { @@ -223,11 +221,11 @@ static Networking_Core *new_networking(const Logger *log, const Memory *mem, con static void test_basic(void) { uint32_t index[] = { 1, 2, 3 }; - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); Logger *log1 = logger_new(); @@ -288,7 +286,7 @@ static void test_basic(void) networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_test_3, onion1); networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_test_3_old, onion1); ck_assert_msg((onion1_a != nullptr) && (onion2_a != nullptr), "Onion_Announce failed initializing."); - uint8_t zeroes[64] = {0}; + const uint8_t zeroes[64] = {0}; random_bytes(rng, sb_data, sizeof(sb_data)); uint64_t s; memcpy(&s, sb_data, sizeof(uint64_t)); @@ -407,7 +405,7 @@ static Onions *new_onions(const Memory *mem, const Random *rng, uint16_t port, u { IP ip = get_loopback(); ip.ip.v6.uint8[15] = 1; - const Network *ns = system_network(); + const Network *ns = os_network(); Onions *on = (Onions *)malloc(sizeof(Onions)); if (!on) { @@ -576,9 +574,9 @@ static void test_announce(void) { uint32_t index[NUM_ONIONS]; Onions *onions[NUM_ONIONS]; - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); for (uint32_t i = 0; i < NUM_ONIONS; ++i) { diff --git a/auto_tests/overflow_recvq_test.c b/auto_tests/overflow_recvq_test.c index 8855f70f..d250b4d7 100644 --- a/auto_tests/overflow_recvq_test.c +++ b/auto_tests/overflow_recvq_test.c @@ -11,9 +11,13 @@ typedef struct State { #define NUM_MSGS 40000 -static void handle_friend_message(Tox *tox, uint32_t friend_number, Tox_Message_Type type, - const uint8_t *message, size_t length, void *user_data) +static void handle_friend_message(const Tox_Event_Friend_Message *event, void *user_data) { + //const uint32_t friend_number = tox_event_friend_message_get_friend_number(event); + //const Tox_Message_Type type = tox_event_friend_message_get_type(event); + //const uint8_t *message = tox_event_friend_message_get_message(event); + //const uint32_t message_length = tox_event_friend_message_get_message_length(event); + const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; state->recv_count++; @@ -21,7 +25,7 @@ static void handle_friend_message(Tox *tox, uint32_t friend_number, Tox_Message_ static void net_crypto_overflow_test(AutoTox *autotoxes) { - tox_callback_friend_message(autotoxes[0].tox, handle_friend_message); + tox_events_callback_friend_message(autotoxes[0].dispatch, handle_friend_message); printf("sending many messages to tox0\n"); diff --git a/auto_tests/proxy_test.c b/auto_tests/proxy_test.c index d6f2d8cf..d20c14f2 100644 --- a/auto_tests/proxy_test.c +++ b/auto_tests/proxy_test.c @@ -24,10 +24,10 @@ static bool try_bootstrap(Tox *tox1, Tox *tox2, Tox *tox3, Tox *tox4) tox_self_get_connection_status(tox3) != TOX_CONNECTION_NONE && tox_self_get_connection_status(tox4) != TOX_CONNECTION_NONE) { printf("%d %d %d %d\n", - tox_self_get_connection_status(tox1), - tox_self_get_connection_status(tox2), - tox_self_get_connection_status(tox3), - tox_self_get_connection_status(tox4)); + tox_self_get_connection_status(tox1), + tox_self_get_connection_status(tox2), + tox_self_get_connection_status(tox3), + tox_self_get_connection_status(tox4)); return true; } @@ -38,10 +38,10 @@ static bool try_bootstrap(Tox *tox1, Tox *tox2, Tox *tox3, Tox *tox4) if (i % 10 == 0) { printf("%d %d %d %d\n", - tox_self_get_connection_status(tox1), - tox_self_get_connection_status(tox2), - tox_self_get_connection_status(tox3), - tox_self_get_connection_status(tox4)); + tox_self_get_connection_status(tox1), + tox_self_get_connection_status(tox2), + tox_self_get_connection_status(tox3), + tox_self_get_connection_status(tox4)); } c_sleep(tox_iteration_interval(tox1)); diff --git a/auto_tests/reconnect_test.c b/auto_tests/reconnect_test.c index 253f66b0..8a4b31c4 100644 --- a/auto_tests/reconnect_test.c +++ b/auto_tests/reconnect_test.c @@ -51,7 +51,7 @@ static bool all_disconnected_from(uint32_t tox_count, AutoTox *autotoxes, uint32 static void test_reconnect(AutoTox *autotoxes) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); const time_t test_start_time = time(nullptr); @@ -67,7 +67,12 @@ static void test_reconnect(AutoTox *autotoxes) do { for (uint16_t i = 0; i < TOX_COUNT; ++i) { if (i != disconnect) { - tox_iterate(autotoxes[i].tox, &autotoxes[i]); + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(autotoxes[i].tox, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + tox_dispatch_invoke(autotoxes[i].dispatch, events, &autotoxes[i]); + tox_events_free(events); + autotoxes[i].clock += 1000; } } diff --git a/auto_tests/save_compatibility_test.c b/auto_tests/save_compatibility_test.c index 74d7b51a..75dd4f21 100644 --- a/auto_tests/save_compatibility_test.c +++ b/auto_tests/save_compatibility_test.c @@ -9,7 +9,8 @@ #include #include -#define LOADED_SAVE_FILE "../auto_tests/data/save.tox" +#define LOADED_SAVE_FILE_BIG "../auto_tests/data/save.tox.big" +#define LOADED_SAVE_FILE_LITTLE "../auto_tests/data/save.tox.little" // Information from the save file #define EXPECTED_NAME "name" @@ -18,7 +19,7 @@ #define EXPECTED_STATUS_MESSAGE_SIZE strlen(EXPECTED_STATUS_MESSAGE) #define EXPECTED_NUM_FRIENDS 1 #define EXPECTED_NOSPAM "4C762C7D" -#define EXPECTED_TOX_ID "B70E97D41F69B7F4C42A5BC7BD7A76B95B8030BE1B7C0E9E6FC19FC4ABEB195B4C762C7D800B" +#define EXPECTED_TOX_ID "E776E9A993EE3CAE04F5946D9AC66FBBAA8C63A95A94B41942353C6DC1739B4B4C762C7DA7B9" static size_t get_file_size(const char *save_path) { @@ -135,6 +136,13 @@ static void test_save_compatibility(const char *save_path) tox_kill(tox); } +static bool is_little_endian(void) +{ + uint16_t x = 1; + return ((uint8_t *)&x)[0] == 1; +} + +// cppcheck-suppress constParameter int main(int argc, char *argv[]) { char base_path[4096] = {0}; @@ -152,10 +160,15 @@ int main(int argc, char *argv[]) base_path[strrchr(base_path, '/') - base_path] = '\0'; } - char save_path[4096 + sizeof(LOADED_SAVE_FILE)]; - snprintf(save_path, sizeof(save_path), "%s/%s", base_path, LOADED_SAVE_FILE); - - test_save_compatibility(save_path); + if (is_little_endian()) { + char save_path[4096 + sizeof(LOADED_SAVE_FILE_LITTLE)]; + snprintf(save_path, sizeof(save_path), "%s/%s", base_path, LOADED_SAVE_FILE_LITTLE); + test_save_compatibility(save_path); + } else { + char save_path[4096 + sizeof(LOADED_SAVE_FILE_BIG)]; + snprintf(save_path, sizeof(save_path), "%s/%s", base_path, LOADED_SAVE_FILE_BIG); + test_save_compatibility(save_path); + } return 0; } diff --git a/auto_tests/save_friend_test.c b/auto_tests/save_friend_test.c index 80a6ed03..339690f2 100644 --- a/auto_tests/save_friend_test.c +++ b/auto_tests/save_friend_test.c @@ -22,13 +22,12 @@ struct test_data { static void set_random(Tox *m, const Random *rng, bool (*setter)(Tox *, const uint8_t *, size_t, Tox_Err_Set_Info *), size_t length) { VLA(uint8_t, text, length); - uint32_t i; - for (i = 0; i < length; ++i) { + for (uint32_t i = 0; i < length; ++i) { text[i] = random_u08(rng); } - setter(m, text, SIZEOF_VLA(text), nullptr); + setter(m, text, length, nullptr); } static void alloc_string(uint8_t **to, size_t length) @@ -44,18 +43,25 @@ static void set_string(uint8_t **to, const uint8_t *from, size_t length) memcpy(*to, from, length); } -static void namechange_callback(Tox *tox, uint32_t friend_number, const uint8_t *name, size_t length, void *user_data) +static void namechange_callback(const Tox_Event_Friend_Name *event, void *user_data) { + //const uint32_t friend_number = tox_event_friend_name_get_friend_number(event); + const uint8_t *name = tox_event_friend_name_get_name(event); + const uint32_t name_length = tox_event_friend_name_get_name_length(event); + struct test_data *to_compare = (struct test_data *)user_data; - set_string(&to_compare->name, name, length); + set_string(&to_compare->name, name, name_length); to_compare->received_name = true; } -static void statuschange_callback(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length, - void *user_data) +static void statuschange_callback(const Tox_Event_Friend_Status_Message *event, void *user_data) { + //const uint32_t friend_number = tox_event_friend_status_message_get_friend_number(event); + const uint8_t *message = tox_event_friend_status_message_get_message(event); + const uint32_t message_length = tox_event_friend_status_message_get_message_length(event); + struct test_data *to_compare = (struct test_data *)user_data; - set_string(&to_compare->status_message, message, length); + set_string(&to_compare->status_message, message, message_length); to_compare->received_status_message = true; } @@ -65,6 +71,12 @@ int main(void) Tox *const tox1 = tox_new_log(nullptr, nullptr, nullptr); Tox *const tox2 = tox_new_log(nullptr, nullptr, nullptr); + ck_assert(tox1 != nullptr); + ck_assert(tox2 != nullptr); + + tox_events_init(tox1); + Tox_Dispatch *dispatch1 = tox_dispatch_new(nullptr); + ck_assert(dispatch1 != nullptr); printf("bootstrapping tox2 off tox1\n"); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; @@ -86,7 +98,7 @@ int main(void) ck_assert(reference_name != nullptr); ck_assert(reference_status != nullptr); - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); set_random(tox1, rng, tox_self_set_name, tox_max_name_length()); set_random(tox2, rng, tox_self_set_name, tox_max_name_length()); @@ -96,8 +108,8 @@ int main(void) tox_self_get_name(tox2, reference_name); tox_self_get_status_message(tox2, reference_status); - tox_callback_friend_name(tox1, namechange_callback); - tox_callback_friend_status_message(tox1, statuschange_callback); + tox_events_callback_friend_name(dispatch1, namechange_callback); + tox_events_callback_friend_status_message(dispatch1, statuschange_callback); while (true) { if (tox_self_get_connection_status(tox1) && @@ -107,7 +119,12 @@ int main(void) break; } - tox_iterate(tox1, &to_compare); + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(tox1, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + tox_dispatch_invoke(dispatch1, events, &to_compare); + tox_events_free(events); + tox_iterate(tox2, nullptr); c_sleep(tox_iteration_interval(tox1)); @@ -119,7 +136,12 @@ int main(void) break; } - tox_iterate(tox1, &to_compare); + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(tox1, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + tox_dispatch_invoke(dispatch1, events, &to_compare); + tox_events_free(events); + tox_iterate(tox2, nullptr); c_sleep(tox_iteration_interval(tox1)); @@ -146,6 +168,7 @@ int main(void) "incorrect status message: should be all zeroes"); tox_options_free(options); + tox_dispatch_free(dispatch1); tox_kill(tox1); tox_kill(tox2); tox_kill(tox_to_compare); diff --git a/auto_tests/save_load_test.c b/auto_tests/save_load_test.c index 20baed5b..f4158856 100644 --- a/auto_tests/save_load_test.c +++ b/auto_tests/save_load_test.c @@ -32,16 +32,24 @@ #endif #define TCP_RELAY_PORT 33431 -static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) +static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata) { - if (length == 7 && memcmp("Gentoo", data, 7) == 0) { - tox_friend_add_norequest(m, public_key, nullptr); + Tox *tox = (Tox *)userdata; + + const uint8_t *public_key = tox_event_friend_request_get_public_key(event); + const uint8_t *message = tox_event_friend_request_get_message(event); + uint32_t message_length = tox_event_friend_request_get_message_length(event); + + if (message_length == 7 && memcmp("Gentoo", message, 7) == 0) { + tox_friend_add_norequest(tox, public_key, nullptr); } } static unsigned int connected_t1; -static void tox_connection_status(Tox *tox, Tox_Connection connection_status, void *user_data) +static void tox_connection_status(const Tox_Event_Self_Connection_Status *event, void *user_data) { + const Tox_Connection connection_status = tox_event_self_connection_status_get_connection_status(event); + if (connected_t1 && !connection_status) { ck_abort_msg("Tox went offline"); } @@ -147,6 +155,9 @@ static void test_few_clients(void) Tox *tox1 = tox_new_log(opts1, &t_n_error, &index[0]); ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "Failed to create tox instance: %d", t_n_error); tox_options_free(opts1); + tox_events_init(tox1); + Tox_Dispatch *dispatch1 = tox_dispatch_new(nullptr); + ck_assert(dispatch1 != nullptr); struct Tox_Options *opts2 = tox_options_new(nullptr); tox_options_set_ipv6_enabled(opts2, USE_IPV6); @@ -154,6 +165,9 @@ static void test_few_clients(void) tox_options_set_local_discovery_enabled(opts2, false); Tox *tox2 = tox_new_log(opts2, &t_n_error, &index[1]); ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "Failed to create tox instance: %d", t_n_error); + tox_events_init(tox2); + Tox_Dispatch *dispatch2 = tox_dispatch_new(nullptr); + ck_assert(dispatch2 != nullptr); struct Tox_Options *opts3 = tox_options_new(nullptr); tox_options_set_ipv6_enabled(opts3, USE_IPV6); @@ -163,7 +177,6 @@ static void test_few_clients(void) ck_assert_msg(tox1 && tox2 && tox3, "Failed to create 3 tox instances"); - Time_Data time_data; ck_assert_msg(pthread_mutex_init(&time_data.lock, nullptr) == 0, "Failed to init time_data mutex"); time_data.clock = current_time_monotonic(tox1->mono_time); @@ -183,8 +196,8 @@ static void test_few_clients(void) tox_bootstrap(tox3, "localhost", dht_port, dht_key, nullptr); connected_t1 = 0; - tox_callback_self_connection_status(tox1, tox_connection_status); - tox_callback_friend_request(tox2, accept_friend_request); + tox_events_callback_self_connection_status(dispatch1, tox_connection_status); + tox_events_callback_friend_request(dispatch2, accept_friend_request); uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(tox2, address); uint32_t test = tox_friend_add(tox3, address, (const uint8_t *)"Gentoo", 7, nullptr); @@ -193,8 +206,20 @@ static void test_few_clients(void) uint8_t off = 1; while (true) { - tox_iterate(tox1, nullptr); - tox_iterate(tox2, nullptr); + { + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(tox1, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + tox_dispatch_invoke(dispatch1, events, tox1); + tox_events_free(events); + } + { + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(tox2, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + tox_dispatch_invoke(dispatch2, events, tox2); + tox_events_free(events); + } tox_iterate(tox3, nullptr); if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2) @@ -220,9 +245,10 @@ static void test_few_clients(void) // We're done with this callback, so unset it to ensure we don't fail the // test if tox1 goes offline while tox2 and 3 are reloaded. - tox_callback_self_connection_status(tox1, nullptr); + tox_events_callback_self_connection_status(dispatch1, nullptr); reload_tox(&tox2, opts2, &index[1]); + tox_events_init(tox2); reload_tox(&tox3, opts3, &index[2]); @@ -231,8 +257,20 @@ static void test_few_clients(void) off = 1; while (true) { - tox_iterate(tox1, nullptr); - tox_iterate(tox2, nullptr); + { + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(tox1, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + tox_dispatch_invoke(dispatch1, events, tox1); + tox_events_free(events); + } + { + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(tox2, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + tox_dispatch_invoke(dispatch2, events, tox2); + tox_events_free(events); + } tox_iterate(tox3, nullptr); if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2) @@ -257,6 +295,9 @@ static void test_few_clients(void) printf("test_few_clients succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); + tox_dispatch_free(dispatch1); + tox_dispatch_free(dispatch2); + tox_kill(tox1); tox_kill(tox2); tox_kill(tox3); diff --git a/auto_tests/send_message_test.c b/auto_tests/send_message_test.c index 92079cb8..d39ba23f 100644 --- a/auto_tests/send_message_test.c +++ b/auto_tests/send_message_test.c @@ -14,12 +14,15 @@ typedef struct State { #define MESSAGE_FILLER 'G' static void message_callback( - Tox *m, uint32_t friendnumber, Tox_Message_Type type, - const uint8_t *string, size_t length, void *user_data) + const Tox_Event_Friend_Message *event, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; + const Tox_Message_Type type = tox_event_friend_message_get_type(event); + const uint8_t *string = tox_event_friend_message_get_message(event); + const uint32_t length = tox_event_friend_message_get_message_length(event); + if (type != TOX_MESSAGE_TYPE_NORMAL) { ck_abort_msg("Bad type"); } @@ -38,7 +41,7 @@ static void message_callback( static void send_message_test(AutoTox *autotoxes) { - tox_callback_friend_message(autotoxes[1].tox, &message_callback); + tox_events_callback_friend_message(autotoxes[1].dispatch, &message_callback); const size_t msgs_len = tox_max_message_length() + 1; uint8_t *msgs = (uint8_t *)malloc(msgs_len); diff --git a/auto_tests/set_name_test.c b/auto_tests/set_name_test.c index 9ad7946c..0a60bfc2 100644 --- a/auto_tests/set_name_test.c +++ b/auto_tests/set_name_test.c @@ -15,12 +15,16 @@ #define NICKNAME "Gentoo" -static void nickchange_callback(Tox *tox, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata) +static void nickchange_callback(const Tox_Event_Friend_Name *event, void *user_data) { - ck_assert_msg(length == sizeof(NICKNAME), "Name length not correct: %d != %d", (uint16_t)length, + //const uint32_t friend_number = tox_event_friend_name_get_friend_number(event); + const uint8_t *name = tox_event_friend_name_get_name(event); + const uint32_t name_length = tox_event_friend_name_get_name_length(event); + + ck_assert_msg(name_length == sizeof(NICKNAME), "Name length not correct: %d != %d", (uint16_t)name_length, (uint16_t)sizeof(NICKNAME)); - ck_assert_msg(memcmp(string, NICKNAME, sizeof(NICKNAME)) == 0, "Name not correct: %s", (const char *)string); - bool *nickname_updated = (bool *)userdata; + ck_assert_msg(memcmp(name, NICKNAME, sizeof(NICKNAME)) == 0, "Name not correct: %s", (const char *)name); + bool *nickname_updated = (bool *)user_data; *nickname_updated = true; } @@ -34,6 +38,12 @@ static void test_set_name(void) ck_assert_msg(tox1 && tox2, "failed to create 2 tox instances"); + // we only run events on tox2 in this test case + tox_events_init(tox2); + + Tox_Dispatch *dispatch2 = tox_dispatch_new(nullptr); + ck_assert(dispatch2 != nullptr); + printf("tox1 adds tox2 as friend, tox2 adds tox1\n"); uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(tox2, public_key); @@ -50,7 +60,13 @@ static void test_set_name(void) do { tox_iterate(tox1, nullptr); - tox_iterate(tox2, nullptr); + + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(tox2, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + //tox_dispatch_invoke(dispatch2, events, nullptr); + tox_events_free(events); + c_sleep(ITERATION_INTERVAL); } while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE || tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE); @@ -60,14 +76,20 @@ static void test_set_name(void) do { tox_iterate(tox1, nullptr); - tox_iterate(tox2, nullptr); + + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(tox2, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + //tox_dispatch_invoke(dispatch2, events, nullptr); + tox_events_free(events); + c_sleep(ITERATION_INTERVAL); } while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP || tox_friend_get_connection_status(tox2, 0, nullptr) != TOX_CONNECTION_UDP); printf("tox clients connected took %lu seconds\n", (unsigned long)(time(nullptr) - con_time)); - tox_callback_friend_name(tox2, nickchange_callback); + tox_events_callback_friend_name(dispatch2, nickchange_callback); Tox_Err_Set_Info err_n; bool ret = tox_self_set_name(tox1, (const uint8_t *)NICKNAME, sizeof(NICKNAME), &err_n); ck_assert_msg(ret && err_n == TOX_ERR_SET_INFO_OK, "tox_self_set_name failed because %d\n", err_n); @@ -76,7 +98,13 @@ static void test_set_name(void) do { tox_iterate(tox1, nullptr); - tox_iterate(tox2, &nickname_updated); + + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(tox2, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + tox_dispatch_invoke(dispatch2, events, &nickname_updated); + tox_events_free(events); + c_sleep(ITERATION_INTERVAL); } while (!nickname_updated); @@ -87,6 +115,8 @@ static void test_set_name(void) printf("test_set_name succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); + tox_dispatch_free(dispatch2); + tox_kill(tox1); tox_kill(tox2); } diff --git a/auto_tests/set_status_message_test.c b/auto_tests/set_status_message_test.c index 435d2239..01b3af11 100644 --- a/auto_tests/set_status_message_test.c +++ b/auto_tests/set_status_message_test.c @@ -15,9 +15,13 @@ #define STATUS_MESSAGE "Installing Gentoo" -static void status_callback(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length, void *user_data) +static void status_callback(const Tox_Event_Friend_Status_Message *event, void *user_data) { - ck_assert_msg(length == sizeof(STATUS_MESSAGE) && + //uint32_t friend_number = tox_event_friend_status_message_get_friend_number(event); + const uint8_t *message = tox_event_friend_status_message_get_message(event); + uint32_t message_length = tox_event_friend_status_message_get_message_length(event); + + ck_assert_msg(message_length == sizeof(STATUS_MESSAGE) && memcmp(message, STATUS_MESSAGE, sizeof(STATUS_MESSAGE)) == 0, "incorrect data in status callback"); bool *status_updated = (bool *)user_data; @@ -34,6 +38,12 @@ static void test_set_status_message(void) ck_assert_msg(tox1 && tox2, "failed to create 2 tox instances"); + // we only run events on tox2 in this test case + tox_events_init(tox2); + + Tox_Dispatch *dispatch2 = tox_dispatch_new(nullptr); + ck_assert(dispatch2 != nullptr); + printf("tox1 adds tox2 as friend, tox2 adds tox1\n"); uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(tox2, public_key); @@ -50,7 +60,12 @@ static void test_set_status_message(void) do { tox_iterate(tox1, nullptr); - tox_iterate(tox2, nullptr); + + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(tox2, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + //tox_dispatch_invoke(dispatch2, events, nullptr); + tox_events_free(events); c_sleep(ITERATION_INTERVAL); } while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE || @@ -61,7 +76,12 @@ static void test_set_status_message(void) do { tox_iterate(tox1, nullptr); - tox_iterate(tox2, nullptr); + + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(tox2, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + //tox_dispatch_invoke(dispatch2, events, nullptr); + tox_events_free(events); c_sleep(ITERATION_INTERVAL); } while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP || @@ -69,8 +89,8 @@ static void test_set_status_message(void) printf("tox clients connected took %lu seconds\n", (unsigned long)(time(nullptr) - con_time)); + tox_events_callback_friend_status_message(dispatch2, status_callback); Tox_Err_Set_Info err_n; - tox_callback_friend_status_message(tox2, status_callback); bool ret = tox_self_set_status_message(tox1, (const uint8_t *)STATUS_MESSAGE, sizeof(STATUS_MESSAGE), &err_n); ck_assert_msg(ret && err_n == TOX_ERR_SET_INFO_OK, "tox_self_set_status_message failed because %d\n", err_n); @@ -79,7 +99,13 @@ static void test_set_status_message(void) do { tox_iterate(tox1, nullptr); - tox_iterate(tox2, &status_updated); + + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(tox2, true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + tox_dispatch_invoke(dispatch2, events, &status_updated); + tox_events_free(events); + c_sleep(ITERATION_INTERVAL); } while (!status_updated); @@ -92,6 +118,8 @@ static void test_set_status_message(void) printf("test_set_status_message succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); + tox_dispatch_free(dispatch2); + tox_kill(tox1); tox_kill(tox2); } diff --git a/auto_tests/tox_dispatch_test.c b/auto_tests/tox_dispatch_test.c index 01294589..6a57ed4a 100644 --- a/auto_tests/tox_dispatch_test.c +++ b/auto_tests/tox_dispatch_test.c @@ -18,7 +18,7 @@ // Set to true to produce an msgpack file at /tmp/test.mp. static const bool want_dump_events = false; -static void handle_events_friend_message(Tox *tox, const Tox_Event_Friend_Message *event, void *user_data) +static void handle_events_friend_message(const Tox_Event_Friend_Message *event, void *user_data) { bool *success = (bool *)user_data; @@ -84,7 +84,7 @@ static bool await_message(Tox **toxes, const Tox_Dispatch *dispatch) } bool success = false; - tox_dispatch_invoke(dispatch, events, toxes[1], &success); + tox_dispatch_invoke(dispatch, events, &success); print_events(sys, events); if (success) { @@ -169,22 +169,9 @@ static void test_tox_events(void) } } -static void fake_test_unpack(void) -{ - // TODO(Green-Sky): add proper unpack tests and/or implement ngc events - (void)tox_group_privacy_state_unpack; - (void)tox_group_privacy_state_unpack; - (void)tox_group_voice_state_unpack; - (void)tox_group_topic_lock_unpack; - (void)tox_group_join_fail_unpack; - (void)tox_group_mod_event_unpack; - (void)tox_group_exit_type_unpack; -} - int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); test_tox_events(); - fake_test_unpack(); return 0; } diff --git a/auto_tests/tox_many_tcp_test.c b/auto_tests/tox_many_tcp_test.c index b6e34d79..0f883005 100644 --- a/auto_tests/tox_many_tcp_test.c +++ b/auto_tests/tox_many_tcp_test.c @@ -26,16 +26,27 @@ #define TOX_LOCALHOST "127.0.0.1" #endif +typedef struct State { + uint32_t to_comp; + Tox *tox; +} State; + static bool enable_broken_tests = false; -static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) +static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata) { - if (*((uint32_t *)userdata) != 974536) { + State *state = (State *)userdata; + + const uint8_t *public_key = tox_event_friend_request_get_public_key(event); + const uint8_t *message = tox_event_friend_request_get_message(event); + const uint32_t message_length = tox_event_friend_request_get_message_length(event); + + if (state->to_comp != 974536) { return; } - if (length == 7 && memcmp("Gentoo", data, 7) == 0) { - tox_friend_add_norequest(m, public_key, nullptr); + if (message_length == 7 && memcmp("Gentoo", message, 7) == 0) { + tox_friend_add_norequest(state->tox, public_key, nullptr); } } @@ -46,7 +57,7 @@ static uint16_t tcp_relay_port = 33448; static void test_many_clients_tcp(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); long long unsigned int cur_time = time(nullptr); Tox *toxes[NUM_TOXES_TCP]; @@ -73,7 +84,7 @@ static void test_many_clients_tcp(void) continue; } ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i); - tox_callback_friend_request(toxes[i], accept_friend_request); + tox_events_init(toxes[i]); uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(toxes[0], dpk); Tox_Err_Bootstrap error; @@ -85,6 +96,11 @@ static void test_many_clients_tcp(void) tox_options_free(opts); } + Tox_Dispatch *dispatch = tox_dispatch_new(nullptr); + ck_assert(dispatch != nullptr); + + tox_events_callback_friend_request(dispatch, accept_friend_request); + struct { uint16_t tox1; uint16_t tox2; @@ -131,12 +147,18 @@ loop_top: } for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) { - tox_iterate(toxes[i], &to_comp); + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(toxes[i], true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + State state = {to_comp, toxes[i]}; + tox_dispatch_invoke(dispatch, events, &state); + tox_events_free(events); } c_sleep(50); } + tox_dispatch_free(dispatch); for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) { tox_kill(toxes[i]); } @@ -148,7 +170,7 @@ loop_top: static void test_many_clients_tcp_b(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); long long unsigned int cur_time = time(nullptr); Tox *toxes[NUM_TOXES_TCP]; @@ -167,7 +189,7 @@ static void test_many_clients_tcp_b(void) index[i] = i + 1; toxes[i] = tox_new_log(opts, nullptr, &index[i]); ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i); - tox_callback_friend_request(toxes[i], accept_friend_request); + tox_events_init(toxes[i]); uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(toxes[(i % NUM_TCP_RELAYS)], dpk); ck_assert_msg(tox_add_tcp_relay(toxes[i], TOX_LOCALHOST, tcp_relay_port + (i % NUM_TCP_RELAYS), dpk, nullptr), @@ -179,6 +201,11 @@ static void test_many_clients_tcp_b(void) tox_options_free(opts); } + Tox_Dispatch *dispatch = tox_dispatch_new(nullptr); + ck_assert(dispatch != nullptr); + + tox_events_callback_friend_request(dispatch, accept_friend_request); + struct { uint16_t tox1; uint16_t tox2; @@ -232,12 +259,18 @@ loop_top: } for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) { - tox_iterate(toxes[i], &to_comp); + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(toxes[i], true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + State state = {to_comp, toxes[i]}; + tox_dispatch_invoke(dispatch, events, &state); + tox_events_free(events); } c_sleep(30); } + tox_dispatch_free(dispatch); for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) { tox_kill(toxes[i]); } @@ -245,7 +278,6 @@ loop_top: printf("test_many_clients_tcp_b succeeded, took %llu seconds\n", time(nullptr) - cur_time); } - static void tox_suite(void) { /* Each tox connects to a single tox TCP */ diff --git a/auto_tests/tox_many_test.c b/auto_tests/tox_many_test.c index 8501b5c1..7a53191d 100644 --- a/auto_tests/tox_many_test.c +++ b/auto_tests/tox_many_test.c @@ -13,20 +13,25 @@ #include "auto_test_support.h" #include "check_compat.h" -static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) +static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata) { - if (length == 7 && memcmp("Gentoo", data, 7) == 0) { - tox_friend_add_norequest(m, public_key, nullptr); + Tox *tox = (Tox *)userdata; + + const uint8_t *public_key = tox_event_friend_request_get_public_key(event); + const uint8_t *message = tox_event_friend_request_get_message(event); + const uint32_t message_length = tox_event_friend_request_get_message_length(event); + + if (message_length == 7 && memcmp("Gentoo", message, 7) == 0) { + tox_friend_add_norequest(tox, public_key, nullptr); } } - #define TCP_TEST_NUM_TOXES 90 #define TCP_TEST_NUM_FRIENDS 50 static void test_many_clients(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); time_t cur_time = time(nullptr); Tox *toxes[TCP_TEST_NUM_TOXES]; @@ -36,9 +41,14 @@ static void test_many_clients(void) index[i] = i + 1; toxes[i] = tox_new_log(nullptr, nullptr, &index[i]); ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i); - tox_callback_friend_request(toxes[i], accept_friend_request); + tox_events_init(toxes[i]); } + Tox_Dispatch *dispatch = tox_dispatch_new(nullptr); + ck_assert(dispatch != nullptr); + + tox_events_callback_friend_request(dispatch, accept_friend_request); + struct { uint16_t tox1; uint16_t tox2; @@ -112,12 +122,17 @@ loop_top: } for (uint32_t i = 0; i < TCP_TEST_NUM_TOXES; ++i) { - tox_iterate(toxes[i], nullptr); + Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; + Tox_Events *events = tox_events_iterate(toxes[i], true, &err); + ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); + tox_dispatch_invoke(dispatch, events, toxes[i]); + tox_events_free(events); } c_sleep(50); } + tox_dispatch_free(dispatch); for (uint32_t i = 0; i < TCP_TEST_NUM_TOXES; ++i) { tox_kill(toxes[i]); } diff --git a/auto_tests/tox_new_test.c b/auto_tests/tox_new_test.c new file mode 100644 index 00000000..9aaeb191 --- /dev/null +++ b/auto_tests/tox_new_test.c @@ -0,0 +1,9 @@ +#include "../toxcore/tox.h" + +#include "../toxcore/ccompat.h" + +int main(void) +{ + tox_kill(tox_new(nullptr, nullptr)); + return 0; +} diff --git a/auto_tests/toxav_basic_test.c b/auto_tests/toxav_basic_test.c index cdf04323..541b254f 100644 --- a/auto_tests/toxav_basic_test.c +++ b/auto_tests/toxav_basic_test.c @@ -23,7 +23,6 @@ #define TEST_STOP_RESUME_PAYLOAD 1 #define TEST_PAUSE_RESUME_SEND 1 - #define ck_assert_call_control(a, b, c) do { \ Toxav_Err_Call_Control cc_err; \ bool ok = toxav_call_control(a, b, c, &cc_err); \ @@ -34,7 +33,6 @@ ck_assert(cc_err == TOXAV_ERR_CALL_CONTROL_OK); \ } while (0) - typedef struct { bool incoming; uint32_t state; @@ -46,7 +44,6 @@ static void clear_call_control(CallControl *cc) *cc = empty; } - /** * Callbacks */ @@ -89,7 +86,6 @@ static void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const } } - /** * Iterate helper */ @@ -207,7 +203,6 @@ static void test_av_flows(void) c_sleep(20); } - { Toxav_Err_New error; alice_av = toxav_new(alice, &error); diff --git a/auto_tests/toxav_many_test.c b/auto_tests/toxav_many_test.c index b1f2f9fa..2892f724 100644 --- a/auto_tests/toxav_many_test.c +++ b/auto_tests/toxav_many_test.c @@ -74,7 +74,6 @@ static void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const } } - /** * Iterate helper */ @@ -299,7 +298,6 @@ static void test_av_three_calls(void) } } - do { tox_iterate(bootstrap, nullptr); tox_iterate(alice, nullptr); diff --git a/auto_tests/typing_test.c b/auto_tests/typing_test.c index 5c015987..4a03023f 100644 --- a/auto_tests/typing_test.c +++ b/auto_tests/typing_test.c @@ -17,10 +17,14 @@ typedef struct State { #include "auto_test_support.h" -static void typing_callback(Tox *m, uint32_t friendnumber, bool typing, void *user_data) +static void typing_callback(const Tox_Event_Friend_Typing *event, void *user_data) { const AutoTox *autotox = (AutoTox *)user_data; State *state = (State *)autotox->state; + + //const uint32_t friend_number = tox_event_friend_typing_get_friend_number(event); + const bool typing = tox_event_friend_typing_get_typing(event); + state->friend_is_typing = typing; } @@ -28,7 +32,7 @@ static void test_typing(AutoTox *autotoxes) { time_t cur_time = time(nullptr); - tox_callback_friend_typing(autotoxes[1].tox, &typing_callback); + tox_events_callback_friend_typing(autotoxes[1].dispatch, &typing_callback); tox_self_set_typing(autotoxes[0].tox, 0, true, nullptr); do { diff --git a/cmake/StrictAbi.cmake b/cmake/StrictAbi.cmake index f91ec160..ec579219 100644 --- a/cmake/StrictAbi.cmake +++ b/cmake/StrictAbi.cmake @@ -48,8 +48,8 @@ function(_make_version_script target) endfunction() option(STRICT_ABI "Enforce strict ABI export in dynamic libraries" OFF) -if(WIN32 OR APPLE) - # Windows and OSX don't have this linker functionality. +if((WIN32 AND NOT MINGW) OR APPLE) + # Windows and macOS don't have this linker functionality. set(STRICT_ABI OFF) endif() diff --git a/docs/Doxyfile b/docs/Doxyfile index 054f3ec0..7015c9e5 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1295,15 +1295,6 @@ HTML_COLORSTYLE_SAT = 100 HTML_COLORSTYLE_GAMMA = 80 -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = NO - # If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML # documentation will contain a main index with vertical navigation menus that # are dynamically created via JavaScript. If disabled, the navigation index will @@ -1950,14 +1941,6 @@ LATEX_HIDE_INDICES = NO LATEX_BIB_STYLE = plain -# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated -# page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_TIMESTAMP = NO - # The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) # path from which the emoji images will be read. If a relative path is entered, # it will be relative to the LATEX_OUTPUT directory. If left blank the @@ -2587,3 +2570,19 @@ GENERATE_LEGEND = YES # The default value is: YES. DOT_CLEANUP = YES + +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser for more accurate parsing at the cost of reduced performance. +# This can be particularly helpful with template rich C++ code for which +# doxygen's built-in parser lacks the necessary type information. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the clang parser with +# the path to the directory containing a file called compile_commands.json. +# This file is the compilation database containing the options used when the +# source files were built. This is equivalent to specifying the -p option to a +# clang tool, such as clang-check. These options will then be passed to the +# parser. Any options specified with CLANG_OPTIONS will be added as well. + +CLANG_DATABASE_PATH = _build diff --git a/docs/Group-Chats.md b/docs/Group-Chats.md index 2935c7f5..b2199e76 100644 --- a/docs/Group-Chats.md +++ b/docs/Group-Chats.md @@ -2,77 +2,122 @@ Group chats. Note: we assume everyone in the chat trusts each other. -These group chats work by temporarily adding the 4 "closest" people defined by a distance function -in group.c in order to form a circle of connected peers. These peers then relay messages to each other. - -A friend invites another friend to a group chat by sending them an invite packet. The friend either ignores -the invite or responds with a response packet if he wants to join the chat. The friend invite contains the type -of groupchat (text only, A/V) the friend is being invited to. +These group chats work by temporarily adding the 4 "closest" people defined by a +distance function in group.c in order to form a circle of connected peers. These +peers then relay messages to each other. +A friend invites another friend to a group chat by sending them an invite +packet. The friend either ignores the invite or responds with a response packet +if he wants to join the chat. The friend invite contains the type of groupchat +(text only, A/V) the friend is being invited to. TODO(irungentoo): write more of this. ## Protocol Invite packets: -Invite packet: + +### Invite packet: + +``` [uint8_t id 96][uint8_t id 0][uint16_t group chat number][33 bytes group chat identifier[1 byte type][32 bytes id]] +``` -Response packet +### Response packet + +``` [uint8_t id 96][uint8_t id 1][uint16_t group chat number(local)][uint16_t group chat number to join][33 bytes group chat identifier[1 byte type][32 bytes id]] +``` +### Peer online packet: -Peer online packet: +``` [uint8_t id 97][uint16_t group chat number (local)][33 bytes group chat identifier[1 byte type][32 bytes id]] +``` -Peer leave packet: +### Peer leave packet: + +``` [uint8_t id 98][uint16_t group chat number][uint8_t id 1] +``` -Peer query packet: +### Peer query packet: + +``` [uint8_t id 98][uint16_t group chat number][uint8_t id 8] +``` -Peer response packet: -[uint8_t id 98][uint16_t group chat number][uint8_t id 9][Repeated times number of peers: [uint16_t peer num][uint8_t 32bytes real public key][uint8_t 32bytes temp DHT public key][uint8_t name length][name]] +### Peer response packet: -Title response packet: +``` +[uint8_t id 98][uint16_t group chat number][uint8_t id 9][Repeated times number of peers: [uint16_t peer num][uint8_t 32bytes real public key][uint8_t 32bytes temp DHT public key][uint8_t name length][name]] +``` + +### Title response packet: + +``` [uint8_t id 98][uint16_t group chat number][uint8_t id 10][title] +``` -Message packets: +### Message packets: + +``` [uint8_t id 99][uint16_t group chat number][uint16_t peer number][uint32_t message number][uint8_t with a value representing id of message][data] +``` -Lossy Message packets: +### Lossy Message packets: + +``` [uint8_t id 199][uint16_t group chat number][uint16_t peer number][uint16_t message number][uint8_t with a value representing id of message][data] +``` -Group chat types: -0: text -1: AV +## Group chat types: +- 0: text +- 1: AV Note: the message number is increased by 1 for each sent message. -message ids: -0 - ping -sent every ~60 seconds by every peer. -No data. +## message ids: + +### 0 - ping + +sent every ~60 seconds by every peer. No data. + +### 16 - new_peer -16 - new_peer Tell everyone about a new peer in the chat. + +``` [uint16_t peer_num][uint8_t 32bytes real public key][uint8_t 32bytes temp DHT public key] +``` -17 - kill_peer +### 17 - kill_peer + +``` [uint16_t peer_num] +``` -48 - name change +### 48 - name change + +``` [uint8_t name[namelen]] +``` -49 - groupchat title change +### 49 - groupchat title change + +``` [uint8_t title[titlelen]] +``` -64 - chat message +### 64 - chat message + +``` [uint8_t message[messagelen]] +``` -65 - action (/me) +### 65 - action (/me) + +``` [uint8_t message[messagelen]] - - - +``` diff --git a/docs/apidsl.md b/docs/apidsl.md deleted file mode 100644 index 96ff5d0d..00000000 --- a/docs/apidsl.md +++ /dev/null @@ -1,51 +0,0 @@ -This folder contains the input file (``tox.in.h``) that has to be used to generate the ``tox.h`` api with: https://github.com/TokTok/apidsl - -# Minimal requirements - -There are some minimal requirements to contribute to ``tox.h``: -* unix environment -* ``astyle`` ``>=2.03`` -* [``apidsl``](https://github.com/TokTok/apidsl) (you can use provided service with curl instead) - -## Quick way - -If you want to do it quickly and you don't have time for anything other than copypasting commands, you should have ``curl`` installed. - - -1. Make sure that you have ``curl`` and ``>=astyle-2.03`` installed -2. Modify [``tox.api.h``](/toxcore/tox.api.h) -3. Run command below ↓ - -Command to run from ``toxcore`` directory (quick way, involves using curl): -```bash -# For tox.h: -curl -X POST --data-binary @- https://apidsl.herokuapp.com/apidsl \ - < toxcore/tox.api.h \ - | astyle --options=other/astyle/astylerc \ - > toxcore/tox.h -# For toxav.h: -curl -X POST --data-binary @- https://apidsl.herokuapp.com/apidsl \ - < toxav/toxav.api.h \ - | astyle --options=other/astyle/astylerc \ - > toxav/toxav.h -``` - -You may want to make sure with ``git diff`` that changes made in ``tox.h`` reflect changes in ``tox.in.h``. - -And you're done. - - -## Manually - -If you prefer to have more control over what is happening, there are steps below: - -1. Install [``apidsl``](https://github.com/TokTok/apidsl) -2. Install ``astyle``, version 2.03 or later. -3. Modify [``tox.api.h``](/toxcore/tox.api.h) -4. Use ``apidsl`` ``??`` -5. Parse generated ``tox.h`` with astyle, minimal command for it would be: -```bash -astyle --options=other/astyle/astylerc toxcore/tox.h -``` - -**Always pass output from ``apidsl`` through astyle.** diff --git a/docs/av_api.md b/docs/av_api.md index a087cdad..733c91f8 100644 --- a/docs/av_api.md +++ b/docs/av_api.md @@ -8,38 +8,36 @@ phone_t* initPhone(uint16_t _listen_port, uint16_t _send_port); ``` -function initializes sample phone. _listen_port and _send_port are variables only meant -for local testing. You will not have to do anything regarding to that since -everything will be started within a messenger. +function initializes sample phone. `_listen_port` and `_send_port` are variables +only meant for local testing. You will not have to do anything regarding to that +since everything will be started within a messenger. - -Phone requires one msi session and two rtp sessions ( one for audio and one for -video ). +Phone requires one msi session and two rtp sessions (one for audio and one for +video). ``` msi_session_t* msi_init_session( void* _core_handler, const uint8_t* _user_agent ); ``` -initializes msi session. -Params: +initializes msi session. Params: ``` void* _core_handler - pointer to an object handling networking, const uint8_t* _user_agent - string describing phone client version. ``` -Return value: -msi_session_t* - pointer to a newly created msi session handler. +Return value: `msi_session_t*` - pointer to a newly created msi session handler. -### msi_session_t reference: +### `msi_session_t` reference: -How to handle msi session: -Controlling is done via callbacks and action handlers. -First register callbacks for every state/action received and make sure -NOT TO PLACE SOMETHING LIKE LOOPS THAT TAKES A LOT OF TIME TO EXECUTE; every callback is being called -directly from event loop. You can find examples in phone.c. +How to handle msi session: Controlling is done via callbacks and action +handlers. First register callbacks for every state/action received and make sure +NOT TO PLACE SOMETHING LIKE LOOPS THAT TAKES A LOT OF TIME TO EXECUTE; every +callback is being called directly from event loop. You can find examples in +phone.c. + +Register callbacks: -Register callbacks: ``` void msi_register_callback_call_started ( MCALLBACK ); void msi_register_callback_call_canceled ( MCALLBACK ); @@ -55,10 +53,9 @@ void msi_register_callback_recv_error ( MCALLBACK ); void msi_register_callback_requ_timeout ( MCALLBACK ); ``` -MCALLBACK is defined as: void (*callback) (void* _arg) -msi_session_t* handler is being thrown as \_arg so you can use that and \_agent_handler to get to your own phone handler -directly from callback. - +MCALLBACK is defined as: `void (*callback) (void* _arg)` `msi_session_t*` +handler is being thrown as `_arg` so you can use that and `_agent_handler` to +get to your own phone handler directly from callback. Actions: @@ -66,80 +63,93 @@ Actions: int msi_invite ( msi_session_t* _session, call_type _call_type, uint32_t _timeoutms ); ``` -Sends call invite. Before calling/sending invite msi_session_t::_friend_id is needed to be set or else -it will not work. _call_type is type of the call ( Audio/Video ) and _timeoutms is how long -will poll wait until request is terminated. +Sends call invite. Before calling/sending invite `msi_session_t::_friend_id` is +needed to be set or else it will not work. `_call_type` is type of the call ( +Audio/Video ) and `_timeoutms` is how long will poll wait until request is +terminated. ``` int msi_hangup ( msi_session_t* _session ); ``` + Hangs up active call ``` int msi_answer ( msi_session_t* _session, call_type _call_type ); ``` -Answer incoming call. _call_type set's callee call type. + +Answer incoming call. `_call_type` set's callee call type. ``` int msi_cancel ( msi_session_t* _session ); ``` + Cancel current request. ``` int msi_reject ( msi_session_t* _session ); ``` -Reject incoming call. +Reject incoming call. ### Now for rtp: -You will need 2 sessions; one for audio one for video. -You start them with: +You will need 2 sessions; one for audio one for video. You start them with: + ``` rtp_session_t* rtp_init_session ( int _max_users, int _multi_session ); ``` Params: + ``` int _max_users - max users. -1 if undefined int _multi_session - any positive number means uses multi session; -1 if not. ``` Return value: + ``` rtp_session_t* - pointer to a newly created rtp session handler. ``` ### How to handle rtp session: + Take a look at + ``` void* phone_handle_media_transport_poll ( void* _hmtc_args_p ) in phone.c ``` + on example. Basically what you do is just receive a message via: + ``` struct rtp_msg_s* rtp_recv_msg ( rtp_session_t* _session ); ``` -and then you use payload within the rtp_msg_s struct. Don't forget to deallocate it with: -void rtp_free_msg ( rtp_session_t* _session, struct rtp_msg_s* _msg ); +and then you use payload within the `rtp_msg_s` struct. Don't forget to +deallocate it with: +`void rtp_free_msg ( rtp_session_t* _session, struct rtp_msg_s* _msg );` Receiving should be thread safe so don't worry about that. When you capture and encode a payload you want to send it ( obviously ). first create a new message with: + ``` struct rtp_msg_s* rtp_msg_new ( rtp_session_t* _session, const uint8_t* _data, uint32_t _length ); ``` and then send it with: + ``` int rtp_send_msg ( rtp_session_t* _session, struct rtp_msg_s* _msg, void* _core_handler ); ``` -_core_handler is the same network handler as in msi_session_s struct. - +`_core_handler` is the same network handler as in `msi_session_s` struct. ## A/V initialization: + ``` int init_receive_audio(codec_state *cs); int init_receive_video(codec_state *cs); @@ -156,39 +166,62 @@ In the future, VP8 should be used directly and ffmpeg should be dropped from the The variable bps is the required bitrate in bits per second. ``` - ### A/V encoding/decoding: + ``` void *encode_video_thread(void *arg); ``` -Spawns the video encoding thread. The argument should hold a pointer to a codec_state. -This function should only be called if video encoding is supported (when init_send_video returns 1). -Each video frame gets encoded into a packet, which is sent via RTP. Every 60 frames a new bidirectional interframe is encoded. + +Spawns the video encoding thread. The argument should hold a pointer to a +`codec_state`. This function should only be called if video encoding is +supported (when `init_send_video` returns 1). Each video frame gets encoded into +a packet, which is sent via RTP. Every 60 frames a new bidirectional interframe +is encoded. + ``` void *encode_audio_thread(void *arg); ``` -Spawns the audio encoding thread. The argument should hold a pointer to a codec_state. -This function should only be called if audio encoding is supported (when init_send_audio returns 1). -Audio frames are read from the selected audio capture device during initialisation. This audio capturing can be rerouted to a different device on the fly. -Each audio frame is encoded into a packet, and sent via RTP. All audio frames have the same amount of samples, which is defined in AV_codec.h. + +Spawns the audio encoding thread. The argument should hold a pointer to a +`codec_state`. This function should only be called if audio encoding is +supported (when `init_send_audio` returns 1). Audio frames are read from the +selected audio capture device during initialisation. This audio capturing can be +rerouted to a different device on the fly. Each audio frame is encoded into a +packet, and sent via RTP. All audio frames have the same amount of samples, +which is defined in `AV_codec.h`. + ``` int video_decoder_refresh(codec_state *cs, int width, int height); ``` -Sets the SDL window dimensions and creates a pixel buffer with the requested size. It also creates a scaling context, which will be used to convert the input image format to YUV420P. + +Sets the SDL window dimensions and creates a pixel buffer with the requested +size. It also creates a scaling context, which will be used to convert the input +image format to YUV420P. ``` void *decode_video_thread(void *arg); ``` -Spawns a video decoding thread. The argument should hold a pointer to a codec_state. The codec_state is assumed to contain a successfully initialised video decoder. -This function reads video packets and feeds them to the video decoder. If the video frame's resolution has changed, video_decoder_refresh() is called. Afterwards, the frame is displayed on the SDL window. + +Spawns a video decoding thread. The argument should hold a pointer to a +`codec_state`. The `codec_state` is assumed to contain a successfully +initialised video decoder. This function reads video packets and feeds them to +the video decoder. If the video frame's resolution has changed, +`video_decoder_refresh()` is called. Afterwards, the frame is displayed on the +SDL window. + ``` void *decode_audio_thread(void *arg); ``` -Spawns an audio decoding thread. The argument should hold a pointer to a codec_state. The codec_state is assumed to contain a successfully initialised audio decoder. -All received audio packets are pushed into a jitter buffer and are reordered. If there is a missing packet, or a packet has arrived too late, it is treated as a lost packet and the audio decoder is informed of the packet loss. The audio decoder will then try to reconstruct the lost packet, based on information from previous packets. -Audio is played on the default OpenAL output device. +Spawns an audio decoding thread. The argument should hold a pointer to a +`codec_state`. The `codec_state` is assumed to contain a successfully +initialised audio decoder. All received audio packets are pushed into a jitter +buffer and are reordered. If there is a missing packet, or a packet has arrived +too late, it is treated as a lost packet and the audio decoder is informed of +the packet loss. The audio decoder will then try to reconstruct the lost packet, +based on information from previous packets. Audio is played on the default +OpenAL output device. -If you have any more qustions/bug reports/feature request contact the following users on the irc channel #tox-dev on irc.freenode.net: -For RTP and MSI: mannol +If you have any more qustions/bug reports/feature request contact the following +users on the irc channel #tox-dev on irc.freenode.net: For RTP and MSI: mannol For audio and video: Martijnvdc diff --git a/docs/minpgc.md b/docs/minpgc.md index a09895bd..6389bb50 100644 --- a/docs/minpgc.md +++ b/docs/minpgc.md @@ -3,29 +3,29 @@ This document describes the "minpgc" simple persistent conferences implementation of PR #1069. -Many of the ideas derive from isotoxin's persistent conferences -implementation, PR #826. +Many of the ideas derive from isotoxin's persistent conferences implementation, +PR #826. ## Specification of changes from pre-existing conference specification + We add one new packet type: Rejoin Conference packet -| Length | Contents | -|:-------|:--------------------------------| -| `1` | `uint8_t` (0x64) | -| `33` | Group chat identifier | +| Length | Contents | +| :----- | :-------------------- | +| `1` | `uint8_t` (0x64) | +| `33` | Group chat identifier | +A peer times out from a group if it has been inactive for 60s. When a peer times +out, we flag it as _frozen_. Frozen peers are disregarded for all purposes +except those discussed below - in particular no packets are sent to them except +as described below, they are omitted from the peer lists sent to the client or +in a Peer Response packet, and they are not considered when determining closest +peers for establishing direct connections. -A peer times out from a group if it has been inactive for 60s. When a peer -times out, we flag it as _frozen_. Frozen peers are disregarded for all -purposes except those discussed below - in particular no packets are sent to -them except as described below, they are omitted from the peer lists sent to -the client or in a Peer Response packet, and they are not considered when -determining closest peers for establishing direct connections. - -A peer is considered to be active if we receive a group message or Rejoin -packet from it, or a New Peer message for it. +A peer is considered to be active if we receive a group message or Rejoin packet +from it, or a New Peer message for it. If a frozen peer is seen to be active, we remove its 'frozen' flag and send a Name group message. (We can hold off on sending this message until the next @@ -40,77 +40,83 @@ message. (This is current behaviour; it's mentioned here because it's important and not currently mentioned in the spec.) If we receive a Rejoin packet from a peer we update its DHT pubkey, add a -temporary groupchat connection for the peer, and, once the connection is -online, send out a New Peer message announcing the peer, and a Name message. +temporary groupchat connection for the peer, and, once the connection is online, +send out a New Peer message announcing the peer, and a Name message. -Whenever we make a new friend connection, we check if the public key is that -of any frozen peer. If so, we send it a Rejoin packet, add a temporary -groupchat connection for it, and, once the connection is online, send the -peer a Peer Query packet. +Whenever we make a new friend connection, we check if the public key is that of +any frozen peer. If so, we send it a Rejoin packet, add a temporary groupchat +connection for it, and, once the connection is online, send the peer a Peer +Query packet. -We do the same with a peer when we are setting it as frozen if we have a -friend connection to it. +We do the same with a peer when we are setting it as frozen if we have a friend +connection to it. The temporary groupchat connections established in sending and handling Rejoin packets are not immediately operational (because group numbers are not known); rather, an Online packet is sent when we handle a Rejoin packet. -When a connection is set as online as a result of an Online packet, we ping -the group. +When a connection is set as online as a result of an Online packet, we ping the +group. When processing the reply to a Peer Query, we update the DHT pubkey of an -existing peer if and only if it is frozen or has not had its DHT pubkey -updated since it last stopped being frozen. +existing peer if and only if it is frozen or has not had its DHT pubkey updated +since it last stopped being frozen. When we receive a Title Response packet, we set the title if it has never been set or if at some point since it was last set, there were no unfrozen peers (except us). ## Discussion -### Overview -The intention is to recover seamlessly from splits in the group, the most -common form of which is a single peer temporarily losing all connectivity. -To see how this works, first note that groups (even before the changes -discussed here) have the property that for a group to be connected in the -sense that any peer will receive the messages of any other peer and have them -in their peerlist, it is necessary and sufficient that there is a path of -direct group connections between any two peers. +### Overview + +The intention is to recover seamlessly from splits in the group, the most common +form of which is a single peer temporarily losing all connectivity. + +To see how this works, first note that groups (even before the changes discussed +here) have the property that for a group to be connected in the sense that any +peer will receive the messages of any other peer and have them in their +peerlist, it is necessary and sufficient that there is a path of direct group +connections between any two peers. Now suppose the group is split into two connected components, with each member -of one component frozen according to the members of the other. Suppose there -are two peers, one in each component, which are using the above protocol, and +of one component frozen according to the members of the other. Suppose there are +two peers, one in each component, which are using the above protocol, and suppose they establish a friend connection. Then each will rejoin the other, forming a direct group connection. Hence the whole group will become connected (even if all other peers are using the unmodified protocol). The Peer Query packet sent on rejoining hastens this process. -Peers who leave the group during a split will not be deleted by all peers -after the merge - but they will be set as frozen due to ping timeouts, which -is sufficient. +Peers who leave the group during a split will not be deleted by all peers after +the merge - but they will be set as frozen due to ping timeouts, which is +sufficient. ### Titles -If we have a split into components each containing multiple peers, and the -title is changed in one component, then peers will continue to disagree on the -title after the split. Short of a complicated voting system, this seems the -only reasonable behaviour. + +If we have a split into components each containing multiple peers, and the title +is changed in one component, then peers will continue to disagree on the title +after the split. Short of a complicated voting system, this seems the only +reasonable behaviour. ### Implementation notes -Although I've described the logic in terms of an 'frozen' flag, it might -actually make more sense in the implementation to have a separate list for + +Although I've described the logic in terms of an 'frozen' flag, it might +actually make more sense in the implementation to have a separate list for frozen peers. ## Saving + Saving is implemented by simply saving all live groups with their group numbers and full peer info for all peers. On reload, all peers are set as frozen. Clients needs to support this by understanding that groups may exist on start-up. Clients should call `tox_conference_get_chatlist` to obtain them. A -group which is deleted (with `tox_conference_delete`) is removed permanently -and will not be saved. +group which is deleted (with `tox_conference_delete`) is removed permanently and +will not be saved. ## Limitations + If a peer disconnects from the group for a period short enough that group timeouts do not occur, and a name change occurs during this period, then the name change will never be propagated. @@ -120,9 +126,8 @@ requesting missed group messages. But this is considered out of scope of this PR. If a peer changes its DHT pubkey, the change might not be properly propagated -under various circumstances - in particular, if connections do not go down -long enough for the peer to become frozen. +under various circumstances - in particular, if connections do not go down long +enough for the peer to become frozen. -One way to deal with this would be to add a group message announcing the -sending peer's current DHT pubkey, and treat it analogously to the Name -message. +One way to deal with this would be to add a group message announcing the sending +peer's current DHT pubkey, and treat it analogously to the Name message. diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index 5fd2568d..8a15fb5e 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -50,7 +50,6 @@ static const char *motd_str = ""; //Change this to anything within 256 bytes(but #define PORT 33445 - static bool manage_keys(DHT *dht) { enum { KEYS_SIZE = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE }; @@ -61,7 +60,7 @@ static bool manage_keys(DHT *dht) if (keys_file != nullptr) { /* If file was opened successfully -- load keys, otherwise save new keys */ - size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file); + const size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file); if (read_size != KEYS_SIZE) { printf("Error while reading the key file\nExiting.\n"); @@ -126,7 +125,7 @@ static void print_log(void *context, Logger_Level level, const char *file, int l int main(int argc, char *argv[]) { - if (argc == 2 && !tox_strncasecmp(argv[1], "-h", 3)) { + if (argc == 2 && tox_strncasecmp(argv[1], "-h", 3) == 0) { printf("Usage (connected) : %s [--ipv4|--ipv6] IP PORT KEY\n", argv[0]); printf("Usage (unconnected): %s [--ipv4|--ipv6]\n", argv[0]); return 0; @@ -134,7 +133,7 @@ int main(int argc, char *argv[]) /* let user override default by cmdline */ bool ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ - int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); + const int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); if (argvoffset < 0) { return 1; @@ -151,9 +150,9 @@ int main(int argc, char *argv[]) logger_callback_log(logger, print_log, nullptr, nullptr); } - const Random *rng = system_random(); - const Network *ns = system_network(); - const Memory *mem = system_memory(); + const Random *rng = os_random(); + const Network *ns = os_network(); + const Memory *mem = os_memory(); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); const uint16_t start_port = PORT; @@ -165,11 +164,12 @@ int main(int argc, char *argv[]) Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht); #ifdef DHT_NODE_EXTRA_PACKETS - bootstrap_set_callbacks(dht_get_net(dht), (uint32_t)DAEMON_VERSION_NUMBER, (const uint8_t *) motd_str, strlen(motd_str)+1); + bootstrap_set_callbacks(dht_get_net(dht), (uint32_t)DAEMON_VERSION_NUMBER, (const uint8_t *) motd_str, strlen(motd_str) + 1); #endif - if (!(onion && forwarding && onion_a)) { + if (onion == nullptr || forwarding == nullptr || onion_a == nullptr) { printf("Something failed to initialize.\n"); + // cppcheck-suppress resourceLeak return 1; } @@ -178,17 +178,19 @@ int main(int argc, char *argv[]) perror("Initialization"); if (!manage_keys(dht)) { + // cppcheck-suppress resourceLeak return 1; } printf("Public key: "); #ifdef TCP_RELAY_ENABLED #define NUM_PORTS 3 - uint16_t ports[NUM_PORTS] = {443, 3389, PORT}; + const uint16_t ports[NUM_PORTS] = {443, 3389, PORT}; TCP_Server *tcp_s = new_tcp_server(logger, mem, rng, ns, ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion, forwarding); if (tcp_s == nullptr) { printf("TCP server failed to initialize.\n"); + // cppcheck-suppress resourceLeak return 1; } @@ -199,6 +201,7 @@ int main(int argc, char *argv[]) if (file == nullptr) { printf("Could not open file \"%s\" for writing. Exiting...\n", public_id_filename); + // cppcheck-suppress resourceLeak return 1; } @@ -226,8 +229,8 @@ int main(int argc, char *argv[]) const uint16_t port = net_htons((uint16_t)port_conv); uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]); - int res = dht_bootstrap_from_address(dht, argv[argvoffset + 1], - ipv6enabled, port, bootstrap_key); + const bool res = dht_bootstrap_from_address(dht, argv[argvoffset + 1], + ipv6enabled, port, bootstrap_key); free(bootstrap_key); if (!res) { @@ -236,17 +239,17 @@ int main(int argc, char *argv[]) } } - int is_waiting_for_dht_connection = 1; + bool is_waiting_for_dht_connection = true; uint64_t last_lan_discovery = 0; const Broadcast_Info *broadcast = lan_discovery_init(ns); - while (1) { + while (true) { mono_time_update(mono_time); if (is_waiting_for_dht_connection && dht_isconnected(dht)) { printf("Connected to other bootstrap node successfully.\n"); - is_waiting_for_dht_connection = 0; + is_waiting_for_dht_connection = false; } do_dht(dht); diff --git a/other/analysis/run-clang-tidy b/other/analysis/run-clang-tidy index dc07f946..bcdb78f5 100755 --- a/other/analysis/run-clang-tidy +++ b/other/analysis/run-clang-tidy @@ -3,17 +3,20 @@ CHECKS="*" ERRORS="*" +# Can't fix this, because winsock has different HANDLE type than posix. +# Still good to occasionally look at. +ERRORS="$ERRORS,-google-readability-casting" + # Need to investigate or disable and document these. # ========================================================= # TODO(iphydf): Fix these. ERRORS="$ERRORS,-cert-err34-c" ERRORS="$ERRORS,-readability-suspicious-call-argument" +CHECKS="$CHECKS,-cppcoreguidelines-avoid-goto,-hicpp-avoid-goto" +CHECKS="$CHECKS,-bugprone-incorrect-roundings" -# TODO(iphydf): Fix once cimple 0.0.19 is released. -CHECKS="$CHECKS,-google-readability-casting" - -# TODO(iphydf): Fix these. +# TODO(iphydf): Fix this by making more functions set error code enums. CHECKS="$CHECKS,-bugprone-switch-missing-default-case" # TODO(iphydf): We might want some of these. For the ones we don't want, add a @@ -30,17 +33,22 @@ CHECKS="$CHECKS,-misc-no-recursion" CHECKS="$CHECKS,-cppcoreguidelines-avoid-non-const-global-variables" # TODO(iphydf): Probably fix these. -CHECKS="$CHECKS,-cert-err33-c" -CHECKS="$CHECKS,-cppcoreguidelines-avoid-magic-numbers" -CHECKS="$CHECKS,-readability-magic-numbers" - -# TODO(iphydf): We're using a lot of macros for constants. Should we convert -# all of them to enum? -CHECKS="$CHECKS,-modernize-macro-to-enum" +CHECKS="$CHECKS,-cert-err33-c,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers" # Documented disabled checks. We don't want these for sure. # ========================================================= +# We want to decay many arrays to pointers. In C, we do that all the time. +CHECKS="$CHECKS,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-hicpp-no-array-decay" + +# enum{} breaks comparisons and arithmetic in C++. +CHECKS="$CHECKS,-modernize-macro-to-enum" + +# For most things, we do want this, but for some we want to ensure (with msan) +# that struct members are actually initialised with useful non-zero values. +# Initialising them by default takes away that validation. +CHECKS="$CHECKS,-cppcoreguidelines-pro-type-member-init,-hicpp-member-init" + # https://stackoverflow.com/questions/58672959/why-does-clang-tidy-say-vsnprintf-has-an-uninitialized-va-list-argument CHECKS="$CHECKS,-clang-analyzer-valist.Uninitialized" @@ -115,8 +123,7 @@ CHECKS="$CHECKS,-readability-redundant-control-flow" # ^ # Trip the checker, which is true, because of integer promotion, but also not # very helpful as a diagnostic. -CHECKS="$CHECKS,-bugprone-narrowing-conversions" -CHECKS="$CHECKS,-cppcoreguidelines-narrowing-conversions" +CHECKS="$CHECKS,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions" # Mistakenly thinks that # const int a = 0, b = 1; @@ -135,9 +142,51 @@ CHECKS="$CHECKS,-cppcoreguidelines-narrowing-conversions" # - Turning 'a' and 'b' into pre-processor macros is the only option left, but # #defines and #undefs in the middle of a function hurt the readability and # are less idiomatic than simply using 'const int'. -CHECKS="$CHECKS,-cert-dcl03-c" -CHECKS="$CHECKS,-hicpp-static-assert" -CHECKS="$CHECKS,-misc-static-assert" +CHECKS="$CHECKS,-cert-dcl03-c,-hicpp-static-assert,-misc-static-assert" + +# Doesn't consider use of preprocessor macros as needing a header, breaking +# struct definitions that depend on size macros from e.g. crypto_core.h. +CHECKS="$CHECKS,-misc-include-cleaner" + +# A bunch of checks only valid for C++, we turn off for C. +# ========================================================= + +# We don't use Google's int typedefs. +CHECKS="$CHECKS,-google-runtime-int" +# We write C code, so we use C arrays. +CHECKS="$CHECKS,-cppcoreguidelines-avoid-c-arrays,-hicpp-avoid-c-arrays,-modernize-avoid-c-arrays" +# C loops are ok. This one tells us to use range-for. +CHECKS="$CHECKS,-modernize-loop-convert" +# No auto in C. +CHECKS="$CHECKS,-hicpp-use-auto,-modernize-use-auto" +# Only C style casts in C. +CHECKS="$CHECKS,-cppcoreguidelines-pro-type-cstyle-cast" +# We use malloc (for now), and MISRA checks this too. +CHECKS="$CHECKS,-cppcoreguidelines-no-malloc,-hicpp-no-malloc" +# No owning_ptr<> in C. +CHECKS="$CHECKS,-cppcoreguidelines-owning-memory" +# void foo(void) is good in C. +CHECKS="$CHECKS,-modernize-redundant-void-arg" +# No using-typedefs in C. +CHECKS="$CHECKS,-modernize-use-using" +# No namespaces in C. +CHECKS="$CHECKS,-misc-use-anonymous-namespace" +# No trailing return type in C. +CHECKS="$CHECKS,-modernize-use-trailing-return-type" +# No and friends in C. +CHECKS="$CHECKS,-hicpp-deprecated-headers,-modernize-deprecated-headers" +# We use varargs for logging (we could reconsider, but right now we do). +CHECKS="$CHECKS,-cppcoreguidelines-pro-type-vararg,-hicpp-vararg,-cert-dcl50-cpp" +# We do want to use the array index operator, even when the index is non-constant. +CHECKS="$CHECKS,-cppcoreguidelines-pro-bounds-constant-array-index" +# We don't want to use pointer arithmetic, but this one includes array index +# operators, which we do want to use. +CHECKS="$CHECKS,-cppcoreguidelines-pro-bounds-pointer-arithmetic" +# Can't use constexpr, yet. C will have it eventually, but it'll be years +# until we can use it across all the compilers. +CHECKS="$CHECKS,-cppcoreguidelines-macro-usage" +# These are all very C++ and/or LLVM specific. +CHECKS="$CHECKS,-llvmlibc-*" set -eux @@ -154,7 +203,7 @@ copy_files() { find "${DIRS[@]}" \ -maxdepth 1 -type d -exec mkdir -p "$1/{}" \; find "${DIRS[@]}" \ - -maxdepth 1 -name "*.c" -exec cp "{}" "$1/{}" \; + -maxdepth 1 -name "*.[ch]" -exec cp "{}" "$1/{}" \; } run() { @@ -166,7 +215,7 @@ run() { ls .clang-tidy copy_files a if ! find "${DIRS[@]}" \ - -maxdepth 1 -name "*.c" -print0 \ + -maxdepth 1 -name "*.[ch]" -print0 \ | xargs -0 -n15 -P"$(nproc)" clang-tidy \ -p="$PWD/_build" \ --extra-arg=-DMIN_LOGGER_LEVEL=LOGGER_LEVEL_TRACE \ @@ -184,5 +233,6 @@ run() { } cmake . -B_build -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON +sed -i -e 's/-std=c11/-xc++/' _build/compile_commands.json . other/analysis/variants.sh diff --git a/other/astyle/astylerc b/other/astyle/astylerc index 9554a3e5..ab17b797 100644 --- a/other/astyle/astylerc +++ b/other/astyle/astylerc @@ -1,5 +1,6 @@ # Bracket Style Options --style=kr +--attach-namespaces # Tab Options --indent=spaces=4 @@ -9,15 +10,21 @@ # Padding Options --pad-header ---break-blocks --pad-oper +# Not supported in restyled's astyle. +#--unpad-brackets --unpad-paren --align-pointer=name --align-reference=name +# Disabled because it causes very large changes and it's unclear whether we +# want all of those. +#--squeeze-ws # Formatting Options +--add-braces --convert-tabs ---max-code-length=120 +--max-code-length=200 +--attach-return-type # Other Options --preserve-date diff --git a/other/astyle/format-source b/other/astyle/format-source index cb8b8feb..3118b885 100755 --- a/other/astyle/format-source +++ b/other/astyle/format-source @@ -2,36 +2,6 @@ set -ex -SOURCE_DIR="$1" -ASTYLE="$2" - -# Go to the source root. -if [ -z "$SOURCE_DIR" ]; then - SOURCE_DIR=. -fi -cd "$SOURCE_DIR" - -if [ -z "$ASTYLE" ] || ! which "$ASTYLE"; then - ASTYLE=astyle -fi - -if ! which "$ASTYLE"; then - # If we couldn't find or install an astyle binary, don't do anything. - echo "Could not find an astyle binary; please install astyle." - exit 1 -fi - -readarray -t CC_SOURCES <<<"$(find . '(' -name '*.cc' ')')" -CC_SOURCES+=(toxcore/crypto_core.c) -CC_SOURCES+=(toxcore/ping_array.c) - -for bin in clang-format-11 clang-format-7 clang-format-6.0 clang-format-5.0 clang-format; do - if which "$bin"; then - "$bin" -i -style='{BasedOnStyle: Google, ColumnLimit: 100}' "${CC_SOURCES[@]}" - break - fi -done - FIND="find ." FIND="$FIND '(' -name '*.[ch]' ')'" FIND="$FIND -and -not -name '*.api.h'" @@ -40,7 +10,15 @@ FIND="$FIND -and -not -wholename './third_party/*'" FIND="$FIND -and -not -wholename './toxencryptsave/crypto_pwhash*'" readarray -t C_SOURCES <<<"$(eval "$FIND")" +readarray -t CC_SOURCES <<<"$(find . '(' -name '*.cc' -or -name '*.hh' ')')" +#CC_SOURCES+=(toxcore/crypto_core.c) +#CC_SOURCES+=(toxcore/ping_array.c) -"$ASTYLE" -n --options=other/astyle/astylerc "${C_SOURCES[@]}" +# Format C++ sources with clang-format. +clang-format -i "${CC_SOURCES[@]}" + +# Format C sources with astyle. We can't use clang-format, because it strongly +# messes up formatting of non_null annotations. +astyle -n --options=other/astyle/astylerc "${C_SOURCES[@]}" git diff --color=always --exit-code diff --git a/other/bootstrap_daemon/docker/Dockerfile b/other/bootstrap_daemon/docker/Dockerfile index 9fc0f517..1cbaf4c0 100644 --- a/other/bootstrap_daemon/docker/Dockerfile +++ b/other/bootstrap_daemon/docker/Dockerfile @@ -48,8 +48,9 @@ RUN CC=clang cmake -B_build -H. \ # Verify checksum from dev-built binary, so we can be sure Docker Hub doesn't # mess with your binaries. COPY other/bootstrap_daemon/docker/tox-bootstrapd.sha256 other/bootstrap_daemon/docker/ -RUN SHA256="$(sha256sum /usr/local/bin/tox-bootstrapd)" && \ - (sha256sum -c other/bootstrap_daemon/docker/tox-bootstrapd.sha256 || \ +ARG CHECK=sha256sum +RUN SHA256="$("$CHECK" /usr/local/bin/tox-bootstrapd)" && \ + ("$CHECK" -c other/bootstrap_daemon/docker/tox-bootstrapd.sha256 || \ (echo "::error file=other/bootstrap_daemon/docker/tox-bootstrapd.sha256,line=1::$SHA256" && \ false)) diff --git a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 index fc02a5e4..faef8b86 100644 --- a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 +++ b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 @@ -1 +1 @@ -0b904988d79b9576bb88c6c7316d107b5a61bd6119a0992ebd7c1fa43db70abf /usr/local/bin/tox-bootstrapd +af58a125e5c80d7a19bc7f32868c1edfdf80f366e3bf778728961a50ce63ee26 /usr/local/bin/tox-bootstrapd diff --git a/other/bootstrap_daemon/src/command_line_arguments.c b/other/bootstrap_daemon/src/command_line_arguments.c index a2e696c3..3b798efb 100644 --- a/other/bootstrap_daemon/src/command_line_arguments.c +++ b/other/bootstrap_daemon/src/command_line_arguments.c @@ -18,7 +18,6 @@ #include - /** * Prints --help message */ @@ -48,8 +47,8 @@ static void print_help(void) } Cli_Status handle_command_line_arguments( - int argc, char *argv[], char **cfg_file_path, LOG_BACKEND *log_backend, - bool *run_in_foreground) + int argc, char *argv[], char **cfg_file_path, LOG_BACKEND *log_backend, + bool *run_in_foreground) { if (argc < 2) { log_write(LOG_LEVEL_ERROR, "Error: No arguments provided.\n\n"); diff --git a/other/bootstrap_daemon/src/command_line_arguments.h b/other/bootstrap_daemon/src/command_line_arguments.h index 3595ece3..3be39530 100644 --- a/other/bootstrap_daemon/src/command_line_arguments.h +++ b/other/bootstrap_daemon/src/command_line_arguments.h @@ -32,7 +32,7 @@ typedef enum Cli_Status { * @param run_in_foreground Sets to the provided by the user foreground option. */ Cli_Status handle_command_line_arguments( - int argc, char *argv[], char **cfg_file_path, LOG_BACKEND *log_backend, - bool *run_in_foreground); + int argc, char *argv[], char **cfg_file_path, LOG_BACKEND *log_backend, + bool *run_in_foreground); #endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_COMMAND_LINE_ARGUMENTS_H diff --git a/other/bootstrap_daemon/src/config.c b/other/bootstrap_daemon/src/config.c index b20925b1..891912dc 100644 --- a/other/bootstrap_daemon/src/config.c +++ b/other/bootstrap_daemon/src/config.c @@ -44,13 +44,13 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por log_write(LOG_LEVEL_WARNING, "No '%s' setting in the configuration file.\n", NAME_TCP_RELAY_PORTS); log_write(LOG_LEVEL_WARNING, "Using default '%s':\n", NAME_TCP_RELAY_PORTS); - uint16_t default_ports[] = {DEFAULT_TCP_RELAY_PORTS}; + const uint16_t default_ports[] = {DEFAULT_TCP_RELAY_PORTS}; // Check to avoid calling malloc(0) later on // NOLINTNEXTLINE, clang-tidy: error: suspicious comparison of 'sizeof(expr)' to a constant [bugprone-sizeof-expression,-warnings-as-errors] static_assert(sizeof(default_ports) > 0, "At least one default TCP relay port should be provided"); - const size_t default_ports_count = sizeof(default_ports)/sizeof(*default_ports); + const size_t default_ports_count = sizeof(default_ports) / sizeof(*default_ports); for (size_t i = 0; i < default_ports_count; ++i) { log_write(LOG_LEVEL_INFO, "Port #%zu: %u\n", i, default_ports[i]); @@ -58,6 +58,10 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por // Similar procedure to the one of reading config file below *tcp_relay_ports = (uint16_t *)malloc(default_ports_count * sizeof(uint16_t)); + if (*tcp_relay_ports == nullptr) { + log_write(LOG_LEVEL_ERROR, "Allocation failure.\n"); + return; + } for (size_t i = 0; i < default_ports_count; ++i) { @@ -73,10 +77,8 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por ++*tcp_relay_port_count; } - // The loop above skips invalid ports, so we adjust the allocated memory size - if ((*tcp_relay_port_count) > 0) { - *tcp_relay_ports = (uint16_t *)realloc(*tcp_relay_ports, (*tcp_relay_port_count) * sizeof(uint16_t)); - } else { + // No ports, so we free the array. + if (*tcp_relay_port_count == 0) { free(*tcp_relay_ports); *tcp_relay_ports = nullptr; } @@ -90,7 +92,7 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por return; } - int config_port_count = config_setting_length(ports_array); + const int config_port_count = config_setting_length(ports_array); if (config_port_count == 0) { log_write(LOG_LEVEL_ERROR, "'%s' is empty.\n", NAME_TCP_RELAY_PORTS); @@ -98,6 +100,10 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por } *tcp_relay_ports = (uint16_t *)malloc(config_port_count * sizeof(uint16_t)); + if (*tcp_relay_ports == nullptr) { + log_write(LOG_LEVEL_ERROR, "Allocation failure.\n"); + return; + } for (int i = 0; i < config_port_count; ++i) { config_setting_t *elem = config_setting_get_elem(ports_array, i); @@ -125,18 +131,16 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por ++*tcp_relay_port_count; } - // The loop above skips invalid ports, so we adjust the allocated memory size - if ((*tcp_relay_port_count) > 0) { - *tcp_relay_ports = (uint16_t *)realloc(*tcp_relay_ports, (*tcp_relay_port_count) * sizeof(uint16_t)); - } else { + // No ports, so we free the array. + if (*tcp_relay_port_count == 0) { free(*tcp_relay_ports); *tcp_relay_ports = nullptr; } } -int get_general_config(const char *cfg_file_path, char **pid_file_path, char **keys_file_path, int *port, - int *enable_ipv6, int *enable_ipv4_fallback, int *enable_lan_discovery, int *enable_tcp_relay, - uint16_t **tcp_relay_ports, int *tcp_relay_port_count, int *enable_motd, char **motd) +bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **keys_file_path, int *port, + int *enable_ipv6, int *enable_ipv4_fallback, int *enable_lan_discovery, int *enable_tcp_relay, + uint16_t **tcp_relay_ports, int *tcp_relay_port_count, int *enable_motd, char **motd) { config_t cfg; @@ -156,7 +160,7 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k if (config_read_file(&cfg, cfg_file_path) == CONFIG_FALSE) { log_write(LOG_LEVEL_ERROR, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg)); config_destroy(&cfg); - return 0; + return false; } // Get port @@ -177,6 +181,10 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k const size_t pid_file_path_len = strlen(tmp_pid_file) + 1; *pid_file_path = (char *)malloc(pid_file_path_len); + if (*pid_file_path == nullptr) { + log_write(LOG_LEVEL_ERROR, "Allocation failure.\n"); + return false; + } memcpy(*pid_file_path, tmp_pid_file, pid_file_path_len); // Get keys file location @@ -190,6 +198,10 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k const size_t keys_file_path_len = strlen(tmp_keys_file) + 1; *keys_file_path = (char *)malloc(keys_file_path_len); + if (*keys_file_path == nullptr) { + log_write(LOG_LEVEL_ERROR, "Allocation failure.\n"); + return false; + } memcpy(*keys_file_path, tmp_keys_file, keys_file_path_len); // Get IPv6 option @@ -223,7 +235,7 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k *enable_tcp_relay = DEFAULT_ENABLE_TCP_RELAY; } - if (*enable_tcp_relay) { + if (*enable_tcp_relay != 0) { parse_tcp_relay_ports_config(&cfg, tcp_relay_ports, tcp_relay_port_count); } else { *tcp_relay_port_count = 0; @@ -237,7 +249,7 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k *enable_motd = DEFAULT_ENABLE_MOTD; } - if (*enable_motd) { + if (*enable_motd != 0) { // Get MOTD const char *tmp_motd; @@ -247,8 +259,8 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k tmp_motd = DEFAULT_MOTD; } - size_t tmp_motd_length = strlen(tmp_motd) + 1; - size_t motd_length = tmp_motd_length > MAX_MOTD_LENGTH ? MAX_MOTD_LENGTH : tmp_motd_length; + const size_t tmp_motd_length = strlen(tmp_motd) + 1; + const size_t motd_length = tmp_motd_length > MAX_MOTD_LENGTH ? MAX_MOTD_LENGTH : tmp_motd_length; *motd = (char *)malloc(motd_length); snprintf(*motd, motd_length, "%s", tmp_motd); } @@ -259,14 +271,14 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_PID_FILE_PATH, *pid_file_path); log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_KEYS_FILE_PATH, *keys_file_path); log_write(LOG_LEVEL_INFO, "'%s': %d\n", NAME_PORT, *port); - log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV6, *enable_ipv6 ? "true" : "false"); - log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV4_FALLBACK, *enable_ipv4_fallback ? "true" : "false"); - log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, *enable_lan_discovery ? "true" : "false"); + log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV6, *enable_ipv6 != 0 ? "true" : "false"); + log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV4_FALLBACK, *enable_ipv4_fallback != 0 ? "true" : "false"); + log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, *enable_lan_discovery != 0 ? "true" : "false"); - log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_TCP_RELAY, *enable_tcp_relay ? "true" : "false"); + log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_TCP_RELAY, *enable_tcp_relay != 0 ? "true" : "false"); // Show info about tcp ports only if tcp relay is enabled - if (*enable_tcp_relay) { + if (*enable_tcp_relay != 0) { if (*tcp_relay_port_count == 0) { log_write(LOG_LEVEL_ERROR, "No TCP ports could be read.\n"); } else { @@ -278,13 +290,13 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k } } - log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_MOTD, *enable_motd ? "true" : "false"); + log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_MOTD, *enable_motd != 0 ? "true" : "false"); - if (*enable_motd) { + if (*enable_motd != 0) { log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_MOTD, *motd); } - return 1; + return true; } /** @@ -302,8 +314,12 @@ static uint8_t *bootstrap_hex_string_to_bin(const char *hex_string) return nullptr; } - size_t len = strlen(hex_string) / 2; + const size_t len = strlen(hex_string) / 2; uint8_t *ret = (uint8_t *)malloc(len); + if (ret == nullptr) { + log_write(LOG_LEVEL_ERROR, "Allocation failure.\n"); + return nullptr; + } const char *pos = hex_string; @@ -316,7 +332,7 @@ static uint8_t *bootstrap_hex_string_to_bin(const char *hex_string) return ret; } -int bootstrap_from_config(const char *cfg_file_path, DHT *dht, int enable_ipv6) +bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6) { const char *const NAME_BOOTSTRAP_NODES = "bootstrap_nodes"; @@ -331,7 +347,7 @@ int bootstrap_from_config(const char *cfg_file_path, DHT *dht, int enable_ipv6) if (config_read_file(&cfg, cfg_file_path) == CONFIG_FALSE) { log_write(LOG_LEVEL_ERROR, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg)); config_destroy(&cfg); - return 0; + return false; } config_setting_t *node_list = config_lookup(&cfg, NAME_BOOTSTRAP_NODES); @@ -340,13 +356,13 @@ int bootstrap_from_config(const char *cfg_file_path, DHT *dht, int enable_ipv6) log_write(LOG_LEVEL_WARNING, "No '%s' setting in the configuration file. Skipping bootstrapping.\n", NAME_BOOTSTRAP_NODES); config_destroy(&cfg); - return 1; + return true; } if (config_setting_length(node_list) == 0) { log_write(LOG_LEVEL_WARNING, "No bootstrap nodes found. Skipping bootstrapping.\n"); config_destroy(&cfg); - return 1; + return true; } int bs_port; @@ -357,15 +373,15 @@ int bootstrap_from_config(const char *cfg_file_path, DHT *dht, int enable_ipv6) int i = 0; - while (config_setting_length(node_list)) { - int address_resolved; + while (config_setting_length(node_list) != 0) { + bool address_resolved; uint8_t *bs_public_key_bin; node = config_setting_get_elem(node_list, 0); if (node == nullptr) { config_destroy(&cfg); - return 0; + return false; } // Check that all settings are present @@ -421,5 +437,5 @@ next: config_destroy(&cfg); - return 1; + return true; } diff --git a/other/bootstrap_daemon/src/config.h b/other/bootstrap_daemon/src/config.h index ae9aff8c..be1e57aa 100644 --- a/other/bootstrap_daemon/src/config.h +++ b/other/bootstrap_daemon/src/config.h @@ -19,19 +19,19 @@ * also, iff `tcp_relay_ports_count` > 0, then you are responsible for freeing `tcp_relay_ports` * and also `motd` iff `enable_motd` is set. * - * @return 1 on success, - * 0 on failure, doesn't modify any data pointed by arguments. + * @return true on success, + * false on failure, doesn't modify any data pointed by arguments. */ -int get_general_config(const char *cfg_file_path, char **pid_file_path, char **keys_file_path, int *port, - int *enable_ipv6, int *enable_ipv4_fallback, int *enable_lan_discovery, int *enable_tcp_relay, - uint16_t **tcp_relay_ports, int *tcp_relay_port_count, int *enable_motd, char **motd); +bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **keys_file_path, int *port, + int *enable_ipv6, int *enable_ipv4_fallback, int *enable_lan_discovery, int *enable_tcp_relay, + uint16_t **tcp_relay_ports, int *tcp_relay_port_count, int *enable_motd, char **motd); /** * Bootstraps off nodes listed in the config file. * - * @return 1 on success, some or no bootstrap nodes were added - * 0 on failure, an error occurred while parsing the config file. + * @return true on success, some or no bootstrap nodes were added + * false on failure, an error occurred while parsing the config file. */ -int bootstrap_from_config(const char *cfg_file_path, DHT *dht, int enable_ipv6); +bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6); #endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_H diff --git a/other/bootstrap_daemon/src/log.c b/other/bootstrap_daemon/src/log.c index ed3bf03d..5dde7b52 100644 --- a/other/bootstrap_daemon/src/log.c +++ b/other/bootstrap_daemon/src/log.c @@ -58,7 +58,6 @@ bool log_close(void) return true; } - bool log_write(LOG_LEVEL level, const char *format, ...) { if (current_backend == INVALID_BACKEND) { diff --git a/other/bootstrap_daemon/src/log.h b/other/bootstrap_daemon/src/log.h index 162b8683..79126258 100644 --- a/other/bootstrap_daemon/src/log.h +++ b/other/bootstrap_daemon/src/log.h @@ -12,7 +12,7 @@ #include -#include "../../../toxcore/ccompat.h" +#include "../../../toxcore/attributes.h" typedef enum LOG_BACKEND { LOG_BACKEND_STDOUT, @@ -47,5 +47,4 @@ bool log_close(void); */ bool log_write(LOG_LEVEL level, const char *format, ...) GNU_PRINTF(2, 3); - #endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_H diff --git a/other/bootstrap_daemon/src/log_backend_stdout.h b/other/bootstrap_daemon/src/log_backend_stdout.h index b2c8dc7b..131d48da 100644 --- a/other/bootstrap_daemon/src/log_backend_stdout.h +++ b/other/bootstrap_daemon/src/log_backend_stdout.h @@ -10,10 +10,11 @@ #ifndef C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_STDOUT_H #define C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_STDOUT_H -#include "log.h" - #include +#include "../../../toxcore/attributes.h" +#include "log.h" + void log_backend_stdout_write(LOG_LEVEL level, const char *format, va_list args) GNU_PRINTF(2, 0); -#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_STDOUT_H +#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_STDOUT_H diff --git a/other/bootstrap_daemon/src/log_backend_syslog.c b/other/bootstrap_daemon/src/log_backend_syslog.c index 1f73d9a6..c5fccefd 100644 --- a/other/bootstrap_daemon/src/log_backend_syslog.c +++ b/other/bootstrap_daemon/src/log_backend_syslog.c @@ -51,7 +51,7 @@ void log_backend_syslog_write(LOG_LEVEL level, const char *format, va_list args) va_list args2; va_copy(args2, args); - int size = vsnprintf(nullptr, 0, format, args2); + const int size = vsnprintf(nullptr, 0, format, args2); va_end(args2); assert(size >= 0); @@ -61,6 +61,9 @@ void log_backend_syslog_write(LOG_LEVEL level, const char *format, va_list args) } char *buf = (char *)malloc(size + 1); + if (buf == nullptr) { + return; + } vsnprintf(buf, size + 1, format, args); syslog(log_backend_syslog_level(level), "%s", buf); diff --git a/other/bootstrap_daemon/src/log_backend_syslog.h b/other/bootstrap_daemon/src/log_backend_syslog.h index 6cb9eade..8e919f03 100644 --- a/other/bootstrap_daemon/src/log_backend_syslog.h +++ b/other/bootstrap_daemon/src/log_backend_syslog.h @@ -10,12 +10,13 @@ #ifndef C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_SYSLOG_H #define C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_SYSLOG_H -#include "log.h" - #include +#include "../../../toxcore/attributes.h" +#include "log.h" + void log_backend_syslog_open(void); void log_backend_syslog_close(void); void log_backend_syslog_write(LOG_LEVEL level, const char *format, va_list args) GNU_PRINTF(2, 0); -#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_SYSLOG_H +#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_SYSLOG_H diff --git a/other/bootstrap_daemon/src/tox-bootstrapd.c b/other/bootstrap_daemon/src/tox-bootstrapd.c index 45b3bfc4..44a9c282 100644 --- a/other/bootstrap_daemon/src/tox-bootstrapd.c +++ b/other/bootstrap_daemon/src/tox-bootstrapd.c @@ -50,7 +50,6 @@ #include "global.h" #include "log.h" - static void sleep_milliseconds(uint32_t ms) { struct timespec req; @@ -61,10 +60,10 @@ static void sleep_milliseconds(uint32_t ms) // Uses the already existing key or creates one if it didn't exist // -// returns 1 on success -// 0 on failure - no keys were read or stored +// returns true on success +// false on failure - no keys were read or stored -static int manage_keys(DHT *dht, const char *keys_file_path) +static bool manage_keys(DHT *dht, const char *keys_file_path) { enum { KEYS_SIZE = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE }; uint8_t keys[KEYS_SIZE]; @@ -77,7 +76,7 @@ static int manage_keys(DHT *dht, const char *keys_file_path) if (read_size != KEYS_SIZE) { fclose(keys_file); - return 0; + return false; } dht_set_self_public_key(dht, keys); @@ -89,21 +88,21 @@ static int manage_keys(DHT *dht, const char *keys_file_path) keys_file = fopen(keys_file_path, "wb"); - if (!keys_file) { - return 0; + if (keys_file == nullptr) { + return false; } const size_t write_size = fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file); if (write_size != KEYS_SIZE) { fclose(keys_file); - return 0; + return false; } } fclose(keys_file); - return 1; + return true; } // Prints public key @@ -164,7 +163,6 @@ static Cli_Status daemonize(LOG_BACKEND log_backend, char *pid_file_path) return CLI_STATUS_ERROR; } - // Change the current working directory if ((chdir("/")) < 0) { log_write(LOG_LEVEL_ERROR, "Couldn't change working directory to '/'. Exiting.\n"); @@ -222,7 +220,7 @@ int main(int argc, char *argv[]) bool run_in_foreground = false; // Choose backend for printing command line argument parsing output based on whether the daemon is being run from a terminal - LOG_BACKEND log_backend = isatty(STDOUT_FILENO) ? LOG_BACKEND_STDOUT : LOG_BACKEND_SYSLOG; + LOG_BACKEND log_backend = isatty(STDOUT_FILENO) != 0 ? LOG_BACKEND_STDOUT : LOG_BACKEND_SYSLOG; log_open(log_backend); switch (handle_command_line_arguments(argc, argv, &cfg_file_path, &log_backend, &run_in_foreground)) { @@ -283,7 +281,7 @@ int main(int argc, char *argv[]) free(pid_file_path); IP ip; - ip_init(&ip, enable_ipv6); + ip_init(&ip, enable_ipv6 != 0); Logger *logger = logger_new(); @@ -292,16 +290,16 @@ int main(int argc, char *argv[]) } const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM); - const Memory *mem = system_memory(); - const Random *rng = system_random(); - const Network *ns = system_network(); + const Memory *mem = os_memory(); + const Random *rng = os_random(); + const Network *ns = os_network(); Networking_Core *net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr); if (net == nullptr) { - if (enable_ipv6 && enable_ipv4_fallback) { + if (enable_ipv6 != 0 && enable_ipv4_fallback != 0) { log_write(LOG_LEVEL_WARNING, "Couldn't initialize IPv6 networking. Falling back to using IPv4.\n"); enable_ipv6 = 0; - ip_init(&ip, enable_ipv6); + ip_init(&ip, enable_ipv6 != 0); net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr); if (net == nullptr) { @@ -336,7 +334,7 @@ int main(int argc, char *argv[]) mono_time_update(mono_time); - DHT *const dht = new_dht(logger, mem, rng, ns, mono_time, net, true, enable_lan_discovery); + DHT *const dht = new_dht(logger, mem, rng, ns, mono_time, net, true, enable_lan_discovery != 0); if (dht == nullptr) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n"); @@ -396,7 +394,7 @@ int main(int argc, char *argv[]) Onion *onion = new_onion(logger, mem, mono_time, rng, dht); - if (!onion) { + if (onion == nullptr) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n"); kill_gca(group_announce); kill_announcements(announce); @@ -413,7 +411,7 @@ int main(int argc, char *argv[]) Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht); - if (!onion_a) { + if (onion_a == nullptr) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion Announce. Exiting.\n"); kill_gca(group_announce); kill_onion(onion); @@ -431,7 +429,7 @@ int main(int argc, char *argv[]) gca_onion_init(group_announce, onion_a); - if (enable_motd) { + if (enable_motd != 0) { if (bootstrap_set_callbacks(dht_get_net(dht), DAEMON_VERSION_NUMBER, (uint8_t *)motd, strlen(motd) + 1) == 0) { log_write(LOG_LEVEL_INFO, "Set MOTD successfully.\n"); free(motd); @@ -474,7 +472,7 @@ int main(int argc, char *argv[]) TCP_Server *tcp_server = nullptr; - if (enable_tcp_relay) { + if (enable_tcp_relay != 0) { if (tcp_relay_port_count == 0) { log_write(LOG_LEVEL_ERROR, "No TCP relay ports read. Exiting.\n"); kill_onion_announce(onion_a); @@ -490,7 +488,7 @@ int main(int argc, char *argv[]) return 1; } - tcp_server = new_tcp_server(logger, mem, rng, ns, enable_ipv6, + tcp_server = new_tcp_server(logger, mem, rng, ns, enable_ipv6 != 0, tcp_relay_port_count, tcp_relay_ports, dht_get_self_secret_key(dht), onion, forwarding); @@ -506,7 +504,7 @@ int main(int argc, char *argv[]) assert(rlim_suggested >= rlim_min); - if (!getrlimit(RLIMIT_NOFILE, &limit)) { + if (getrlimit(RLIMIT_NOFILE, &limit) == 0) { if (limit.rlim_cur < limit.rlim_max) { // Some systems have a hard limit of over 1000000 open file descriptors, so let's cap it at something reasonable // so that we don't set it to an unreasonably high number. @@ -515,7 +513,7 @@ int main(int argc, char *argv[]) } } - if (!getrlimit(RLIMIT_NOFILE, &limit) && limit.rlim_cur < rlim_min) { + if (getrlimit(RLIMIT_NOFILE, &limit) == 0 && limit.rlim_cur < rlim_min) { log_write(LOG_LEVEL_WARNING, "Current limit on the number of files this process can open (%ju) is rather low for the proper functioning of the TCP server. " "Consider raising the limit to at least %ju or the recommended %ju. " @@ -537,7 +535,7 @@ int main(int argc, char *argv[]) } } - if (bootstrap_from_config(cfg_file_path, dht, enable_ipv6)) { + if (bootstrap_from_config(cfg_file_path, dht, enable_ipv6 != 0)) { log_write(LOG_LEVEL_INFO, "List of bootstrap nodes read successfully.\n"); } else { log_write(LOG_LEVEL_ERROR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path); @@ -559,11 +557,11 @@ int main(int argc, char *argv[]) uint64_t last_lan_discovery = 0; const uint16_t net_htons_port = net_htons(start_port); - int waiting_for_dht_connection = 1; + bool waiting_for_dht_connection = true; Broadcast_Info *broadcast = nullptr; - if (enable_lan_discovery) { + if (enable_lan_discovery != 0) { broadcast = lan_discovery_init(ns); log_write(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n"); } @@ -578,25 +576,25 @@ int main(int argc, char *argv[]) // Prevent the signal handler from being called again before it returns sigfillset(&sa.sa_mask); - if (sigaction(SIGINT, &sa, nullptr)) { + if (sigaction(SIGINT, &sa, nullptr) != 0) { log_write(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGINT. Continuing without the signal handler set.\n"); } - if (sigaction(SIGTERM, &sa, nullptr)) { + if (sigaction(SIGTERM, &sa, nullptr) != 0) { log_write(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGTERM. Continuing without the signal handler set.\n"); } - while (!caught_signal) { + while (caught_signal == 0) { mono_time_update(mono_time); do_dht(dht); - if (enable_lan_discovery && mono_time_is_timeout(mono_time, last_lan_discovery, LAN_DISCOVERY_INTERVAL)) { + if (enable_lan_discovery != 0 && mono_time_is_timeout(mono_time, last_lan_discovery, LAN_DISCOVERY_INTERVAL)) { lan_discovery_send(dht_get_net(dht), broadcast, dht_get_self_public_key(dht), net_htons_port); last_lan_discovery = mono_time_get(mono_time); } - if (enable_tcp_relay) { + if (enable_tcp_relay != 0) { do_tcp_server(tcp_server, mono_time); } @@ -604,7 +602,7 @@ int main(int argc, char *argv[]) if (waiting_for_dht_connection && dht_isconnected(dht)) { log_write(LOG_LEVEL_INFO, "Connected to another bootstrap node successfully.\n"); - waiting_for_dht_connection = 0; + waiting_for_dht_connection = false; } sleep_milliseconds(30); diff --git a/other/bootstrap_daemon/websocket/websockify/go.mod b/other/bootstrap_daemon/websocket/websockify/go.mod index 782137e8..6db72397 100644 --- a/other/bootstrap_daemon/websocket/websockify/go.mod +++ b/other/bootstrap_daemon/websocket/websockify/go.mod @@ -2,6 +2,6 @@ module github.com/TokTok/c-toxcore/other/bootstrap_daemon/websocket/websockify go 1.17 -require ( - github.com/gorilla/websocket master -) +require github.com/gorilla/websocket v1.5.1 + +require golang.org/x/net v0.17.0 // indirect diff --git a/other/bootstrap_daemon/websocket/websockify/go.sum b/other/bootstrap_daemon/websocket/websockify/go.sum new file mode 100644 index 00000000..487893c9 --- /dev/null +++ b/other/bootstrap_daemon/websocket/websockify/go.sum @@ -0,0 +1,42 @@ +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +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= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +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= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/other/bootstrap_daemon/websocket/websockify/websockify.go b/other/bootstrap_daemon/websocket/websockify/websockify.go index 067ddb7a..898af4e3 100644 --- a/other/bootstrap_daemon/websocket/websockify/websockify.go +++ b/other/bootstrap_daemon/websocket/websockify/websockify.go @@ -18,6 +18,7 @@ package main import ( "encoding/hex" "flag" + "fmt" "log" "net" "net/http" @@ -104,7 +105,10 @@ func main() { if r.Header.Get("Upgrade") == "websocket" { serveWs(w, r) } else { - http.ServeFile(w, r, r.URL.Path[1:]) + w.Header().Set("Content-Type", "text/plain") + w.WriteHeader(http.StatusNotFound) + + fmt.Fprintf(w, "404 Not Found") } }) log.Fatal(http.ListenAndServe(*sourceAddr, nil)) diff --git a/other/bootstrap_node_packets.c b/other/bootstrap_node_packets.c index fb009218..c250b255 100644 --- a/other/bootstrap_node_packets.c +++ b/other/bootstrap_node_packets.c @@ -35,7 +35,7 @@ static int handle_info_request(void *object, const IP_Port *source, const uint8_ uint8_t data[1 + sizeof(bootstrap_version) + MAX_MOTD_LENGTH]; data[0] = BOOTSTRAP_INFO_PACKET_ID; memcpy(data + 1, &bootstrap_version, sizeof(bootstrap_version)); - uint16_t len = 1 + sizeof(bootstrap_version) + bootstrap_motd_length; + const uint16_t len = 1 + sizeof(bootstrap_version) + bootstrap_motd_length; memcpy(data + 1 + sizeof(bootstrap_version), bootstrap_motd, bootstrap_motd_length); if (sendpacket(nc, source, data, len) == len) { diff --git a/other/docker/autotools/Dockerfile b/other/docker/autotools/autotools.Dockerfile similarity index 72% rename from other/docker/autotools/Dockerfile rename to other/docker/autotools/autotools.Dockerfile index fc85f505..bbe7357f 100644 --- a/other/docker/autotools/Dockerfile +++ b/other/docker/autotools/autotools.Dockerfile @@ -1,5 +1,6 @@ ################################################ # autotools-linux +FROM toxchat/c-toxcore:sources AS sources FROM ubuntu:22.04 RUN apt-get update && \ @@ -24,7 +25,12 @@ USER builder WORKDIR /home/builder -# Copy the sources and run the build. +# Copy autotools-specific build scripts not present in the sources image. +# These change less frequently than the sources, thus are copied first. COPY --chown=builder:builder . /home/builder/c-toxcore/ + +# Copy the sources and run the build. +COPY --chown=builder:builder --from=sources /src/ /home/builder/c-toxcore/ + WORKDIR /home/builder/c-toxcore RUN CC=gcc .github/scripts/autotools-linux diff --git a/other/docker/autotools/autotools.Dockerfile.dockerignore b/other/docker/autotools/autotools.Dockerfile.dockerignore new file mode 100644 index 00000000..ddd22a5f --- /dev/null +++ b/other/docker/autotools/autotools.Dockerfile.dockerignore @@ -0,0 +1,12 @@ +**/* +!.github/scripts/autotools-linux +!m4/* +!configure.ac +!*.pc.in +!*.spec.in +!**/Makefile.am +!**/Makefile.inc +!docs/updates/* +!other/DHTnodes +!other/astyle/* +!other/tox.png diff --git a/other/docker/autotools/run b/other/docker/autotools/run index aadb1440..300465b0 100755 --- a/other/docker/autotools/run +++ b/other/docker/autotools/run @@ -2,4 +2,5 @@ set -eux BUILD=autotools -docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/Dockerfile" . +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/clang-tidy/Dockerfile b/other/docker/clang-tidy/clang-tidy.Dockerfile similarity index 62% rename from other/docker/clang-tidy/Dockerfile rename to other/docker/clang-tidy/clang-tidy.Dockerfile index eaf23f98..986bb9c4 100644 --- a/other/docker/clang-tidy/Dockerfile +++ b/other/docker/clang-tidy/clang-tidy.Dockerfile @@ -1,3 +1,4 @@ +FROM toxchat/c-toxcore:sources AS sources FROM alpine:3.19.0 RUN ["apk", "add", "--no-cache", \ @@ -16,6 +17,8 @@ RUN ["apk", "add", "--no-cache", \ ENV CC=clang CXX=clang++ -COPY . /c-toxcore/ +COPY --from=sources /src/ /c-toxcore/ +COPY other/analysis/run-clang-tidy other/analysis/variants.sh /c-toxcore/other/analysis/ +COPY .clang-tidy /c-toxcore/ WORKDIR /c-toxcore RUN other/analysis/run-clang-tidy diff --git a/other/docker/clang-tidy/run b/other/docker/clang-tidy/run index 62036edf..ab830de0 100755 --- a/other/docker/clang-tidy/run +++ b/other/docker/clang-tidy/run @@ -2,4 +2,5 @@ set -eux BUILD=clang-tidy -docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/Dockerfile" . +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/compcert/.gitignore b/other/docker/compcert/.gitignore new file mode 100644 index 00000000..25264231 --- /dev/null +++ b/other/docker/compcert/.gitignore @@ -0,0 +1 @@ +!/Makefile diff --git a/other/docker/compcert/Dockerfile b/other/docker/compcert/Dockerfile deleted file mode 100644 index bcc61387..00000000 --- a/other/docker/compcert/Dockerfile +++ /dev/null @@ -1,30 +0,0 @@ -FROM toxchat/compcert:latest - -WORKDIR /work -COPY auto_tests/ /work/auto_tests/ -COPY testing/ /work/testing/ -COPY toxav/ /work/toxav/ -COPY toxcore/ /work/toxcore/ -COPY toxencryptsave/ /work/toxencryptsave/ -COPY third_party/ /work/third_party/ - -SHELL ["/bin/bash", "-o", "pipefail", "-c"] - -RUN ccomp \ - -o send_message_test \ - -Wall -Werror \ - -Wno-c11-extensions \ - -Wno-unknown-pragmas \ - -Wno-unused-variable \ - -fstruct-passing -fno-unprototyped -g \ - auto_tests/auto_test_support.c \ - auto_tests/send_message_test.c \ - testing/misc_tools.c \ - toxav/*.c \ - toxcore/*.c \ - toxcore/*/*.c \ - toxencryptsave/*.c \ - third_party/cmp/*.c \ - -D__COMPCERT__ -DDISABLE_VLA -Dinline= \ - -lpthread $(pkg-config --cflags --libs libsodium opus vpx) \ - && ./send_message_test | grep 'tox clients connected' diff --git a/other/docker/compcert/Makefile b/other/docker/compcert/Makefile new file mode 100644 index 00000000..9aa84f18 --- /dev/null +++ b/other/docker/compcert/Makefile @@ -0,0 +1,39 @@ +CC := ccomp +CFLAGS := -Wall \ + -Wno-c11-extensions \ + -Wno-unknown-pragmas \ + -Wno-unused-variable \ + -fstruct-passing -fno-unprototyped -g \ + -Ilibsodium/src/libsodium/include \ + $(shell pkg-config --cflags opus vpx) +LDFLAGS := -lpthread $(shell pkg-config --libs opus vpx) + +libsodium_SOURCES := $(shell find libsodium/src/libsodium -name "*.c") +libsodium_OBJECTS := $(libsodium_SOURCES:.c=.o) + +$(libsodium_OBJECTS): CFLAGS += \ + -DDEV_MODE \ + -DCONFIGURED \ + -D_DEFAULT_SOURCE \ + -Ilibsodium/builds/msvc \ + -Ilibsodium/src/libsodium/include/sodium + +toxcore_SOURCES := $(wildcard \ + auto_tests/auto_test_support.c \ + auto_tests/send_message_test.c \ + testing/misc_tools.c \ + toxav/*.c \ + toxcore/*.c \ + toxcore/*/*.c \ + toxencryptsave/*.c \ + third_party/cmp/*.c) +toxcore_OBJECTS := $(toxcore_SOURCES:.c=.o) +$(toxcore_OBJECTS): CFLAGS += \ + -Werror \ + -D__COMPCERT__ \ + -DDISABLE_VLA \ + -DMIN_LOGGER_LEVEL=LOGGER_LEVEL_TRACE \ + -Dinline= \ + +send_message_test: $(libsodium_OBJECTS) $(toxcore_OBJECTS) + $(CC) -o $@ $+ $(LDFLAGS) diff --git a/other/docker/compcert/compcert.Dockerfile b/other/docker/compcert/compcert.Dockerfile new file mode 100644 index 00000000..567ea786 --- /dev/null +++ b/other/docker/compcert/compcert.Dockerfile @@ -0,0 +1,19 @@ +FROM toxchat/c-toxcore:sources AS sources +FROM toxchat/compcert:latest + +RUN apt-get update && \ + DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \ + gdb \ + make \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /work +COPY --from=sources /src/ /work/ + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN git clone --depth=1 https://github.com/jedisct1/libsodium /work/libsodium +COPY other/docker/compcert/Makefile /work/ +RUN make "-j$(nproc)" +RUN ./send_message_test | grep 'tox clients connected' diff --git a/other/docker/compcert/run b/other/docker/compcert/run index 8b03c84c..885f811a 100755 --- a/other/docker/compcert/run +++ b/other/docker/compcert/run @@ -2,4 +2,5 @@ set -eux BUILD=compcert -docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/Dockerfile" . +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/coverage/Dockerfile b/other/docker/coverage/coverage.Dockerfile similarity index 97% rename from other/docker/coverage/Dockerfile rename to other/docker/coverage/coverage.Dockerfile index 8a289869..8d6649af 100644 --- a/other/docker/coverage/Dockerfile +++ b/other/docker/coverage/coverage.Dockerfile @@ -1,4 +1,4 @@ -FROM toxchat/c-toxcore:sources AS src +FROM toxchat/c-toxcore:sources AS sources FROM ubuntu:20.04 AS build SHELL ["/bin/bash", "-o", "pipefail", "-c"] @@ -41,7 +41,7 @@ ENV CC=clang-17 \ PYTHONUNBUFFERED=1 \ PATH=$PATH:/usr/lib/go-1.18/bin -COPY --from=src /src/ /work/ +COPY --from=sources /src/ /work/ WORKDIR /work RUN git clone --depth=1 https://github.com/TokTok/toktok-fuzzer /work/testing/fuzzing/toktok-fuzzer diff --git a/other/docker/coverage/Dockerfile.nginx b/other/docker/coverage/nginx.Dockerfile similarity index 100% rename from other/docker/coverage/Dockerfile.nginx rename to other/docker/coverage/nginx.Dockerfile diff --git a/other/docker/coverage/run b/other/docker/coverage/run index aea7603c..e4f51339 100755 --- a/other/docker/coverage/run +++ b/other/docker/coverage/run @@ -4,6 +4,8 @@ set -eux read -a ci_env <<<"$(bash <(curl -s https://codecov.io/env))" -docker build -t toxchat/c-toxcore:sources -f other/docker/sources/Dockerfile . -docker build -t toxchat/c-toxcore:coverage -f other/docker/coverage/Dockerfile . +BUILD=coverage +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . + docker run "${ci_env[@]}" -e CI=true --name toxcore-coverage --rm -t toxchat/c-toxcore:coverage /usr/local/bin/codecov diff --git a/other/docker/coverage/serve b/other/docker/coverage/serve index 94a09d15..e5da11d5 100755 --- a/other/docker/coverage/serve +++ b/other/docker/coverage/serve @@ -2,7 +2,9 @@ set -eux -docker build -t toxchat/c-toxcore:sources -f other/docker/sources/Dockerfile . -docker build -t toxchat/c-toxcore:coverage -f other/docker/coverage/Dockerfile . -docker build -t toxchat/c-toxcore:coverage-nginx -f other/docker/coverage/Dockerfile.nginx other/docker/coverage +BUILD=coverage +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . + +docker build -t toxchat/c-toxcore:coverage-nginx -f other/docker/coverage/nginx.Dockerfile other/docker/coverage docker run --name toxcore-coverage --rm -it -p "28192:80" toxchat/c-toxcore:coverage-nginx diff --git a/other/docker/cppcheck/Dockerfile b/other/docker/cppcheck/Dockerfile deleted file mode 100644 index 34b516fb..00000000 --- a/other/docker/cppcheck/Dockerfile +++ /dev/null @@ -1,30 +0,0 @@ -FROM alpine:3.19.0 - -RUN ["apk", "add", "--no-cache", \ - "bash", \ - "cppcheck", \ - "findutils", \ - "libconfig-dev", \ - "libsodium-dev", \ - "libvpx-dev", \ - "linux-headers", \ - "make", \ - "opus-dev"] - -COPY other/bootstrap_daemon/ /src/workspace/c-toxcore/other/bootstrap_daemon/ -COPY other/bootstrap_node_packets.* /src/workspace/c-toxcore/other/ -COPY other/fun/ /src/workspace/c-toxcore/other/fun/ -COPY auto_tests/check_compat.h /src/workspace/c-toxcore/auto_tests/ -COPY testing/ /src/workspace/c-toxcore/testing/ -COPY toxav/ /src/workspace/c-toxcore/toxav/ -COPY toxcore/ /src/workspace/c-toxcore/toxcore/ -COPY toxencryptsave/ /src/workspace/c-toxcore/toxencryptsave/ -COPY third_party/cmp/cmp.h /src/workspace/c-toxcore/third_party/cmp/ -COPY other/analysis/run-cppcheck \ - other/analysis/gen-file.sh \ - other/analysis/variants.sh \ - /src/workspace/c-toxcore/other/analysis/ -COPY other/docker/cppcheck/toxcore.cfg \ - /src/workspace/c-toxcore/other/docker/cppcheck/ -WORKDIR /src/workspace/c-toxcore -RUN ["other/analysis/run-cppcheck"] diff --git a/other/docker/cppcheck/cppcheck.Dockerfile b/other/docker/cppcheck/cppcheck.Dockerfile new file mode 100644 index 00000000..7bc800c0 --- /dev/null +++ b/other/docker/cppcheck/cppcheck.Dockerfile @@ -0,0 +1,23 @@ +FROM toxchat/c-toxcore:sources AS sources +FROM alpine:3.19.0 + +RUN ["apk", "add", "--no-cache", \ + "bash", \ + "cppcheck", \ + "findutils", \ + "libconfig-dev", \ + "libsodium-dev", \ + "libvpx-dev", \ + "linux-headers", \ + "make", \ + "opus-dev"] + +COPY --from=sources /src/ /src/workspace/c-toxcore/ +COPY other/analysis/run-cppcheck \ + other/analysis/gen-file.sh \ + other/analysis/variants.sh \ + /src/workspace/c-toxcore/other/analysis/ +COPY other/docker/cppcheck/toxcore.cfg \ + /src/workspace/c-toxcore/other/docker/cppcheck/ +WORKDIR /src/workspace/c-toxcore +RUN ["other/analysis/run-cppcheck"] diff --git a/other/docker/cppcheck/run b/other/docker/cppcheck/run index 8e437f4c..4cc18bac 100755 --- a/other/docker/cppcheck/run +++ b/other/docker/cppcheck/run @@ -2,4 +2,5 @@ set -eux BUILD=cppcheck -docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/Dockerfile" . +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/doxygen/Dockerfile b/other/docker/doxygen/Dockerfile deleted file mode 100644 index e10c645d..00000000 --- a/other/docker/doxygen/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM alpine:latest AS build - -ENV LANG=en_US.UTF-8 \ - LANGUAGE=en_US.UTF-8 \ - LC_CTYPE=en_US.UTF-8 \ - LC_ALL=en_US.UTF-8 - -RUN apk add --no-cache doxygen git graphviz texlive \ - && git clone --depth=1 https://github.com/jothepro/doxygen-awesome-css.git /work/doxygen-awesome-css -WORKDIR /work -COPY . /work/ -RUN cat docs/Doxyfile > Doxyfile \ - && echo "WARN_AS_ERROR = YES" >> Doxyfile \ - && sed -i -e 's/^non_null([^)]*) *//;s/^nullable([^)]*) *//' $(find . -name "*.[ch]") \ - && doxygen Doxyfile - -FROM nginx:alpine -COPY --from=build /work/_docs/html/ /usr/share/nginx/html/ diff --git a/other/docker/doxygen/dockerignore b/other/docker/doxygen/dockerignore new file mode 100644 index 00000000..e3dd207f --- /dev/null +++ b/other/docker/doxygen/dockerignore @@ -0,0 +1,2 @@ +# ===== custom ===== +!docs/Doxyfile diff --git a/other/docker/doxygen/doxygen.Dockerfile b/other/docker/doxygen/doxygen.Dockerfile new file mode 100644 index 00000000..44732be0 --- /dev/null +++ b/other/docker/doxygen/doxygen.Dockerfile @@ -0,0 +1,20 @@ +FROM toxchat/doxygen:latest AS build + +RUN ["apk", "add", "--no-cache", \ + "gtest-dev", \ + "libconfig-dev", \ + "libsodium-dev", \ + "libvpx-dev", \ + "opus-dev"] + +RUN git clone --depth=1 https://github.com/jothepro/doxygen-awesome-css.git /work/c-toxcore/doxygen-awesome-css + +WORKDIR /work/c-toxcore +COPY . /work/c-toxcore/ +RUN cmake . -B_build -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ + && echo "WARN_AS_ERROR = YES" >> Doxyfile \ + && sed -i -e 's/^non_null([^)]*) *//;s/^nullable([^)]*) *//' $(find . -name "*.[ch]") \ + && doxygen docs/Doxyfile + +FROM nginx:alpine +COPY --from=build /work/c-toxcore/_docs/html/ /usr/share/nginx/html/ diff --git a/other/docker/doxygen/doxygen.Dockerfile.dockerignore b/other/docker/doxygen/doxygen.Dockerfile.dockerignore new file mode 100644 index 00000000..532c4e44 --- /dev/null +++ b/other/docker/doxygen/doxygen.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 +# ===== custom ===== +!docs/Doxyfile diff --git a/other/docker/doxygen/run b/other/docker/doxygen/run index c702ba5f..2c038325 100755 --- a/other/docker/doxygen/run +++ b/other/docker/doxygen/run @@ -1,6 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash -set -eux - -docker build -t toxchat/c-toxcore:docs -f other/docker/doxygen/Dockerfile . -docker run --name toxcore-docs --rm -it -p "28192:80" toxchat/c-toxcore:docs +. "$(cd "$(dirname "${BASH_SOURCE[0]}")/../sources" && pwd)/run.sh" +docker run --name toxcore-doxygen --rm -it -p "28192:80" "toxchat/c-toxcore:$BUILD" diff --git a/other/docker/freebsd/Dockerfile b/other/docker/freebsd/freebsd.Dockerfile similarity index 100% rename from other/docker/freebsd/Dockerfile rename to other/docker/freebsd/freebsd.Dockerfile diff --git a/other/docker/freebsd/run b/other/docker/freebsd/run index f4448a46..d844ec4f 100755 --- a/other/docker/freebsd/run +++ b/other/docker/freebsd/run @@ -2,4 +2,4 @@ set -eux BUILD=freebsd -docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/Dockerfile" . +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/goblint/BUILD.bazel b/other/docker/goblint/BUILD.bazel new file mode 100644 index 00000000..afd687a3 --- /dev/null +++ b/other/docker/goblint/BUILD.bazel @@ -0,0 +1,8 @@ +load("@rules_cc//cc:defs.bzl", "cc_library") + +cc_library( + name = "sodium", + testonly = True, + srcs = ["sodium.c"], + deps = ["@libsodium"], +) diff --git a/other/docker/goblint/analysis.json b/other/docker/goblint/analysis.json new file mode 100644 index 00000000..a682b89b --- /dev/null +++ b/other/docker/goblint/analysis.json @@ -0,0 +1,43 @@ +{ + "ana": { + "activated": [ + "base","mallocWrapper","escape","mutex","mutexEvents","access","assert","expRelation" + ], + "arrayoob": true, + "wp": true, + "apron": { + "strengthening": true + }, + "base": { + "structs" : { + "domain" : "combined-sk" + }, + "arrays": { + "domain": "partitioned" + } + }, + "malloc": { + "wrappers": [ + "mem_balloc", + "mem_alloc", + "mem_valloc", + "mem_vrealloc" + ] + } + }, + "warn": { + "behavior": false, + "call": false, + "integer": true, + "float": false, + "race": false, + "deadcode": false, + "unsound": false, + "imprecise": false, + "success": false, + "unknown": false + }, + "exp": { + "earlyglobs": true + } +} diff --git a/other/docker/goblint/goblint.Dockerfile b/other/docker/goblint/goblint.Dockerfile new file mode 100644 index 00000000..eb627510 --- /dev/null +++ b/other/docker/goblint/goblint.Dockerfile @@ -0,0 +1,21 @@ +FROM toxchat/c-toxcore:sources AS sources +FROM ghcr.io/goblint/analyzer:latest + +RUN apt-get update && \ + DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \ + libsodium-dev \ + tcc \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /work +COPY --from=sources /src/ /work/ + +COPY other/make_single_file /work/other/ + +RUN other/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 + +COPY other/docker/goblint/analysis.json /work/other/docker/goblint/ +RUN /opt/goblint/analyzer/bin/goblint --conf /work/other/docker/goblint/analysis.json analysis.c diff --git a/other/docker/goblint/run b/other/docker/goblint/run new file mode 100755 index 00000000..f2bbceea --- /dev/null +++ b/other/docker/goblint/run @@ -0,0 +1,6 @@ +#!/bin/sh + +set -eux +BUILD=goblint +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/goblint/sodium.c b/other/docker/goblint/sodium.c new file mode 100644 index 00000000..eb70c274 --- /dev/null +++ b/other/docker/goblint/sodium.c @@ -0,0 +1,112 @@ +#include + +#include + +int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, const unsigned char *seed) +{ + memset(pk, 0, 32); + memset(sk, 0, 32); + return 0; +} +int crypto_sign_ed25519_pk_to_curve25519(unsigned char *curve25519_pk, + const unsigned char *ed25519_pk) +{ + memset(curve25519_pk, 0, 32); + return 0; +} +int crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk, + const unsigned char *ed25519_sk) +{ + memset(curve25519_sk, 0, 32); + return 0; +} +void sodium_memzero(void *const pnt, const size_t len) +{ + memset(pnt, 0, len); +} +int sodium_mlock(void *const addr, const size_t len) +{ + return 0; +} +int sodium_munlock(void *const addr, const size_t len) +{ + return 0; +} +int crypto_verify_32(const unsigned char *x, const unsigned char *y) +{ + return memcmp(x, y, 32); +} +int crypto_verify_64(const unsigned char *x, const unsigned char *y) +{ + return memcmp(x, y, 64); +} +int crypto_sign_detached(unsigned char *sig, unsigned long long *siglen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) +{ + return 0; +} +int crypto_sign_verify_detached(const unsigned char *sig, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk) +{ + return 0; +} +int crypto_box_beforenm(unsigned char *k, const unsigned char *pk, + const unsigned char *sk) +{ + memset(k, 0, 32); + return 0; +} +int crypto_box_afternm(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + memset(c, 0, 32); + return 0; +} +int crypto_box_open_afternm(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + return 0; +} +int crypto_scalarmult_curve25519_base(unsigned char *q, + const unsigned char *n) +{ + memset(q, 0, 32); + return 0; +} +int crypto_auth(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + return 0; +} +int crypto_auth_verify(const unsigned char *h, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + return 0; +} +int crypto_hash_sha256(unsigned char *out, const unsigned char *in, + unsigned long long inlen) +{ + return 0; +} +int crypto_hash_sha512(unsigned char *out, const unsigned char *in, + unsigned long long inlen) +{ + return 0; +} +void randombytes(unsigned char *const buf, const unsigned long long buf_len) +{ + memset(buf, 0, buf_len); +} +uint32_t randombytes_uniform(const uint32_t upper_bound) +{ + return upper_bound; +} +int sodium_init(void) +{ + return 0; +} diff --git a/other/docker/infer/Dockerfile b/other/docker/infer/infer.Dockerfile similarity index 89% rename from other/docker/infer/Dockerfile rename to other/docker/infer/infer.Dockerfile index b4f8ebb2..f7f4547b 100644 --- a/other/docker/infer/Dockerfile +++ b/other/docker/infer/infer.Dockerfile @@ -1,9 +1,7 @@ +FROM toxchat/c-toxcore:sources AS sources FROM toxchat/infer:latest -COPY toxav/ /work/c-toxcore/toxav/ -COPY toxcore/ /work/c-toxcore/toxcore/ -COPY toxencryptsave/ /work/c-toxcore/toxencryptsave/ -COPY third_party/ /work/c-toxcore/third_party/ +COPY --from=sources /src/ /work/c-toxcore/ RUN infer capture -- clang++ -fsyntax-only \ $(pkg-config --cflags libconfig libsodium opus vpx) \ /work/c-toxcore/toxav/*.c \ diff --git a/other/docker/infer/run b/other/docker/infer/run index ab1c021c..f605d140 100755 --- a/other/docker/infer/run +++ b/other/docker/infer/run @@ -2,4 +2,5 @@ set -eux BUILD=infer -docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/Dockerfile" . +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/misra/Makefile b/other/docker/misra/Makefile index bb394fb5..9f6e32a3 100644 --- a/other/docker/misra/Makefile +++ b/other/docker/misra/Makefile @@ -126,11 +126,6 @@ SUPPRESSIONS += 19.2 # # Reason: We believe it should be used when #define is used in block scope. SUPPRESSIONS += 20.5 -# The # and ## preprocessor operators should not be used. -# -# TODO(iphydf): Remove suppression when VLAs are gone. This is only used in -# the SIZEOF_VLA macro. -SUPPRESSIONS += 20.10 # #define and #undef shall not be used on a reserved identifier or reserved macro name. # # Reason: Needed for feature test macros like _DEFAULT_SOURCE. @@ -160,7 +155,12 @@ SUPPRESSIONS += 21.10 CPPFLAGS := -DCMP_NO_FLOAT=1 -DMIN_LOGGER_LEVEL=LOGGER_LEVEL_TRACE -SOURCES := $(shell find /src/workspace/c-toxcore -name "*.c") +FIND_FLAGS := -name "*.c" \ + -and -not -wholename "*/auto_tests/*" \ + -and -not -wholename "*/other/*" \ + -and -not -wholename "*/super_donators/*" \ + -and -not -wholename "*/third_party/*" +SOURCES := $(shell find /src/workspace/c-toxcore $(FIND_FLAGS)) analyse: $(DUMPS:.dump=.diag) cppcheck --error-exitcode=1 -j8 --addon=misra --suppress=doubleFree $(patsubst %,--suppress=misra-c2012-%,$(SUPPRESSIONS)) $(CPPFLAGS) $(SOURCES) diff --git a/other/docker/misra/Dockerfile b/other/docker/misra/misra.Dockerfile similarity index 60% rename from other/docker/misra/Dockerfile rename to other/docker/misra/misra.Dockerfile index d005b4c9..aa99a530 100644 --- a/other/docker/misra/Dockerfile +++ b/other/docker/misra/misra.Dockerfile @@ -1,3 +1,4 @@ +FROM toxchat/c-toxcore:sources AS sources FROM ubuntu:20.04 RUN apt-get update && \ @@ -12,10 +13,7 @@ RUN apt-get update && \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* -COPY toxav/ /src/workspace/c-toxcore/toxav/ -COPY toxcore/ /src/workspace/c-toxcore/toxcore/ -COPY toxencryptsave/ /src/workspace/c-toxcore/toxencryptsave/ -COPY third_party/cmp/cmp.h /src/workspace/c-toxcore/third_party/cmp/cmp.h +COPY --from=sources /src/ /src/workspace/c-toxcore/ COPY other/docker/misra/Makefile /src/workspace/ WORKDIR /src/workspace RUN ["make"] diff --git a/other/docker/misra/run b/other/docker/misra/run index 2f96bb4b..a2692a37 100755 --- a/other/docker/misra/run +++ b/other/docker/misra/run @@ -2,4 +2,5 @@ set -eux BUILD=misra -docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/Dockerfile" . +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/modules/check b/other/docker/modules/check new file mode 100755 index 00000000..0249efe4 --- /dev/null +++ b/other/docker/modules/check @@ -0,0 +1,225 @@ +#!/usr/bin/env python3 +import glob +import os +import subprocess +import sys +from dataclasses import dataclass +from typing import Iterable +from typing import Optional + +LIBS = {} +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/errno.h" + textual header "/usr/include/fortify/stdio.h" + textual header "/usr/include/fortify/string.h" + textual header "/usr/include/fortify/unistd.h" + textual header "/usr/include/limits.h" + textual header "/usr/include/stdarg.h" + textual header "/usr/include/stdbool.h" + textual header "/usr/include/stddef.h" + textual header "/usr/include/stdint.h" + textual header "/usr/include/sys/time.h" + textual header "/usr/include/sys/types.h" + textual header "/usr/include/time.h" +} +module "//c-toxcore/third_party:cmp" { + header "third_party/cmp/cmp.h" + use std +} +module "//c-toxcore/toxencryptsave:defines" { + header "toxencryptsave/defines.h" +} +module "@com_google_googletest//:gtest" { + textual header "/usr/include/gmock/gmock.h" + textual header "/usr/include/gtest/gtest.h" + use std +} +module "@libsodium" { + textual header "/usr/include/sodium.h" +} +module "@pthread" { + textual header "/usr/include/pthread.h" +} +module "@psocket" { + textual header "/usr/include/arpa/inet.h" + textual header "/usr/include/fcntl.h" + textual header "/usr/include/fortify/sys/socket.h" + textual header "/usr/include/linux/if.h" + textual header "/usr/include/netdb.h" + textual header "/usr/include/netinet/in.h" + textual header "/usr/include/sys/epoll.h" + textual header "/usr/include/sys/ioctl.h" +} +""" + + +@dataclass +class Context: + pkg: str + pkg_prefix: str + + def bzl_load(self, bzl: str, *syms: str) -> None: + pass + + def bzl_exports_files( + self, + srcs: list[str], + visibility: Optional[list[str]] = None, + ) -> None: + pass + + def bzl_cc_library( + self, + name: str, + srcs: Iterable[str] = tuple(), + hdrs: Iterable[str] = tuple(), + deps: Iterable[str] = tuple(), + visibility: Iterable[str] = tuple(), + testonly: bool = False, + copts: Iterable[str] = tuple(), + ) -> None: + LIBS[name] = { + "srcs": + srcs, + "deps": [ + f"{self.pkg_prefix}{dep}" if dep[0] == ":" else dep + for dep in deps + ], + "hdrs": + hdrs, + } + + def bzl_cc_test( + self, + name: str, + srcs: Iterable[str] = tuple(), + hdrs: Iterable[str] = tuple(), + deps: Iterable[str] = tuple(), + **kwargs: list[str], + ) -> None: + LIBS[name] = { + "srcs": + srcs, + "deps": [ + f"{self.pkg_prefix}{dep}" if dep[0] == ":" else dep + for dep in deps + ], + "hdrs": + hdrs, + } + + def bzl_cc_fuzz_test(self, name: str, **kwargs: list[str]) -> None: + pass + + def bzl_select(self, selector: dict[str, list[str]]) -> list[str]: + return selector["//tools/config:linux"] + + def bzl_glob(self, include: list[str]) -> list[str]: + return [ + f[len(self.pkg) + 1:] for p in include + for f in glob.glob(os.path.join(self.pkg, p)) + ] + + def bzl_alias(self, name: str, actual: str, visibility: list[str]) -> None: + pass + + def bzl_sh_library(self, name: str, **kwargs: list[str]) -> None: + pass + + +def main() -> None: + srcs: list[str] = [] + for pkg in ("toxcore", ): + # TODO(iphydf): Why does this break everything? + # ctx = Context(pkg, "//c-toxcore/{pkg}") + ctx = Context(pkg, "") + with open(os.path.join(pkg, "BUILD.bazel"), "r") as fh: + exec( + fh.read(), + { + "load": ctx.bzl_load, + "exports_files": ctx.bzl_exports_files, + "cc_library": ctx.bzl_cc_library, + "cc_test": ctx.bzl_cc_test, + "cc_fuzz_test": ctx.bzl_cc_fuzz_test, + "select": ctx.bzl_select, + "glob": ctx.bzl_glob, + "alias": ctx.bzl_alias, + "sh_library": ctx.bzl_sh_library, + }, + ) + + with open("module.modulemap", "w") as fh: + fh.write(STD_MODULE) + for name, lib in LIBS.items(): + fh.write(f'module "{ctx.pkg_prefix}:{name}"' + " {\n") + for hdr in lib["hdrs"]: + fh.write(f' header "{pkg}/{hdr}"\n') + fh.write(f" use std\n") + for dep in lib.get("deps", []): + fh.write(f' use "{dep}"\n') + fh.write("}\n") + + for name, lib in LIBS.items(): + for src in lib.get("srcs", []): + MODS[os.path.join(pkg, src)] = name + srcs.extend( + os.path.join(pkg, src) # just within a package for now + for lib in LIBS.values() for src in lib.get("srcs", [])) + # subprocess.run(["cat", "module.modulemap"], check=True) + for src in sorted( + set(srcs) - set([ + # TODO(iphydf): Figure out what's wrong here. + "toxcore/crypto_core_test.cc", + "toxcore/group_announce_test.cc", + "toxcore/group_moderation_test.cc", + "toxcore/mono_time_test.cc", + "toxcore/network_test.cc", + "toxcore/ping_array_test.cc", + "toxcore/util_test.cc", + ])): + print(f"Validating {src}", file=sys.stderr) + subprocess.run( + [ + "clang", + "-fsyntax-only", + "-xc++", + "-Wall", + "-Werror", + "-Wno-missing-braces", + "-DTCP_SERVER_USE_EPOLL", + "-std=c++23", + "-fdiagnostics-color=always", + "-fmodules", + "-fmodules-strict-decluse", + "-fmodule-map-file=module.modulemap", + f"-fmodule-name={ctx.pkg_prefix}:{MODS[src]}", + src, + ], + check=True, + ) + + +if __name__ == "__main__": + main() diff --git a/other/docker/modules/modules.Dockerfile b/other/docker/modules/modules.Dockerfile new file mode 100644 index 00000000..5fb03a25 --- /dev/null +++ b/other/docker/modules/modules.Dockerfile @@ -0,0 +1,21 @@ +FROM toxchat/c-toxcore:sources AS sources +FROM alpine:3.19.0 + +RUN ["apk", "add", "--no-cache", \ + "bash", \ + "clang", \ + "gtest-dev", \ + "libconfig-dev", \ + "libsodium-dev", \ + "libvpx-dev", \ + "linux-headers", \ + "opus-dev", \ + "pkgconfig", \ + "python3"] + +WORKDIR /work +COPY --from=sources /src/ /work/ + +COPY toxcore/BUILD.bazel /work/toxcore/ +COPY other/docker/modules/check /work/other/docker/modules/ +RUN ["other/docker/modules/check"] diff --git a/other/docker/modules/run b/other/docker/modules/run new file mode 100755 index 00000000..cfe53a1e --- /dev/null +++ b/other/docker/modules/run @@ -0,0 +1,6 @@ +#!/bin/sh + +set -eux +BUILD=modules +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/pkgsrc/pkgsrc.Dockerfile b/other/docker/pkgsrc/pkgsrc.Dockerfile new file mode 100644 index 00000000..10fb6a6b --- /dev/null +++ b/other/docker/pkgsrc/pkgsrc.Dockerfile @@ -0,0 +1,10 @@ +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"] + +WORKDIR /work/pkgsrc/chat/toxcore +RUN ["bmake", "clean"] +RUN ["bmake", "DISTFILES=c-toxcore.tar.gz", "DISTDIR=/work", "NO_CHECKSUM=yes"] +RUN ["bmake", "install"] diff --git a/other/docker/pkgsrc/pkgsrc.Dockerfile.dockerignore b/other/docker/pkgsrc/pkgsrc.Dockerfile.dockerignore new file mode 100644 index 00000000..3a3643cb --- /dev/null +++ b/other/docker/pkgsrc/pkgsrc.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/docker/pkgsrc/run b/other/docker/pkgsrc/run new file mode 100755 index 00000000..5a0f34bc --- /dev/null +++ b/other/docker/pkgsrc/run @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +. "$(cd "$(dirname "${BASH_SOURCE[0]}")/../sources" && pwd)/run.sh" diff --git a/other/docker/rpm/rpm.Dockerfile b/other/docker/rpm/rpm.Dockerfile new file mode 100644 index 00000000..129a6961 --- /dev/null +++ b/other/docker/rpm/rpm.Dockerfile @@ -0,0 +1,47 @@ +FROM toxchat/c-toxcore:sources AS sources +FROM fedora:39 + +RUN ["dnf", "install", "-y", \ + "cmake", \ + "g++", \ + "gcc", \ + "git", \ + "libconfig-devel", \ + "libsodium-devel", \ + "libvpx-devel", \ + "make", \ + "opus-devel", \ + "rpmdevtools", \ + "rpmlint", \ + "systemd-units"] + +ARG PROJECT_VERSION=master +ARG PROJECT_COMMIT_ID=master +ARG PROJECT_COMMIT_ID_SHORT=master + +COPY --from=sources /src/ /work/c-toxcore-${PROJECT_COMMIT_ID} +WORKDIR /work/c-toxcore-${PROJECT_COMMIT_ID}/other/rpm + +RUN make toxcore.spec \ + PROJECT_VERSION="$PROJECT_VERSION" \ + PROJECT_COMMIT_ID="$PROJECT_COMMIT_ID" \ + PROJECT_COMMIT_ID_SHORT="$PROJECT_COMMIT_ID_SHORT" \ + PROJECT_GIT_ROOT="/work/c-toxcore-$PROJECT_COMMIT_ID_SHORT" + +WORKDIR /work +RUN tar zcf "c-toxcore-${PROJECT_COMMIT_ID_SHORT}.tar.gz" "c-toxcore-${PROJECT_COMMIT_ID}" \ + && mv "c-toxcore-${PROJECT_COMMIT_ID_SHORT}.tar.gz" "c-toxcore-${PROJECT_COMMIT_ID}/other/rpm" +WORKDIR /work/c-toxcore-${PROJECT_COMMIT_ID}/other/rpm +RUN make srpm \ + PROJECT_VERSION="$PROJECT_VERSION" \ + PROJECT_COMMIT_ID="$PROJECT_COMMIT_ID" \ + PROJECT_COMMIT_ID_SHORT="$PROJECT_COMMIT_ID_SHORT" \ + PROJECT_GIT_ROOT="$PROJECT_GIT_ROOT" + +# Build the binary rpms. +RUN rpmbuild --rebuild "toxcore-${PROJECT_VERSION}-1.fc39.src.rpm" + +# Install them and try running the bootstrap daemon. +RUN rpm -i /root/rpmbuild/RPMS/x86_64/*.rpm +SHELL ["/bin/bash", "-o", "pipefail", "-c"] +RUN script tox-bootstrapd --help | grep Usage diff --git a/other/docker/rpm/run b/other/docker/rpm/run new file mode 100755 index 00000000..ea71cc35 --- /dev/null +++ b/other/docker/rpm/run @@ -0,0 +1,13 @@ +#!/bin/sh + +set -eux +PROJECT_VERSION="$(git describe | sed -e 's/^v//' -e 's/-/_/g')" +PROJECT_COMMIT_ID="$(git rev-parse HEAD)" +PROJECT_COMMIT_ID_SHORT="$(git rev-parse --short HEAD)" + +BUILD=rpm +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . \ + --build-arg="PROJECT_VERSION=$PROJECT_VERSION" \ + --build-arg="PROJECT_COMMIT_ID=$PROJECT_COMMIT_ID" \ + --build-arg="PROJECT_COMMIT_ID_SHORT=$PROJECT_COMMIT_ID_SHORT" diff --git a/other/docker/slimcc/.gitignore b/other/docker/slimcc/.gitignore new file mode 100644 index 00000000..25264231 --- /dev/null +++ b/other/docker/slimcc/.gitignore @@ -0,0 +1 @@ +!/Makefile diff --git a/other/docker/slimcc/Makefile b/other/docker/slimcc/Makefile new file mode 100644 index 00000000..f97d0896 --- /dev/null +++ b/other/docker/slimcc/Makefile @@ -0,0 +1,13 @@ +SOURCES := auto_tests/send_message_test.c \ + auto_tests/auto_test_support.c \ + testing/misc_tools.c \ + $(wildcard tox*/*.c tox*/*/*.c) \ + third_party/cmp/cmp.c +OBJECTS := $(SOURCES:.c=.o) + +CC := /work/slimcc/slimcc +CFLAGS := $(shell pkg-config --cflags libsodium opus vpx) +LDFLAGS := $(shell pkg-config --libs libsodium opus vpx) + +send_message_test: $(OBJECTS) + $(CC) -o $@ $+ $(LDFLAGS) diff --git a/other/docker/slimcc/creduce.sh b/other/docker/slimcc/creduce.sh new file mode 100755 index 00000000..853b2a69 --- /dev/null +++ b/other/docker/slimcc/creduce.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +if ! gcc -I/work/c-toxcore/toxcore -fsyntax-only crash.c; then + exit 1 +fi +/work/slimcc/slimcc -I/work/c-toxcore/toxcore -c crash.c 2>&1 | grep "file_exists: Assertion" diff --git a/other/docker/slimcc/run b/other/docker/slimcc/run new file mode 100755 index 00000000..82d71120 --- /dev/null +++ b/other/docker/slimcc/run @@ -0,0 +1,6 @@ +#!/bin/sh + +set -eux +BUILD=slimcc +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/slimcc/slimcc.Dockerfile b/other/docker/slimcc/slimcc.Dockerfile new file mode 100644 index 00000000..ed205acf --- /dev/null +++ b/other/docker/slimcc/slimcc.Dockerfile @@ -0,0 +1,44 @@ +FROM toxchat/c-toxcore:sources AS sources +FROM ubuntu:22.04 + +RUN apt-get update && \ + DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc \ + git \ + libc-dev \ + libopus-dev \ + libsodium-dev \ + libvpx-dev \ + make \ + pkg-config \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Uncomment this to find bugs in slimcc using creduce. +#RUN apt-get update && \ +# DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \ +# creduce \ +# && apt-get clean \ +# && rm -rf /var/lib/apt/lists/* + +WORKDIR /work/slimcc +RUN ["git", "clone", "https://github.com/fuhsnn/slimcc", "/work/slimcc"] +# Comment this to checkout master (e.g. to find bugs using creduce). +RUN ["git", "checkout", "ac9ddf4d39642e6b4880b1a73e19c6f2769d857e"] +RUN ["make", "CFLAGS=-O3", "-j4"] + +WORKDIR /work/c-toxcore +COPY --from=sources /src/ /work/c-toxcore + +# Uncomment this to find bugs in slimcc using creduce. +#COPY other/docker/slimcc/creduce.sh /work/c-toxcore/other/docker/slimcc/ +#RUN cp toxcore/ccompat.h crash.c \ +# && other/docker/slimcc/creduce.sh \ +# && creduce other/docker/slimcc/creduce.sh crash.c + +COPY other/docker/slimcc/Makefile /work/c-toxcore/ +RUN ["make"] + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] +RUN ./send_message_test | grep "tox clients connected" diff --git a/other/docker/sources/Dockerfile b/other/docker/sources/Dockerfile deleted file mode 100644 index 73a3ea0b..00000000 --- a/other/docker/sources/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM scratch - -# Roughly in order of change frequency. -COPY third_party/ /src/third_party/ -COPY .github/scripts/flags*.sh /src/.github/scripts/ -COPY other/proxy/ /src/other/proxy/ -COPY cmake/ /src/cmake/ -COPY other/bootstrap_daemon/ /src/other/bootstrap_daemon/ -COPY other/pkgconfig/ /src/other/pkgconfig/ -COPY other/rpm/ /src/other/rpm/ -COPY other/*.[ch] /src/other/ -COPY CMakeLists.txt so.version /src/ -COPY toxencryptsave/ /src/toxencryptsave/ -COPY testing/ /src/testing/ -COPY toxav/ /src/toxav/ -COPY toxcore/ /src/toxcore/ -COPY auto_tests/ /src/auto_tests/ diff --git a/other/docker/sources/build b/other/docker/sources/build new file mode 100755 index 00000000..277936f6 --- /dev/null +++ b/other/docker/sources/build @@ -0,0 +1,5 @@ +#!/bin/sh + +set -eux +BUILD=sources +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/sources/run.sh b/other/docker/sources/run.sh new file mode 100644 index 00000000..3335f3d5 --- /dev/null +++ b/other/docker/sources/run.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +# Common docker build script usable by many builds in the other/docker +# directory. We're using a common dockerignore that ignores everything except +# sources and CMake scripts. Subdirectories can contain a "dockerignore" file +# (note the missing "." at the start) that will be pasted to the end of the +# common dockerignore file. This way, we can use "COPY ." and get all the +# files we need at once, which is much faster, more flexible, and less +# error-prone than manually writing lots of COPY directives. + +SOURCESDIR="$(dirname "${BASH_SOURCE[0]}")" +DOCKERDIR="$(dirname "${BASH_SOURCE[1]}")" +BUILD="$(basename "$DOCKERDIR")" + +set -eux +cat "$SOURCESDIR/sources.Dockerfile.dockerignore" >"$DOCKERDIR/$BUILD.Dockerfile.dockerignore" +if [ -f "$DOCKERDIR/dockerignore" ]; then + cat "$DOCKERDIR/dockerignore" >>"$DOCKERDIR/$BUILD.Dockerfile.dockerignore" +fi + +docker build "${DOCKERFLAGS[@]}" -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/sources/sources.Dockerfile b/other/docker/sources/sources.Dockerfile new file mode 100644 index 00000000..c3008b42 --- /dev/null +++ b/other/docker/sources/sources.Dockerfile @@ -0,0 +1,2 @@ +FROM scratch +COPY . /src/ diff --git a/other/docker/sources/sources.Dockerfile.dockerignore b/other/docker/sources/sources.Dockerfile.dockerignore new file mode 100644 index 00000000..3a3643cb --- /dev/null +++ b/other/docker/sources/sources.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/docker/sparse/.gitignore b/other/docker/sparse/.gitignore new file mode 100644 index 00000000..25264231 --- /dev/null +++ b/other/docker/sparse/.gitignore @@ -0,0 +1 @@ +!/Makefile diff --git a/other/docker/sparse/Makefile b/other/docker/sparse/Makefile new file mode 100644 index 00000000..ce567b72 --- /dev/null +++ b/other/docker/sparse/Makefile @@ -0,0 +1,70 @@ +SOURCES := $(wildcard tox*/*.c tox*/*/*.c) \ + third_party/cmp/cmp.c +OBJECTS := $(SOURCES:.c=.o) + +CFLAGS := $(shell pkg-config --cflags libsodium opus vpx) +CPPFLAGS := -DSPARSE -DTCP_SERVER_USE_EPOLL=1 -DMIN_LOGGER_LEVEL=LOGGER_LEVEL_TRACE + +SPARSE_FLAGS := \ + -Wsparse-error \ + -Wpedantic \ + -Waddress \ + -Waddress-space \ + -Wbitwise \ + -Wbitwise-pointer \ + -Wcast-from-as \ + -Wcast-to-as \ + -Wcast-truncate \ + -Wconstant-suffix \ + -Wconstexpr-not-const \ + -Wcontext \ + -Wdecl \ + -Wdefault-bitfield-sign \ + -Wdesignated-init \ + -Wdo-while \ + -Wenum-mismatch \ + -Wexternal-function-has-definition \ + -Wflexible-array-array \ + -Wflexible-array-nested \ + -Wflexible-array-union \ + -Wimplicit-int \ + -Winit-cstring \ + -Wint-to-pointer-cast \ + -Wmemcpy-max-count \ + -Wnon-pointer-null \ + -Wnewline-eof \ + -Wold-initializer \ + -Wold-style-definition \ + -Wone-bit-signed-bitfield \ + -Woverride-init \ + -Woverride-init-all \ + -Wparen-string \ + -Wpast-deep-designator \ + -Wpedantic \ + -Wpointer-to-int-cast \ + -Wptr-subtraction-blows \ + -Wreturn-void \ + -Wshadow \ + -Wshift-count-negative \ + -Wshift-count-overflow \ + -Wsizeof-bool \ + -Wstrict-prototypes \ + -Wpointer-arith \ + -Wsparse-error \ + -Wtautological-compare \ + -Wtransparent-union \ + -Wtypesign \ + -Wundef \ + -Wuninitialized \ + -Wunion-cast \ + -Wvla + +SMATCH_FLAGS := $(foreach i,$(shell smatch --show-checks | grep -o 'check_.*'),--enable=$i) + +analyse: $(OBJECTS) + +%.o: %.c + @echo "Processing $<" + @sparse $(CFLAGS) $(CPPFLAGS) $(SPARSE_FLAGS) $< +# @smatch $(CFLAGS) $(CPPFLAGS) $(SMATCH_FLAGS) $< +# @sparse-llvm $(CFLAGS) $(CPPFLAGS) $< > /dev/null diff --git a/other/docker/sparse/local.mk b/other/docker/sparse/local.mk new file mode 100644 index 00000000..b67f33b8 --- /dev/null +++ b/other/docker/sparse/local.mk @@ -0,0 +1 @@ +CFLAGS=-O3 -g -Wno-discarded-qualifiers -Wno-format-truncation -Wno-stringop-truncation -Wno-uninitialized -Wno-unused -Wno-unused-result diff --git a/other/docker/sparse/run b/other/docker/sparse/run new file mode 100755 index 00000000..6b87e91b --- /dev/null +++ b/other/docker/sparse/run @@ -0,0 +1,6 @@ +#!/bin/sh + +set -eux +BUILD=sparse +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/sparse/sparse.Dockerfile b/other/docker/sparse/sparse.Dockerfile new file mode 100644 index 00000000..e4e185a8 --- /dev/null +++ b/other/docker/sparse/sparse.Dockerfile @@ -0,0 +1,35 @@ +FROM toxchat/c-toxcore:sources AS sources +FROM ubuntu:22.04 + +RUN apt-get update && \ + DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \ + ca-certificates \ + creduce \ + g++ \ + gcc \ + git \ + libc-dev \ + libopus-dev \ + libsodium-dev \ + libsqlite3-dev \ + libssl-dev \ + libvpx-dev \ + llvm-dev \ + make \ + pkg-config \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /work/smatch +RUN git clone --depth=1 https://repo.or.cz/smatch.git /work/smatch +COPY other/docker/sparse/local.mk /work/smatch/local.mk +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 +#RUN sparsec $(pkg-config --cflags --libs libsodium opus vpx) crash.c + +COPY other/docker/sparse/Makefile /work/c-toxcore/ +RUN make -j4 diff --git a/other/docker/tcc/run b/other/docker/tcc/run index 870852ba..63412b55 100755 --- a/other/docker/tcc/run +++ b/other/docker/tcc/run @@ -2,4 +2,5 @@ set -eux BUILD=tcc -docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/Dockerfile" . +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/tcc/Dockerfile b/other/docker/tcc/tcc.Dockerfile similarity index 87% rename from other/docker/tcc/Dockerfile rename to other/docker/tcc/tcc.Dockerfile index d1f10181..425256bc 100644 --- a/other/docker/tcc/Dockerfile +++ b/other/docker/tcc/tcc.Dockerfile @@ -1,3 +1,4 @@ +FROM toxchat/c-toxcore:sources AS sources FROM ubuntu:22.04 RUN apt-get update && \ @@ -12,12 +13,7 @@ RUN apt-get update && \ && rm -rf /var/lib/apt/lists/* WORKDIR /work -COPY auto_tests/ /work/auto_tests/ -COPY testing/ /work/testing/ -COPY toxav/ /work/toxav/ -COPY toxcore/ /work/toxcore/ -COPY toxencryptsave/ /work/toxencryptsave/ -COPY third_party/ /work/third_party/ +COPY --from=sources /src/ /work/ SHELL ["/bin/bash", "-o", "pipefail", "-c"] diff --git a/other/docker/tokstyle/run b/other/docker/tokstyle/run index c743defd..1d92173d 100755 --- a/other/docker/tokstyle/run +++ b/other/docker/tokstyle/run @@ -2,4 +2,5 @@ set -eux BUILD=tokstyle -docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/Dockerfile" . +other/docker/sources/build +docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . diff --git a/other/docker/tokstyle/Dockerfile b/other/docker/tokstyle/tokstyle.Dockerfile similarity index 51% rename from other/docker/tokstyle/Dockerfile rename to other/docker/tokstyle/tokstyle.Dockerfile index 3bb677b5..1cc0c2bc 100644 --- a/other/docker/tokstyle/Dockerfile +++ b/other/docker/tokstyle/tokstyle.Dockerfile @@ -1,3 +1,4 @@ +FROM toxchat/c-toxcore:sources AS sources FROM toxchat/haskell:hs-tokstyle AS tokstyle FROM ubuntu:22.04 @@ -15,8 +16,11 @@ RUN apt-get update && \ COPY --from=tokstyle /bin/check-c /bin/ RUN ["git", "clone", "--depth=1", "https://github.com/TokTok/hs-tokstyle", "/src/workspace/hs-tokstyle"] -COPY toxav/ /src/workspace/c-toxcore/toxav/ -COPY toxcore/ /src/workspace/c-toxcore/toxcore/ -COPY toxencryptsave/ /src/workspace/c-toxcore/toxencryptsave/ -COPY third_party/cmp/cmp.h /src/workspace/c-toxcore/third_party/cmp/cmp.h -RUN /bin/check-c $(find /src/workspace/c-toxcore -name "*.c") +COPY --from=sources /src/ /src/workspace/c-toxcore/ +RUN /bin/check-c $(find /src/workspace/c-toxcore -name "*.c" \ + -and -not -wholename "*/auto_tests/*" \ + -and -not -wholename "*/other/*" \ + -and -not -wholename "*/super_donators/*" \ + -and -not -wholename "*/testing/*" \ + -and -not -wholename "*/third_party/cmp/examples/*" \ + -and -not -wholename "*/third_party/cmp/test/*") diff --git a/other/docker/windows/Dockerfile b/other/docker/windows/Dockerfile index 7d4d59a4..ac7ba11c 100644 --- a/other/docker/windows/Dockerfile +++ b/other/docker/windows/Dockerfile @@ -1,10 +1,13 @@ -FROM debian:bullseye-slim +FROM debian:bookworm-slim + +# When editing, make sure to update /other/windows_build_script_toxcore.sh and +# INSTALL.md to match. # Build-time environment variables -ARG VERSION_MSGPACK=4.0.0 \ +ARG VERSION_OPUS=1.4 \ VERSION_SODIUM=1.0.19 \ - VERSION_OPUS=1.3.1 \ - VERSION_VPX=1.11.0 \ + VERSION_VPX=1.14.0 \ + ENABLE_HASH_VERIFICATION=true \ \ SUPPORT_TEST=false \ SUPPORT_ARCH_i686=true \ @@ -18,6 +21,7 @@ ENV SUPPORT_TEST=${SUPPORT_TEST} \ CROSS_COMPILE=${CROSS_COMPILE} WORKDIR /work +COPY check_sha256.sh . COPY get_packages.sh . RUN ./get_packages.sh @@ -30,6 +34,6 @@ ENV ENABLE_TEST=false \ ALLOW_TEST_FAILURE=false \ ENABLE_ARCH_i686=true \ ENABLE_ARCH_x86_64=true \ - EXTRA_CMAKE_FLAGS="-DTEST_TIMEOUT_SECONDS=90" + EXTRA_CMAKE_FLAGS="-DTEST_TIMEOUT_SECONDS=90 -DUSE_IPV6=OFF" ENTRYPOINT ["bash", "./build_toxcore.sh"] diff --git a/other/docker/windows/build_dependencies.sh b/other/docker/windows/build_dependencies.sh index dcba4f4d..fa2353c9 100755 --- a/other/docker/windows/build_dependencies.sh +++ b/other/docker/windows/build_dependencies.sh @@ -7,6 +7,8 @@ fi #=== Cross-Compile Dependencies === +. ./check_sha256.sh + build() { ARCH=${1} @@ -21,7 +23,7 @@ build() { mkdir -p "$PREFIX_DIR" export MAKEFLAGS=j"$(nproc)" - export CFLAGS=-O3 + export CFLAGS="-O3 -D_FORTIFY_SOURCE=3 -D_GLIBCXX_ASSERTIONS -ftrivial-auto-var-init=zero -fPIE -pie -fstack-protector-strong -fstack-clash-protection -fcf-protection=full" CURL_OPTIONS=(-L --connect-timeout 10) @@ -41,19 +43,42 @@ build() { echo echo "=== Building Sodium $VERSION_SODIUM $ARCH ===" curl "${CURL_OPTIONS[@]}" -O "https://github.com/jedisct1/libsodium/releases/download/$VERSION_SODIUM-RELEASE/libsodium-$VERSION_SODIUM.tar.gz" + check_sha256 "018d79fe0a045cca07331d37bd0cb57b2e838c51bc48fd837a1472e50068bbea" "libsodium-$VERSION_SODIUM.tar.gz" tar -xf "libsodium-$VERSION_SODIUM.tar.gz" cd "libsodium-stable" - ./configure --host="$WINDOWS_TOOLCHAIN" --prefix="$PREFIX_DIR" --disable-shared --enable-static + ./configure \ + --host="$WINDOWS_TOOLCHAIN" \ + --prefix="$PREFIX_DIR" \ + --disable-shared \ + --enable-static make make install cd .. echo echo "=== Building Opus $VERSION_OPUS $ARCH ===" - curl "${CURL_OPTIONS[@]}" -O "https://archive.mozilla.org/pub/opus/opus-$VERSION_OPUS.tar.gz" + if [ "$ARCH" = "i686" ]; then + LIB_OPUS_CFLAGS="" + else + # This makes the build work with -fstack-clash-protection, as otherwise it crashes with: + # silk/float/encode_frame_FLP.c: In function 'silk_encode_frame_FLP': + # silk/float/encode_frame_FLP.c:379:1: internal compiler error: in i386_pe_seh_unwind_emit, at config/i386/winnt.cc:1274 + # Should get patched in a future gcc version: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90458 + LIB_OPUS_CFLAGS="-fno-asynchronous-unwind-tables" + fi + + curl "${CURL_OPTIONS[@]}" -O "https://ftp.osuosl.org/pub/xiph/releases/opus/opus-$VERSION_OPUS.tar.gz" + check_sha256 "c9b32b4253be5ae63d1ff16eea06b94b5f0f2951b7a02aceef58e3a3ce49c51f" "opus-$VERSION_OPUS.tar.gz" tar -xf "opus-$VERSION_OPUS.tar.gz" cd "opus-$VERSION_OPUS" - ./configure --host="$WINDOWS_TOOLCHAIN" --prefix="$PREFIX_DIR" --disable-extra-programs --disable-doc --disable-shared --enable-static + CFLAGS="$CFLAGS $LIB_OPUS_CFLAGS" \ + ./configure \ + --host="$WINDOWS_TOOLCHAIN" \ + --prefix="$PREFIX_DIR" \ + --disable-extra-programs \ + --disable-doc \ + --disable-shared \ + --enable-static make make install cd .. @@ -72,9 +97,19 @@ build() { LIB_VPX_CFLAGS="-fno-asynchronous-unwind-tables" fi curl "${CURL_OPTIONS[@]}" "https://github.com/webmproject/libvpx/archive/v$VERSION_VPX.tar.gz" -o "libvpx-$VERSION_VPX.tar.gz" + check_sha256 "5f21d2db27071c8a46f1725928a10227ae45c5cd1cad3727e4aafbe476e321fa" "libvpx-$VERSION_VPX.tar.gz" tar -xf "libvpx-$VERSION_VPX.tar.gz" cd "libvpx-$VERSION_VPX" - CFLAGS="$LIB_VPX_CFLAGS" CROSS="$WINDOWS_TOOLCHAIN"- ./configure --target="$LIB_VPX_TARGET" --prefix="$PREFIX_DIR" --disable-examples --disable-unit-tests --disable-shared --enable-static + CFLAGS="$CFLAGS $LIB_VPX_CFLAGS" \ + CROSS="$WINDOWS_TOOLCHAIN"- \ + ./configure \ + --target="$LIB_VPX_TARGET" \ + --prefix="$PREFIX_DIR" \ + --disable-examples \ + --disable-unit-tests \ + --disable-tools \ + --disable-shared \ + --enable-static make make install cd .. diff --git a/other/docker/windows/build_toxcore.sh b/other/docker/windows/build_toxcore.sh old mode 100644 new mode 100755 index 59ab8860..d67b68c5 --- a/other/docker/windows/build_toxcore.sh +++ b/other/docker/windows/build_toxcore.sh @@ -2,6 +2,9 @@ set -e -x +# Note: when modifying this script, don't forget to update the appropriate +# parts of the cross-compilation section of the INSTALL.md. + #=== Cross-Compile Toxcore === build() { @@ -23,13 +26,8 @@ build() { rm -rf /tmp/* - # where to install static/shared toxcores before deciding whether they should be copied over to the user - STATIC_TOXCORE_PREFIX_DIR="/tmp/static_prefix" - SHARED_TOXCORE_PREFIX_DIR="/tmp/shared_prefix" - mkdir -p "$STATIC_TOXCORE_PREFIX_DIR" "$SHARED_TOXCORE_PREFIX_DIR" - export MAKEFLAGS=j"$(nproc)" - export CFLAGS=-O3 + export CFLAGS="-D_FORTIFY_SOURCE=3 -D_GLIBCXX_ASSERTIONS -ftrivial-auto-var-init=zero -fPIE -pie -fstack-protector-strong -fstack-clash-protection -fcf-protection=full" echo echo "=== Building toxcore $ARCH ===" @@ -61,19 +59,39 @@ build() { echo "SET(CROSSCOMPILING_EMULATOR /usr/bin/wine)" >>windows_toolchain.cmake fi + if [ "$ARCH" = "i686" ]; then + TOXCORE_CFLAGS="" + else + # This makes the build work with -fstack-clash-protection, as otherwise it crashes with: + #/tmp/toxcore/toxcore/logger.c: In function 'logger_abort': + #/tmp/toxcore/toxcore/logger.c:124:1: internal compiler error: in seh_emit_stackalloc, at config/i386/winnt.cc:1055 + # Should get patched in a future gcc version: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90458 + TOXCORE_CFLAGS="-fno-asynchronous-unwind-tables" + fi + + # Patch CMakeLists.txt to make cracker.exe statically link against OpenMP. For some reason + # -DCMAKE_EXE_LINKER_FLAGS="-static" doesn't do it. + sed -i "s|OpenMP::OpenMP_C)|$(realpath -- /usr/lib/gcc/"$WINDOWS_TOOLCHAIN"/*-win32/libgomp.a) \${CMAKE_THREAD_LIBS_INIT})\ntarget_compile_options(cracker PRIVATE -fopenmp)|g" ../other/fun/CMakeLists.txt + # Silly way to bypass a shellharden check read -ra EXTRA_CMAKE_FLAGS_ARRAY <<<"$EXTRA_CMAKE_FLAGS" - cmake -DCMAKE_TOOLCHAIN_FILE=windows_toolchain.cmake \ - -DCMAKE_INSTALL_PREFIX="$STATIC_TOXCORE_PREFIX_DIR" \ - -DENABLE_SHARED=OFF \ + CFLAGS="$CFLAGS $TOXCORE_CFLAGS" \ + cmake \ + -DCMAKE_TOOLCHAIN_FILE=windows_toolchain.cmake \ + -DCMAKE_INSTALL_PREFIX="$RESULT_PREFIX_DIR" \ + -DCMAKE_BUILD_TYPE="Release" \ + -DENABLE_SHARED=ON \ -DENABLE_STATIC=ON \ - -DCMAKE_C_FLAGS="$CMAKE_C_FLAGS" \ - -DCMAKE_CXX_FLAGS="$CMAKE_CXX_FLAGS" \ - -DCMAKE_EXE_LINKER_FLAGS="$CMAKE_EXE_LINKER_FLAGS -fstack-protector" \ - -DCMAKE_SHARED_LINKER_FLAGS="$CMAKE_SHARED_LINKER_FLAGS" \ + -DSTRICT_ABI=ON \ + -DEXPERIMENTAL_API=ON \ + -DBUILD_FUN_UTILS=ON \ + -DCMAKE_EXE_LINKER_FLAGS="-static" \ + -DCMAKE_SHARED_LINKER_FLAGS="-static" \ "${EXTRA_CMAKE_FLAGS_ARRAY[@]}" \ -S .. - cmake --build . --target install -- -j"$(nproc)" + cmake --build . --target install --parallel "$(nproc)" + # CMake doesn't install fun utils, so do it manually + cp -a other/fun/*.exe "$RESULT_PREFIX_DIR/bin/" if [ "$ENABLE_TEST" = "true" ]; then rm -rf /root/.wine @@ -87,10 +105,12 @@ build() { winecfg export CTEST_OUTPUT_ON_FAILURE=1 - # add libgcc_s_sjlj-1.dll libwinpthread-1.dll into PATH env var of wine + # we don't have to do this since autotests are statically compiled now, + # but just in case add MinGW-w64 dll locations to the PATH anyway export WINEPATH="$( - cd /usr/lib/gcc/"$WINDOWS_TOOLCHAIN"/*posix/ + cd /usr/lib/gcc/"$WINDOWS_TOOLCHAIN"/*win32/ winepath -w "$PWD" + cd - )"\;"$(winepath -w /usr/"$WINDOWS_TOOLCHAIN"/lib/)" if [ "$ALLOW_TEST_FAILURE" = "true" ]; then @@ -102,47 +122,48 @@ build() { fi fi - # move static dependencies - cp -a "$STATIC_TOXCORE_PREFIX_DIR"/* "$RESULT_PREFIX_DIR" - cp -a "$DEP_PREFIX_DIR"/* "$RESULT_PREFIX_DIR" - - # make libtox.dll - cd "$SHARED_TOXCORE_PREFIX_DIR" - for archive in "$STATIC_TOXCORE_PREFIX_DIR"/lib/libtox*.a; do - "$WINDOWS_TOOLCHAIN"-ar xv "$archive" + # generate def, lib and exp as they supposedly help with linking against the dlls, + # especially the lib is supposed to be of great help when linking on msvc. + # cd in order to keep the object names inside .lib and .dll.a short + cd "$RESULT_PREFIX_DIR"/bin/ + for TOX_DLL in *.dll; do + gendef - "$TOX_DLL" >"${TOX_DLL%.*}.def" + # we overwrite the CMake-generated .dll.a for the better + # compatibility with the .lib being generated here + "$WINDOWS_TOOLCHAIN"-dlltool \ + --input-def "${TOX_DLL%.*}.def" \ + --output-lib "${TOX_DLL%.*}.lib" \ + --output-exp "${TOX_DLL%.*}.exp" \ + --output-delaylib "../lib/${TOX_DLL%.*}.dll.a" \ + --dllname "$TOX_DLL" done + cd - + # copy over the deps if [ "$CROSS_COMPILE" = "true" ]; then LIBWINPTHREAD="/usr/$WINDOWS_TOOLCHAIN/lib/libwinpthread.a" + cd /usr/lib/gcc/"$WINDOWS_TOOLCHAIN"/*win32/ + LIBSSP="$PWD/libssp.a" + cd - else LIBWINPTHREAD="/usr/$WINDOWS_TOOLCHAIN/sys-root/mingw/lib/libwinpthread.a" + LIBSSP="/usr/$WINDOWS_TOOLCHAIN/sys-root/mingw/lib/libssp.a" fi + cp -a "$LIBWINPTHREAD" "$LIBSSP" "$RESULT_PREFIX_DIR/lib/" + for STATIC_LIB in "$DEP_PREFIX_DIR"/lib/*.a; do + [[ "$STATIC_LIB" == *.dll.a ]] && continue + cp -a "$STATIC_LIB" "$RESULT_PREFIX_DIR/lib/" + done + cp "$DEP_PREFIX_DIR"/lib/pkgconfig/* "$RESULT_PREFIX_DIR/lib/pkgconfig/" - "$WINDOWS_TOOLCHAIN"-gcc -Wl,--export-all-symbols \ - -Wl,--out-implib=libtox.dll.a \ - -shared \ - -o libtox.dll \ - *.obj \ - "$STATIC_TOXCORE_PREFIX_DIR"/lib/*.a \ - "$DEP_PREFIX_DIR"/lib/*.a \ - "$LIBWINPTHREAD" \ - -liphlpapi \ - -lws2_32 \ - -static-libgcc \ - -lssp - cp libtox.dll.a "$RESULT_PREFIX_DIR"/lib - mkdir -p "$RESULT_PREFIX_DIR"/bin - cp libtox.dll "$RESULT_PREFIX_DIR"/bin + # strip everything + set +e + "$WINDOWS_TOOLCHAIN"-strip --strip-unneeded "$RESULT_PREFIX_DIR"/bin/*.* "$RESULT_PREFIX_DIR"/lib/*.* + set -e rm -rf /tmp/* - # remove everything from include directory except tox headers - mv "$RESULT_PREFIX_DIR"/include/tox "$RESULT_PREFIX_DIR"/tox - rm -rf "$RESULT_PREFIX_DIR"/include/* - mv "$RESULT_PREFIX_DIR"/tox "$RESULT_PREFIX_DIR"/include/tox - sed -i "s|^prefix=.*|prefix=$RESULT_PREFIX_DIR|g" "$RESULT_PREFIX_DIR"/lib/pkgconfig/*.pc - sed -i "s|^libdir=.*|libdir=$RESULT_PREFIX_DIR/lib|g" "$RESULT_PREFIX_DIR"/lib/*.la } #=== Test Supported vs. Enabled === diff --git a/other/docker/windows/check_sha256.sh b/other/docker/windows/check_sha256.sh new file mode 100644 index 00000000..6e5a4f86 --- /dev/null +++ b/other/docker/windows/check_sha256.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +check_sha256() { + [ "$ENABLE_HASH_VERIFICATION" = "true" ] && _check_sha256 "$@" +} + +_check_sha256() { + if ! (echo "$1 $2" | sha256sum -c --status -); then + echo "Error: sha256 of $2 doesn't match the known one." + echo "Expected: $1 $2" + echo "Got: $(sha256sum "$2")" + return 1 + fi + echo "sha256 matches the expected one: $1" + return 0 +} diff --git a/other/docker/windows/get_packages.sh b/other/docker/windows/get_packages.sh index 2c86e17d..efd81e68 100755 --- a/other/docker/windows/get_packages.sh +++ b/other/docker/windows/get_packages.sh @@ -1,10 +1,11 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash set -e -x #=== Install Packages === apt-get update +apt-get upgrade -y # Arch-independent packages required for building toxcore's dependencies and toxcore itself apt-get install -y \ @@ -13,9 +14,10 @@ apt-get install -y \ ca-certificates \ cmake \ curl \ - libtool \ libc-dev \ + libtool \ make \ + mingw-w64-tools \ pkg-config \ tree \ yasm @@ -38,12 +40,27 @@ if [ "$SUPPORT_TEST" = "true" ]; then apt-get install -y \ texinfo + CURL_OPTIONS=(-L --connect-timeout 10) + + # While we would prefer to use Debian's Wine packages, use WineHQ's packages + # instead as Debian Bookworm's Wine crashes when creating a 64-bit prefix. + # see https://github.com/TokTok/c-toxcore/pull/2713#issuecomment-1967319113 + # for the crash details + curl "${CURL_OPTIONS[@]}" -o /etc/apt/keyrings/winehq-archive.key \ + https://dl.winehq.org/wine-builds/winehq.key + curl "${CURL_OPTIONS[@]}" -O --output-dir /etc/apt/sources.list.d/ \ + https://dl.winehq.org/wine-builds/debian/dists/bookworm/winehq-bookworm.sources + + . ./check_sha256.sh + check_sha256 "78b185fabdb323971d13bd329fefc8038e08559aa51c4996de18db0639a51df6" \ + "/etc/apt/keyrings/winehq-archive.key" + check_sha256 "8dd8ef66c749d56e798646674c1c185a99b3ed6727ca0fbb5e493951e66c0f9e" \ + "/etc/apt/sources.list.d/winehq-bookworm.sources" + dpkg --add-architecture i386 apt-get update apt-get install -y \ - wine \ - wine32 \ - wine64 + winehq-stable fi # Clean up to reduce image size diff --git a/other/event_tooling/generate_event_c.cpp b/other/event_tooling/generate_event_c.cpp index 92cab072..de5e52ac 100644 --- a/other/event_tooling/generate_event_c.cpp +++ b/other/event_tooling/generate_event_c.cpp @@ -172,6 +172,7 @@ void generate_event_impl(const std::string& event_name, const std::vector" << t.name_data << " = nullptr;\n"; f << " " << event_name_l << "->" << t.name_length << " = 0;\n"; f << " }\n\n"; + f << " if (" << t.name_data << " == nullptr) {\n"; + f << " assert(" << t.name_length << " == 0);\n"; + f << " return true;\n }\n\n"; f << " uint8_t *" << t.name_data << "_copy = (uint8_t *)malloc(" << t.name_length << ");\n\n"; f << " if (" << t.name_data << "_copy == nullptr) {\n"; f << " return false;\n }\n\n"; @@ -395,7 +407,7 @@ void generate_event_impl(const std::string& event_name, const std::vectorevents, state->mem);\n\n"; f << " if (" << event_name_l << " == nullptr) {\n"; f << " state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;\n return nullptr;\n }\n\n"; - f << " return " << event_name_l << ";\n}\n\n"; + f << " return " << event_name_l << ";\n}\n"; f << R"( @@ -462,9 +475,9 @@ void generate_event_impl(const std::string& event_name, const std::vector #define NUM_THREADS() ((unsigned) omp_get_max_threads()) #else +#pragma message("Being built without OpenMP support -- the program will utilize a single thread only.") #define NUM_THREADS() (1U) #endif @@ -112,8 +113,9 @@ static size_t match_hex_prefix(const uint8_t *key, const uint8_t *prefix, size_t static void cracker_core(uint64_t range_start, uint64_t range_end, uint64_t range_offs, uint64_t priv_key_shadow[4], uint32_t *longest_match, uint8_t hex_prefix[MAX_CRACK_BYTES], size_t prefix_chars_len) { +#if defined(_OPENMP) #pragma omp parallel for firstprivate(priv_key_shadow) shared(longest_match, range_start, range_end, range_offs, hex_prefix, prefix_chars_len) schedule(static) default(none) - +#endif for (uint64_t batch = range_start; batch < range_end; ++batch) { uint8_t *priv_key = (uint8_t *) priv_key_shadow; /* @@ -134,14 +136,19 @@ static void cracker_core(uint64_t range_start, uint64_t range_end, uint64_t rang // Global compare and update uint32_t l_longest_match; +#if defined(_OPENMP) #pragma omp atomic read +#endif l_longest_match = *longest_match; if (matching > l_longest_match) { +#if defined(_OPENMP) #pragma omp atomic write +#endif *longest_match = matching; - +#if defined(_OPENMP) #pragma omp critical +#endif { printf("%u chars matching: \n", matching); printf("Public key: "); @@ -198,7 +205,6 @@ int main(int argc, char *argv[]) randombytes(priv_key, KEY_LEN); uint32_t longest_match = 0; - // Finishes a batch every ~10s on my PC const uint64_t batch_size = (UINT64_C(1) << 18) * NUM_THREADS(); @@ -220,7 +226,6 @@ int main(int argc, char *argv[]) return 0; } - for (uint64_t tries = 0; tries < rem_start; tries += batch_size) { cracker_core(tries, tries + batch_size, 0, priv_key_shadow, &longest_match, hex_prefix, prefix_chars_len); diff --git a/other/fun/cracker_simple.c b/other/fun/cracker_simple.c index 18f4e931..811f93df 100644 --- a/other/fun/cracker_simple.c +++ b/other/fun/cracker_simple.c @@ -13,11 +13,8 @@ #include #include -/* Sodium includes*/ -#include -#include +#include -#include "../../testing/misc_tools.h" #include "../../toxcore/ccompat.h" // Secret key and public key length @@ -30,7 +27,6 @@ static void print_key(const uint8_t *client_id) } } - int main(int argc, char *argv[]) { if (argc < 2) { @@ -41,7 +37,13 @@ int main(int argc, char *argv[]) long long unsigned int num_tries = 0; size_t len = strlen(argv[1]) / 2; - unsigned char *key = hex_string_to_bin(argv[1]); + unsigned char *key = (unsigned char *)malloc(len); + const char *hex_end = nullptr; + if (sodium_hex2bin(key, len, argv[1], strlen(argv[1]), nullptr, nullptr, &hex_end) != 0 + || hex_end != argv[1] + strlen(argv[1])) { + printf("Invalid key provided\n"); + return 1; + } uint8_t pub_key[KEY_LEN], priv_key[KEY_LEN], c_key[KEY_LEN]; if (len > KEY_LEN) { diff --git a/other/fun/sign.c b/other/fun/sign.c index a75fa0d4..d38dd77d 100644 --- a/other/fun/sign.c +++ b/other/fun/sign.c @@ -18,7 +18,6 @@ #include #include -#include "../../testing/misc_tools.h" // hex_string_to_bin #include "../../toxcore/ccompat.h" static int load_file(const char *filename, unsigned char **result) @@ -70,7 +69,12 @@ int main(int argc, char *argv[]) } if (argc == 5 && argv[1][0] == 's') { - unsigned char *secret_key = hex_string_to_bin(argv[2]); + const char *hex_end = nullptr; + if (sodium_hex2bin(sk, sizeof(sk), argv[2], strlen(argv[2]), nullptr, nullptr, &hex_end) != 0 + || hex_end != argv[2] + strlen(argv[2])) { + printf("Invalid secret key provided.\n"); + goto fail; + } unsigned char *data = nullptr; int size = load_file(argv[3], &data); @@ -80,9 +84,8 @@ int main(int argc, char *argv[]) unsigned long long smlen; unsigned char *sm = (unsigned char *)malloc(size + crypto_sign_ed25519_BYTES * 2); - crypto_sign_ed25519(sm, &smlen, data, size, secret_key); + crypto_sign_ed25519(sm, &smlen, data, size, sk); free(data); - free(secret_key); if (smlen - size != crypto_sign_ed25519_BYTES) { free(sm); @@ -110,8 +113,13 @@ int main(int argc, char *argv[]) } if (argc == 4 && argv[1][0] == 'c') { - unsigned char *public_key = hex_string_to_bin(argv[2]); - unsigned char *data; + const char *hex_end = nullptr; + if (sodium_hex2bin(pk, sizeof(pk), argv[2], strlen(argv[2]), nullptr, nullptr, &hex_end) != 0 + || hex_end != argv[2] + strlen(argv[2])) { + printf("Invalid public key provided.\n"); + goto fail; + } + unsigned char *data = nullptr; int size = load_file(argv[3], &data); if (size < 0) { @@ -127,7 +135,7 @@ int main(int argc, char *argv[]) unsigned char *m = (unsigned char *)malloc(size); unsigned long long mlen; - if (crypto_sign_ed25519_open(m, &mlen, signe, size, public_key) == -1) { + if (crypto_sign_ed25519_open(m, &mlen, signe, size, pk) == -1) { printf("Failed checking sig.\n"); free(m); free(signe); diff --git a/other/rpm/toxcore.spec.in b/other/rpm/toxcore.spec.in index 3391d4b9..d7064eb6 100644 --- a/other/rpm/toxcore.spec.in +++ b/other/rpm/toxcore.spec.in @@ -1,7 +1,7 @@ %define full_name c-@PROJECT_NAME@ %define commit 0 %if "${commit}" != "0" -%define shortcommit %(c=%{commit}; echo ${c:0:7}) +%define shortcommit %(c=%{commit}; echo ${c:0:9}) %endif Name: @PROJECT_NAME@ @@ -18,10 +18,12 @@ Source0: https://github.com/TokTok/%{full_name}/archive/%{commit}/%{full_ %endif BuildRequires: cmake +BuildRequires: g++ +BuildRequires: gcc +BuildRequires: libconfig-devel +BuildRequires: libsodium-devel BuildRequires: libvpx-devel BuildRequires: opus-devel -BuildRequires: libsodium-devel -BuildRequires: libconfig-devel BuildRequires: systemd-units %description @@ -63,10 +65,10 @@ Tox DHT bootstrap daemon. %build %cmake -%{__make} %{?_smp_mflags} +%{__make} -C redhat-linux-build %{?_smp_mflags} %install -%make_install +%make_install -C redhat-linux-build mkdir -p %{buildroot}%{_unitdir} install -m 0644 other/rpm/tox-bootstrapd.service %{buildroot}%{_unitdir}/tox-bootstrapd.service install -d "%{buildroot}%{_sharedstatedir}/tox-bootstrapd" @@ -74,7 +76,7 @@ mkdir -p %{buildroot}%{_sysconfdir} install -m 0644 other/bootstrap_daemon/tox-bootstrapd.conf %{buildroot}%{_sysconfdir}/tox-bootstrapd.conf %check -%{__make} %{?_smp_mflags} test +%{__make} -C redhat-linux-build %{?_smp_mflags} test %pre -n tox-bootstrapd getent group tox-bootstrapd >/dev/null || groupadd -r tox-bootstrapd @@ -97,7 +99,7 @@ getent passwd tox-bootstrapd >/dev/null || \ %files %defattr(-, root, root) -%doc LICENSE.md README.md CHANGELOG.md +%doc LICENSE README.md CHANGELOG.md %{_libdir}/libtoxcore.so* %files devel @@ -111,9 +113,10 @@ getent passwd tox-bootstrapd >/dev/null || \ %files -n tox-bootstrapd %defattr(-, root, root) +%{_bindir}/DHT_bootstrap %{_bindir}/tox-bootstrapd %{_unitdir}/tox-bootstrapd.service -%{_sharedstatedir}/tox-bootstrapd +%{_datadir}/bash-completion/completions/tox-bootstrapd %attr(-,tox-bootstrapd,tox-bootstrapd) %{_sharedstatedir}/tox-bootstrapd/ %config(noreplace) %{_sysconfdir}/tox-bootstrapd.conf diff --git a/other/windows_build_script_toxcore.sh b/other/windows_build_script_toxcore.sh index 4ca26571..1f006451 100644 --- a/other/windows_build_script_toxcore.sh +++ b/other/windows_build_script_toxcore.sh @@ -1,8 +1,12 @@ #!/bin/sh -export VERSION_SODIUM="1.0.18" -export VERSION_OPUS="1.3.1" -export VERSION_VPX="1.9.0" +# When editing, make sure to update /other/docker/windows/Dockerfile and +# INSTALL.md to match. + +export VERSION_OPUS="1.4" +export VERSION_SODIUM="1.0.19" +export VERSION_VPX="1.14.0" +export ENABLE_HASH_VERIFICATION=true export SUPPORT_TEST=false export SUPPORT_ARCH_i686=true @@ -15,6 +19,6 @@ export ENABLE_TEST=false export ALLOW_TEST_FAILURE=false export ENABLE_ARCH_i686=true export ENABLE_ARCH_x86_64=true -export EXTRA_CMAKE_FLAGS="-DTEST_TIMEOUT_SECONDS=90" +export EXTRA_CMAKE_FLAGS="-DTEST_TIMEOUT_SECONDS=90 -DUSE_IPV6=OFF" sh ./other/docker/windows/build_toxcore.sh diff --git a/testing/BUILD.bazel b/testing/BUILD.bazel index ac19a6df..41ba8338 100644 --- a/testing/BUILD.bazel +++ b/testing/BUILD.bazel @@ -4,6 +4,7 @@ CIMPLE_FILES = [ "//c-toxcore/toxav:cimple_files", "//c-toxcore/toxcore:cimple_files", "//c-toxcore/toxencryptsave:cimple_files", + "//c-toxcore/third_party:cimple_files", ] sh_test( @@ -40,7 +41,6 @@ sh_test( "-RTS", ], data = CIMPLE_FILES + [ - "//c-toxcore/third_party:headers", "//hs-tokstyle:headers", "@libsodium//:headers", "@libvpx//:headers", diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index 50537995..65ea8a9d 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -92,7 +92,7 @@ int main(int argc, char *argv[]) exit(0); } - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); Mono_Time *const mono_time = mono_time_new(mem, nullptr, nullptr); if (mono_time == nullptr) { @@ -103,7 +103,7 @@ int main(int argc, char *argv[]) Messenger_Options options = {0}; options.ipv6enabled = ipv6enabled; Messenger_Error err; - m = new_messenger(mono_time, mem, system_random(), system_network(), &options, &err); + m = new_messenger(mono_time, mem, os_random(), os_network(), &options, &err); if (!m) { fprintf(stderr, "Failed to allocate messenger datastructure: %d\n", err); @@ -120,8 +120,8 @@ int main(int argc, char *argv[]) const uint16_t port = net_htons((uint16_t)port_conv); uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]); - int res = dht_bootstrap_from_address(m->dht, argv[argvoffset + 1], - ipv6enabled, port, bootstrap_key); + bool res = dht_bootstrap_from_address(m->dht, argv[argvoffset + 1], + ipv6enabled, port, bootstrap_key); free(bootstrap_key); if (!res) { diff --git a/testing/fuzzing/BUILD.bazel b/testing/fuzzing/BUILD.bazel index 008a4313..ce23b792 100644 --- a/testing/fuzzing/BUILD.bazel +++ b/testing/fuzzing/BUILD.bazel @@ -4,10 +4,10 @@ load("@rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test") cc_library( name = "fuzz_support", srcs = [ - "func_conversion.h", + "func_conversion.hh", "fuzz_support.cc", ], - hdrs = ["fuzz_support.h"], + hdrs = ["fuzz_support.hh"], visibility = ["//c-toxcore:__subpackages__"], deps = [ "//c-toxcore/toxcore:crypto_core", @@ -18,7 +18,7 @@ cc_library( cc_library( name = "fuzz_tox", - hdrs = ["fuzz_tox.h"], + hdrs = ["fuzz_tox.hh"], visibility = ["//c-toxcore:__subpackages__"], deps = [":fuzz_support"], ) diff --git a/testing/fuzzing/CMakeLists.txt b/testing/fuzzing/CMakeLists.txt index 7efbb8c5..3ab9ecd9 100644 --- a/testing/fuzzing/CMakeLists.txt +++ b/testing/fuzzing/CMakeLists.txt @@ -1,5 +1,5 @@ # Override network and random functions -add_library(fuzz_support func_conversion.h fuzz_support.cc fuzz_support.h) +add_library(fuzz_support func_conversion.hh fuzz_support.cc fuzz_support.hh) set(LIBFUZZER_LINKER_FLAGS) if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") diff --git a/testing/fuzzing/bootstrap_fuzz_test.cc b/testing/fuzzing/bootstrap_fuzz_test.cc index 11b70b7d..f25e2431 100644 --- a/testing/fuzzing/bootstrap_fuzz_test.cc +++ b/testing/fuzzing/bootstrap_fuzz_test.cc @@ -4,83 +4,74 @@ #include "../../toxcore/tox.h" #include "../../toxcore/tox_dispatch.h" #include "../../toxcore/tox_events.h" -#include "fuzz_support.h" -#include "fuzz_tox.h" +#include "fuzz_support.hh" +#include "fuzz_tox.hh" namespace { void setup_callbacks(Tox_Dispatch *dispatch) { tox_events_callback_conference_connected( - dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Connected *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_conference_connected( - dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Connected *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_conference_invite( - dispatch, [](Tox *tox, const Tox_Event_Conference_Invite *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Invite *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_conference_message( - dispatch, [](Tox *tox, const Tox_Event_Conference_Message *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Message *event, void *user_data) { assert(event == nullptr); }); - tox_events_callback_conference_peer_list_changed(dispatch, - [](Tox *tox, const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) { + tox_events_callback_conference_peer_list_changed( + dispatch, [](const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_conference_peer_name( - dispatch, [](Tox *tox, const Tox_Event_Conference_Peer_Name *event, void *user_data) { - assert(event == nullptr); - }); - tox_events_callback_conference_title( - dispatch, [](Tox *tox, const Tox_Event_Conference_Title *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Peer_Name *event, void *user_data) { assert(event == nullptr); }); + tox_events_callback_conference_title(dispatch, + [](const Tox_Event_Conference_Title *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_file_chunk_request( - dispatch, [](Tox *tox, const Tox_Event_File_Chunk_Request *event, void *user_data) { - assert(event == nullptr); - }); - tox_events_callback_file_recv( - dispatch, [](Tox *tox, const Tox_Event_File_Recv *event, void *user_data) { - assert(event == nullptr); - }); - tox_events_callback_file_recv_chunk( - dispatch, [](Tox *tox, const Tox_Event_File_Recv_Chunk *event, void *user_data) { + dispatch, [](const Tox_Event_File_Chunk_Request *event, void *user_data) { assert(event == nullptr); }); + tox_events_callback_file_recv(dispatch, + [](const Tox_Event_File_Recv *event, void *user_data) { assert(event == nullptr); }); + tox_events_callback_file_recv_chunk(dispatch, + [](const Tox_Event_File_Recv_Chunk *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_file_recv_control( - dispatch, [](Tox *tox, const Tox_Event_File_Recv_Control *event, void *user_data) { + dispatch, [](const Tox_Event_File_Recv_Control *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_friend_connection_status( - dispatch, [](Tox *tox, const Tox_Event_Friend_Connection_Status *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Connection_Status *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_friend_lossless_packet( - dispatch, [](Tox *tox, const Tox_Event_Friend_Lossless_Packet *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Lossless_Packet *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_friend_lossy_packet( - dispatch, [](Tox *tox, const Tox_Event_Friend_Lossy_Packet *event, void *user_data) { - assert(event == nullptr); - }); - tox_events_callback_friend_message( - dispatch, [](Tox *tox, const Tox_Event_Friend_Message *event, void *user_data) { - assert(event == nullptr); - }); - tox_events_callback_friend_name( - dispatch, [](Tox *tox, const Tox_Event_Friend_Name *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Lossy_Packet *event, void *user_data) { assert(event == nullptr); }); + tox_events_callback_friend_message(dispatch, + [](const Tox_Event_Friend_Message *event, void *user_data) { assert(event == nullptr); }); + tox_events_callback_friend_name(dispatch, + [](const Tox_Event_Friend_Name *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_friend_read_receipt( - dispatch, [](Tox *tox, const Tox_Event_Friend_Read_Receipt *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Read_Receipt *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_friend_request( - dispatch, [](Tox *tox, const Tox_Event_Friend_Request *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Request *event, void *user_data) { + Tox *tox = static_cast(user_data); Tox_Err_Friend_Add err; tox_friend_add_norequest(tox, tox_event_friend_request_get_public_key(event), &err); if (!(err == TOX_ERR_FRIEND_ADD_OK || err == TOX_ERR_FRIEND_ADD_OWN_KEY @@ -90,20 +81,16 @@ void setup_callbacks(Tox_Dispatch *dispatch) printf("unexpected error: %s\n", tox_err_friend_add_to_string(err)); } }); - tox_events_callback_friend_status( - dispatch, [](Tox *tox, const Tox_Event_Friend_Status *event, void *user_data) { - assert(event == nullptr); - }); + tox_events_callback_friend_status(dispatch, + [](const Tox_Event_Friend_Status *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_friend_status_message( - dispatch, [](Tox *tox, const Tox_Event_Friend_Status_Message *event, void *user_data) { - assert(event == nullptr); - }); - tox_events_callback_friend_typing( - dispatch, [](Tox *tox, const Tox_Event_Friend_Typing *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Status_Message *event, void *user_data) { assert(event == nullptr); }); + tox_events_callback_friend_typing(dispatch, + [](const Tox_Event_Friend_Typing *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_self_connection_status( - dispatch, [](Tox *tox, const Tox_Event_Self_Connection_Status *event, void *user_data) { + dispatch, [](const Tox_Event_Self_Connection_Status *event, void *user_data) { assert(event == nullptr); }); } @@ -174,7 +161,7 @@ void TestBootstrap(Fuzz_Data &input) Tox_Err_Events_Iterate error_iterate; Tox_Events *events = tox_events_iterate(tox, true, &error_iterate); assert(tox_events_equal(null_sys.sys.get(), events, events)); - tox_dispatch_invoke(dispatch, events, tox, nullptr); + tox_dispatch_invoke(dispatch, events, tox); tox_events_free(events); // Move the clock forward a decent amount so all the time-based checks // trigger more quickly. diff --git a/testing/fuzzing/e2e_fuzz_test.cc b/testing/fuzzing/e2e_fuzz_test.cc index 40634270..1be228e0 100644 --- a/testing/fuzzing/e2e_fuzz_test.cc +++ b/testing/fuzzing/e2e_fuzz_test.cc @@ -12,71 +12,69 @@ #include "../../toxcore/tox.h" #include "../../toxcore/tox_dispatch.h" #include "../../toxcore/tox_events.h" -#include "fuzz_support.h" -#include "fuzz_tox.h" +#include "fuzz_support.hh" +#include "fuzz_tox.hh" namespace { void setup_callbacks(Tox_Dispatch *dispatch) { tox_events_callback_conference_connected( - dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Connected *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_conference_connected( - dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Connected *event, void *user_data) { assert(event != nullptr); }); tox_events_callback_conference_invite( - dispatch, [](Tox *tox, const Tox_Event_Conference_Invite *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Invite *event, void *user_data) { + Tox *tox = static_cast(user_data); const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event); const uint8_t *cookie = tox_event_conference_invite_get_cookie(event); const uint32_t cookie_length = tox_event_conference_invite_get_cookie_length(event); tox_conference_join(tox, friend_number, cookie, cookie_length, nullptr); }); tox_events_callback_conference_message( - dispatch, [](Tox *tox, const Tox_Event_Conference_Message *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Message *event, void *user_data) { assert(event != nullptr); }); - tox_events_callback_conference_peer_list_changed(dispatch, - [](Tox *tox, const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) { + tox_events_callback_conference_peer_list_changed( + dispatch, [](const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) { assert(event != nullptr); }); tox_events_callback_conference_peer_name( - dispatch, [](Tox *tox, const Tox_Event_Conference_Peer_Name *event, void *user_data) { - assert(event != nullptr); - }); - tox_events_callback_conference_title( - dispatch, [](Tox *tox, const Tox_Event_Conference_Title *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Peer_Name *event, void *user_data) { assert(event != nullptr); }); + tox_events_callback_conference_title(dispatch, + [](const Tox_Event_Conference_Title *event, void *user_data) { assert(event != nullptr); }); tox_events_callback_file_chunk_request( - dispatch, [](Tox *tox, const Tox_Event_File_Chunk_Request *event, void *user_data) { + dispatch, [](const Tox_Event_File_Chunk_Request *event, void *user_data) { assert(event == nullptr); }); - tox_events_callback_file_recv( - dispatch, [](Tox *tox, const Tox_Event_File_Recv *event, void *user_data) { - const uint32_t friend_number = tox_event_file_recv_get_friend_number(event); - const uint32_t file_number = tox_event_file_recv_get_file_number(event); - tox_file_control(tox, friend_number, file_number, TOX_FILE_CONTROL_RESUME, nullptr); - }); - tox_events_callback_file_recv_chunk( - dispatch, [](Tox *tox, const Tox_Event_File_Recv_Chunk *event, void *user_data) { - assert(event != nullptr); - }); + tox_events_callback_file_recv(dispatch, [](const Tox_Event_File_Recv *event, void *user_data) { + Tox *tox = static_cast(user_data); + const uint32_t friend_number = tox_event_file_recv_get_friend_number(event); + const uint32_t file_number = tox_event_file_recv_get_file_number(event); + tox_file_control(tox, friend_number, file_number, TOX_FILE_CONTROL_RESUME, nullptr); + }); + tox_events_callback_file_recv_chunk(dispatch, + [](const Tox_Event_File_Recv_Chunk *event, void *user_data) { assert(event != nullptr); }); tox_events_callback_file_recv_control( - dispatch, [](Tox *tox, const Tox_Event_File_Recv_Control *event, void *user_data) { + dispatch, [](const Tox_Event_File_Recv_Control *event, void *user_data) { assert(event != nullptr); }); tox_events_callback_friend_connection_status( - dispatch, [](Tox *tox, const Tox_Event_Friend_Connection_Status *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Connection_Status *event, void *user_data) { // OK: friend came online. const uint32_t friend_number = tox_event_friend_connection_status_get_friend_number(event); assert(friend_number != UINT32_MAX); }); tox_events_callback_friend_lossless_packet( - dispatch, [](Tox *tox, const Tox_Event_Friend_Lossless_Packet *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Lossless_Packet *event, void *user_data) { + Tox *tox = static_cast(user_data); const uint32_t friend_number = tox_event_friend_lossless_packet_get_friend_number(event); const uint32_t data_length = tox_event_friend_lossless_packet_get_data_length(event); @@ -84,14 +82,16 @@ void setup_callbacks(Tox_Dispatch *dispatch) tox_friend_send_lossless_packet(tox, friend_number, data, data_length, nullptr); }); tox_events_callback_friend_lossy_packet( - dispatch, [](Tox *tox, const Tox_Event_Friend_Lossy_Packet *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Lossy_Packet *event, void *user_data) { + Tox *tox = static_cast(user_data); const uint32_t friend_number = tox_event_friend_lossy_packet_get_friend_number(event); const uint32_t data_length = tox_event_friend_lossy_packet_get_data_length(event); const uint8_t *data = tox_event_friend_lossy_packet_get_data(event); tox_friend_send_lossy_packet(tox, friend_number, data, data_length, nullptr); }); tox_events_callback_friend_message( - dispatch, [](Tox *tox, const Tox_Event_Friend_Message *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Message *event, void *user_data) { + Tox *tox = static_cast(user_data); const uint32_t friend_number = tox_event_friend_message_get_friend_number(event); const Tox_Message_Type type = tox_event_friend_message_get_type(event); const uint32_t message_length = tox_event_friend_message_get_message_length(event); @@ -99,32 +99,33 @@ void setup_callbacks(Tox_Dispatch *dispatch) tox_friend_send_message(tox, friend_number, type, message, message_length, nullptr); }); tox_events_callback_friend_name( - dispatch, [](Tox *tox, const Tox_Event_Friend_Name *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Name *event, void *user_data) { // OK: friend name received. }); tox_events_callback_friend_read_receipt( - dispatch, [](Tox *tox, const Tox_Event_Friend_Read_Receipt *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Read_Receipt *event, void *user_data) { // OK: message has been received. }); tox_events_callback_friend_request( - dispatch, [](Tox *tox, const Tox_Event_Friend_Request *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Request *event, void *user_data) { + Tox *tox = static_cast(user_data); Tox_Err_Friend_Add err; tox_friend_add_norequest(tox, tox_event_friend_request_get_public_key(event), &err); }); tox_events_callback_friend_status( - dispatch, [](Tox *tox, const Tox_Event_Friend_Status *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Status *event, void *user_data) { // OK: friend status received. }); tox_events_callback_friend_status_message( - dispatch, [](Tox *tox, const Tox_Event_Friend_Status_Message *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Status_Message *event, void *user_data) { // OK: friend status message received. }); tox_events_callback_friend_typing( - dispatch, [](Tox *tox, const Tox_Event_Friend_Typing *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Typing *event, void *user_data) { // OK: friend may be typing. }); tox_events_callback_self_connection_status( - dispatch, [](Tox *tox, const Tox_Event_Self_Connection_Status *event, void *user_data) { + dispatch, [](const Tox_Event_Self_Connection_Status *event, void *user_data) { // OK: we got connected. }); } @@ -171,7 +172,7 @@ void TestEndToEnd(Fuzz_Data &input) Tox_Err_Events_Iterate error_iterate; Tox_Events *events = tox_events_iterate(tox, true, &error_iterate); assert(tox_events_equal(null_sys.sys.get(), events, events)); - tox_dispatch_invoke(dispatch, events, tox, nullptr); + tox_dispatch_invoke(dispatch, events, tox); tox_events_free(events); // Move the clock forward a decent amount so all the time-based checks // trigger more quickly. diff --git a/testing/fuzzing/func_conversion.h b/testing/fuzzing/func_conversion.hh similarity index 100% rename from testing/fuzzing/func_conversion.h rename to testing/fuzzing/func_conversion.hh diff --git a/testing/fuzzing/fuzz_support.cc b/testing/fuzzing/fuzz_support.cc index fd6b9c43..fe760f99 100644 --- a/testing/fuzzing/fuzz_support.cc +++ b/testing/fuzzing/fuzz_support.cc @@ -2,7 +2,7 @@ * Copyright © 2021-2022 The TokTok team. */ -#include "fuzz_support.h" +#include "fuzz_support.hh" #include #include @@ -18,7 +18,7 @@ #include "../../toxcore/crypto_core.h" #include "../../toxcore/network.h" #include "../../toxcore/tox_private.h" -#include "func_conversion.h" +#include "func_conversion.hh" // TODO(iphydf): Put this somewhere shared. struct Network_Addr { @@ -107,25 +107,25 @@ static constexpr Memory_Funcs fuzz_memory_funcs = { }; static constexpr Network_Funcs fuzz_network_funcs = { - /* .close = */ ![](Fuzz_System *self, int sock) { return 0; }, - /* .accept = */ ![](Fuzz_System *self, int sock) { return 1337; }, - /* .bind = */ ![](Fuzz_System *self, int sock, const Network_Addr *addr) { return 0; }, - /* .listen = */ ![](Fuzz_System *self, int sock, int backlog) { return 0; }, + /* .close = */ ![](Fuzz_System *self, Socket sock) { return 0; }, + /* .accept = */ ![](Fuzz_System *self, Socket sock) { return Socket{1337}; }, + /* .bind = */ ![](Fuzz_System *self, Socket sock, const Network_Addr *addr) { return 0; }, + /* .listen = */ ![](Fuzz_System *self, Socket sock, int backlog) { return 0; }, /* .recvbuf = */ - ![](Fuzz_System *self, int sock) { - assert(sock == 42 || sock == 1337); + ![](Fuzz_System *self, Socket sock) { + assert(sock.value == 42 || sock.value == 1337); const size_t count = random_u16(self->rng.get()); return static_cast(std::min(count, self->data.size())); }, /* .recv = */ - ![](Fuzz_System *self, int sock, uint8_t *buf, size_t len) { - assert(sock == 42 || sock == 1337); + ![](Fuzz_System *self, Socket sock, uint8_t *buf, size_t len) { + assert(sock.value == 42 || sock.value == 1337); // Receive data from the fuzzer. return recv_common(self->data, buf, len); }, /* .recvfrom = */ - ![](Fuzz_System *self, int sock, uint8_t *buf, size_t len, Network_Addr *addr) { - assert(sock == 42 || sock == 1337); + ![](Fuzz_System *self, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) { + assert(sock.value == 42 || sock.value == 1337); addr->addr = sockaddr_storage{}; // Dummy Addr @@ -140,26 +140,26 @@ static constexpr Network_Funcs fuzz_network_funcs = { return recv_common(self->data, buf, len); }, /* .send = */ - ![](Fuzz_System *self, int sock, const uint8_t *buf, size_t len) { - assert(sock == 42 || sock == 1337); + ![](Fuzz_System *self, Socket sock, const uint8_t *buf, size_t len) { + assert(sock.value == 42 || sock.value == 1337); // Always succeed. return static_cast(len); }, /* .sendto = */ - ![](Fuzz_System *self, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr) { - assert(sock == 42 || sock == 1337); + ![](Fuzz_System *self, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr) { + assert(sock.value == 42 || sock.value == 1337); // Always succeed. return static_cast(len); }, - /* .socket = */ ![](Fuzz_System *self, int domain, int type, int proto) { return 42; }, - /* .socket_nonblock = */ ![](Fuzz_System *self, int sock, bool nonblock) { return 0; }, + /* .socket = */ ![](Fuzz_System *self, int domain, int type, int proto) { return Socket{42}; }, + /* .socket_nonblock = */ ![](Fuzz_System *self, Socket sock, bool nonblock) { return 0; }, /* .getsockopt = */ - ![](Fuzz_System *self, int sock, int level, int optname, void *optval, size_t *optlen) { + ![](Fuzz_System *self, Socket sock, int level, int optname, void *optval, size_t *optlen) { std::memset(optval, 0, *optlen); return 0; }, /* .setsockopt = */ - ![](Fuzz_System *self, int sock, int level, int optname, const void *optval, size_t optlen) { + ![](Fuzz_System *self, Socket sock, int level, int optname, const void *optval, size_t optlen) { return 0; }, }; @@ -221,42 +221,42 @@ static constexpr Memory_Funcs null_memory_funcs = { }; static constexpr Network_Funcs null_network_funcs = { - /* .close = */ ![](Null_System *self, int sock) { return 0; }, - /* .accept = */ ![](Null_System *self, int sock) { return 1337; }, - /* .bind = */ ![](Null_System *self, int sock, const Network_Addr *addr) { return 0; }, - /* .listen = */ ![](Null_System *self, int sock, int backlog) { return 0; }, - /* .recvbuf = */ ![](Null_System *self, int sock) { return 0; }, + /* .close = */ ![](Null_System *self, Socket sock) { return 0; }, + /* .accept = */ ![](Null_System *self, Socket sock) { return Socket{1337}; }, + /* .bind = */ ![](Null_System *self, Socket sock, const Network_Addr *addr) { return 0; }, + /* .listen = */ ![](Null_System *self, Socket sock, int backlog) { return 0; }, + /* .recvbuf = */ ![](Null_System *self, Socket sock) { return 0; }, /* .recv = */ - ![](Null_System *self, int sock, uint8_t *buf, size_t len) { + ![](Null_System *self, Socket sock, uint8_t *buf, size_t len) { // Always fail. errno = ENOMEM; return -1; }, /* .recvfrom = */ - ![](Null_System *self, int sock, uint8_t *buf, size_t len, Network_Addr *addr) { + ![](Null_System *self, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) { // Always fail. errno = ENOMEM; return -1; }, /* .send = */ - ![](Null_System *self, int sock, const uint8_t *buf, size_t len) { + ![](Null_System *self, Socket sock, const uint8_t *buf, size_t len) { // Always succeed. return static_cast(len); }, /* .sendto = */ - ![](Null_System *self, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr) { + ![](Null_System *self, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr) { // Always succeed. return static_cast(len); }, - /* .socket = */ ![](Null_System *self, int domain, int type, int proto) { return 42; }, - /* .socket_nonblock = */ ![](Null_System *self, int sock, bool nonblock) { return 0; }, + /* .socket = */ ![](Null_System *self, int domain, int type, int proto) { return Socket{42}; }, + /* .socket_nonblock = */ ![](Null_System *self, Socket sock, bool nonblock) { return 0; }, /* .getsockopt = */ - ![](Null_System *self, int sock, int level, int optname, void *optval, size_t *optlen) { + ![](Null_System *self, Socket sock, int level, int optname, void *optval, size_t *optlen) { std::memset(optval, 0, *optlen); return 0; }, /* .setsockopt = */ - ![](Null_System *self, int sock, int level, int optname, const void *optval, size_t optlen) { + ![](Null_System *self, Socket sock, int level, int optname, const void *optval, size_t optlen) { return 0; }, }; @@ -327,10 +327,10 @@ static constexpr Memory_Funcs record_memory_funcs = { }; static constexpr Network_Funcs record_network_funcs = { - /* .close = */ ![](Record_System *self, int sock) { return 0; }, - /* .accept = */ ![](Record_System *self, int sock) { return 2; }, + /* .close = */ ![](Record_System *self, Socket sock) { return 0; }, + /* .accept = */ ![](Record_System *self, Socket sock) { return Socket{2}; }, /* .bind = */ - ![](Record_System *self, int sock, const Network_Addr *addr) { + ![](Record_System *self, Socket sock, const Network_Addr *addr) { const uint16_t port = get_port(addr); if (self->global_.bound.find(port) != self->global_.bound.end()) { errno = EADDRINUSE; @@ -340,17 +340,17 @@ static constexpr Network_Funcs record_network_funcs = { self->port = port; return 0; }, - /* .listen = */ ![](Record_System *self, int sock, int backlog) { return 0; }, - /* .recvbuf = */ ![](Record_System *self, int sock) { return 0; }, + /* .listen = */ ![](Record_System *self, Socket sock, int backlog) { return 0; }, + /* .recvbuf = */ ![](Record_System *self, Socket sock) { return 0; }, /* .recv = */ - ![](Record_System *self, int sock, uint8_t *buf, size_t len) { + ![](Record_System *self, Socket sock, uint8_t *buf, size_t len) { // Always fail. errno = ENOMEM; return -1; }, /* .recvfrom = */ - ![](Record_System *self, int sock, uint8_t *buf, size_t len, Network_Addr *addr) { - assert(sock == 42); + ![](Record_System *self, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) { + assert(sock.value == 42); if (self->recvq.empty()) { self->push("\xff\xff"); errno = EWOULDBLOCK; @@ -385,29 +385,30 @@ static constexpr Network_Funcs record_network_funcs = { return static_cast(recvlen); }, /* .send = */ - ![](Record_System *self, int sock, const uint8_t *buf, size_t len) { + ![](Record_System *self, Socket sock, const uint8_t *buf, size_t len) { // Always succeed. return static_cast(len); }, /* .sendto = */ - ![](Record_System *self, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr) { - assert(sock == 42); + ![](Record_System *self, Socket sock, const uint8_t *buf, size_t len, + const Network_Addr *addr) { + assert(sock.value == 42); auto backend = self->global_.bound.find(get_port(addr)); assert(backend != self->global_.bound.end()); backend->second->receive(self->port, buf, len); return static_cast(len); }, - /* .socket = */ ![](Record_System *self, int domain, int type, int proto) { return 42; }, - /* .socket_nonblock = */ ![](Record_System *self, int sock, bool nonblock) { return 0; }, + /* .socket = */ + ![](Record_System *self, int domain, int type, int proto) { return Socket{42}; }, + /* .socket_nonblock = */ ![](Record_System *self, Socket sock, bool nonblock) { return 0; }, /* .getsockopt = */ - ![](Record_System *self, int sock, int level, int optname, void *optval, size_t *optlen) { + ![](Record_System *self, Socket sock, int level, int optname, void *optval, size_t *optlen) { std::memset(optval, 0, *optlen); return 0; }, /* .setsockopt = */ - ![](Record_System *self, int sock, int level, int optname, const void *optval, size_t optlen) { - return 0; - }, + ![](Record_System *self, Socket sock, int level, int optname, const void *optval, + size_t optlen) { return 0; }, }; static constexpr Random_Funcs record_random_funcs = { diff --git a/testing/fuzzing/fuzz_support.h b/testing/fuzzing/fuzz_support.hh similarity index 98% rename from testing/fuzzing/fuzz_support.h rename to testing/fuzzing/fuzz_support.hh index 01e472c5..7f03d341 100644 --- a/testing/fuzzing/fuzz_support.h +++ b/testing/fuzzing/fuzz_support.hh @@ -19,7 +19,7 @@ struct Fuzz_Data { static constexpr bool DEBUG = false; - static constexpr std::size_t TRACE_TRAP = -1; // 579; + static constexpr std::size_t TRACE_TRAP = -1; // 579; private: const uint8_t *data_; @@ -303,7 +303,8 @@ struct Record_System : System { if (recording_.size() == Fuzz_Data::TRACE_TRAP) { __asm__("int $3"); } - std::printf("%s: produce@%zu(bool %s)\n", name_, recording_.size(), byte ? "true" : "false"); + std::printf( + "%s: produce@%zu(bool %s)\n", name_, recording_.size(), byte ? "true" : "false"); } recording_.push_back(byte); } diff --git a/testing/fuzzing/fuzz_tox.h b/testing/fuzzing/fuzz_tox.hh similarity index 100% rename from testing/fuzzing/fuzz_tox.h rename to testing/fuzzing/fuzz_tox.hh diff --git a/testing/fuzzing/protodump.cc b/testing/fuzzing/protodump.cc index 70ab6c80..1a3f8c07 100644 --- a/testing/fuzzing/protodump.cc +++ b/testing/fuzzing/protodump.cc @@ -33,7 +33,7 @@ #include "../../toxcore/tox_private.h" #include "../../toxcore/tox_struct.h" #include "../../toxcore/util.h" -#include "fuzz_support.h" +#include "fuzz_support.hh" namespace { @@ -45,73 +45,75 @@ namespace { */ constexpr uint32_t MESSAGE_COUNT = 5; +struct State { + Tox *tox; + uint32_t done; +}; + void setup_callbacks(Tox_Dispatch *dispatch) { tox_events_callback_conference_connected( - dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Connected *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_conference_connected( - dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Connected *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_conference_invite( - dispatch, [](Tox *tox, const Tox_Event_Conference_Invite *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Invite *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_conference_message( - dispatch, [](Tox *tox, const Tox_Event_Conference_Message *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Message *event, void *user_data) { assert(event == nullptr); }); - tox_events_callback_conference_peer_list_changed(dispatch, - [](Tox *tox, const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) { + tox_events_callback_conference_peer_list_changed( + dispatch, [](const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_conference_peer_name( - dispatch, [](Tox *tox, const Tox_Event_Conference_Peer_Name *event, void *user_data) { - assert(event == nullptr); - }); - tox_events_callback_conference_title( - dispatch, [](Tox *tox, const Tox_Event_Conference_Title *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Peer_Name *event, void *user_data) { assert(event == nullptr); }); + tox_events_callback_conference_title(dispatch, + [](const Tox_Event_Conference_Title *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_file_chunk_request( - dispatch, [](Tox *tox, const Tox_Event_File_Chunk_Request *event, void *user_data) { - assert(event == nullptr); - }); - tox_events_callback_file_recv( - dispatch, [](Tox *tox, const Tox_Event_File_Recv *event, void *user_data) { - assert(event == nullptr); - }); - tox_events_callback_file_recv_chunk( - dispatch, [](Tox *tox, const Tox_Event_File_Recv_Chunk *event, void *user_data) { + dispatch, [](const Tox_Event_File_Chunk_Request *event, void *user_data) { assert(event == nullptr); }); + tox_events_callback_file_recv(dispatch, + [](const Tox_Event_File_Recv *event, void *user_data) { assert(event == nullptr); }); + tox_events_callback_file_recv_chunk(dispatch, + [](const Tox_Event_File_Recv_Chunk *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_file_recv_control( - dispatch, [](Tox *tox, const Tox_Event_File_Recv_Control *event, void *user_data) { + dispatch, [](const Tox_Event_File_Recv_Control *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_friend_connection_status( - dispatch, [](Tox *tox, const Tox_Event_Friend_Connection_Status *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Connection_Status *event, void *user_data) { + State *state = static_cast(user_data); // OK: friend came online. const uint32_t friend_number = tox_event_friend_connection_status_get_friend_number(event); assert(friend_number == 0); const uint8_t message = 'A'; Tox_Err_Friend_Send_Message err; - tox_friend_send_message(tox, friend_number, TOX_MESSAGE_TYPE_NORMAL, &message, 1, &err); + tox_friend_send_message( + state->tox, friend_number, TOX_MESSAGE_TYPE_NORMAL, &message, 1, &err); assert(err == TOX_ERR_FRIEND_SEND_MESSAGE_OK); }); tox_events_callback_friend_lossless_packet( - dispatch, [](Tox *tox, const Tox_Event_Friend_Lossless_Packet *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Lossless_Packet *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_friend_lossy_packet( - dispatch, [](Tox *tox, const Tox_Event_Friend_Lossy_Packet *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Lossy_Packet *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_friend_message( - dispatch, [](Tox *tox, const Tox_Event_Friend_Message *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Message *event, void *user_data) { + State *state = static_cast(user_data); const uint32_t friend_number = tox_event_friend_message_get_friend_number(event); assert(friend_number == 0); const uint32_t message_length = tox_event_friend_message_get_message_length(event); @@ -119,48 +121,51 @@ void setup_callbacks(Tox_Dispatch *dispatch) const uint8_t *message = tox_event_friend_message_get_message(event); const uint8_t reply = message[0] + 1; Tox_Err_Friend_Send_Message err; - tox_friend_send_message(tox, friend_number, TOX_MESSAGE_TYPE_NORMAL, &reply, 1, &err); + tox_friend_send_message( + state->tox, friend_number, TOX_MESSAGE_TYPE_NORMAL, &reply, 1, &err); assert(err == TOX_ERR_FRIEND_SEND_MESSAGE_OK); }); tox_events_callback_friend_name( - dispatch, [](Tox *tox, const Tox_Event_Friend_Name *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Name *event, void *user_data) { const uint32_t friend_number = tox_event_friend_name_get_friend_number(event); assert(friend_number == 0); }); tox_events_callback_friend_read_receipt( - dispatch, [](Tox *tox, const Tox_Event_Friend_Read_Receipt *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Read_Receipt *event, void *user_data) { + State *state = static_cast(user_data); const uint32_t friend_number = tox_event_friend_read_receipt_get_friend_number(event); assert(friend_number == 0); const uint32_t message_id = tox_event_friend_read_receipt_get_message_id(event); - uint32_t *done = static_cast(user_data); - *done = std::max(*done, message_id); + state->done = std::max(state->done, message_id); }); tox_events_callback_friend_request( - dispatch, [](Tox *tox, const Tox_Event_Friend_Request *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Request *event, void *user_data) { + State *state = static_cast(user_data); Tox_Err_Friend_Add err; - tox_friend_add_norequest(tox, tox_event_friend_request_get_public_key(event), &err); + tox_friend_add_norequest( + state->tox, tox_event_friend_request_get_public_key(event), &err); assert(err == TOX_ERR_FRIEND_ADD_OK || err == TOX_ERR_FRIEND_ADD_OWN_KEY || err == TOX_ERR_FRIEND_ADD_ALREADY_SENT || err == TOX_ERR_FRIEND_ADD_BAD_CHECKSUM); }); tox_events_callback_friend_status( - dispatch, [](Tox *tox, const Tox_Event_Friend_Status *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Status *event, void *user_data) { const uint32_t friend_number = tox_event_friend_status_get_friend_number(event); assert(friend_number == 0); }); tox_events_callback_friend_status_message( - dispatch, [](Tox *tox, const Tox_Event_Friend_Status_Message *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Status_Message *event, void *user_data) { const uint32_t friend_number = tox_event_friend_status_message_get_friend_number(event); assert(friend_number == 0); }); tox_events_callback_friend_typing( - dispatch, [](Tox *tox, const Tox_Event_Friend_Typing *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Typing *event, void *user_data) { const uint32_t friend_number = tox_event_friend_typing_get_friend_number(event); assert(friend_number == 0); assert(!tox_event_friend_typing_get_typing(event)); }); tox_events_callback_self_connection_status( - dispatch, [](Tox *tox, const Tox_Event_Self_Connection_Status *event, void *user_data) { + dispatch, [](const Tox_Event_Self_Connection_Status *event, void *user_data) { // OK: we got connected. }); } @@ -235,8 +240,8 @@ void RecordBootstrap(const char *init, const char *bootstrap) assert(dispatch != nullptr); setup_callbacks(dispatch); - uint32_t done1 = 0; - uint32_t done2 = 0; + State state1 = {tox1, 0}; + State state2 = {tox2, 0}; const auto iterate = [&](uint8_t clock_increment) { Tox_Err_Events_Iterate error_iterate; @@ -244,12 +249,12 @@ void RecordBootstrap(const char *init, const char *bootstrap) events = tox_events_iterate(tox1, true, &error_iterate); assert(tox_events_equal(sys1.sys.get(), events, events)); - tox_dispatch_invoke(dispatch, events, tox1, &done1); + 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)); - tox_dispatch_invoke(dispatch, events, tox2, &done2); + tox_dispatch_invoke(dispatch, events, &state2); tox_events_free(events); // Move the clock forward a decent amount so all the time-based checks @@ -295,7 +300,7 @@ void RecordBootstrap(const char *init, const char *bootstrap) dump(sys1.take_recording(), init); - while (done1 < MESSAGE_COUNT && done2 < MESSAGE_COUNT) { + while (state1.done < MESSAGE_COUNT && state2.done < MESSAGE_COUNT) { if (Fuzz_Data::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), diff --git a/testing/fuzzing/protodump_reduce.cc b/testing/fuzzing/protodump_reduce.cc index d824bdac..ae9676ca 100644 --- a/testing/fuzzing/protodump_reduce.cc +++ b/testing/fuzzing/protodump_reduce.cc @@ -6,8 +6,8 @@ #include "../../toxcore/tox_dispatch.h" #include "../../toxcore/tox_events.h" #include "../../toxcore/tox_private.h" -#include "fuzz_support.h" -#include "fuzz_tox.h" +#include "fuzz_support.hh" +#include "fuzz_tox.hh" namespace { @@ -16,51 +16,46 @@ constexpr bool PROTODUMP_DEBUG = Fuzz_Data::DEBUG; void setup_callbacks(Tox_Dispatch *dispatch) { tox_events_callback_conference_connected( - dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Connected *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_conference_connected( - dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Connected *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_conference_invite( - dispatch, [](Tox *tox, const Tox_Event_Conference_Invite *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Invite *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_conference_message( - dispatch, [](Tox *tox, const Tox_Event_Conference_Message *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Message *event, void *user_data) { assert(event == nullptr); }); - tox_events_callback_conference_peer_list_changed(dispatch, - [](Tox *tox, const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) { + tox_events_callback_conference_peer_list_changed( + dispatch, [](const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_conference_peer_name( - dispatch, [](Tox *tox, const Tox_Event_Conference_Peer_Name *event, void *user_data) { - assert(event == nullptr); - }); - tox_events_callback_conference_title( - dispatch, [](Tox *tox, const Tox_Event_Conference_Title *event, void *user_data) { + dispatch, [](const Tox_Event_Conference_Peer_Name *event, void *user_data) { assert(event == nullptr); }); + tox_events_callback_conference_title(dispatch, + [](const Tox_Event_Conference_Title *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_file_chunk_request( - dispatch, [](Tox *tox, const Tox_Event_File_Chunk_Request *event, void *user_data) { - assert(event == nullptr); - }); - tox_events_callback_file_recv( - dispatch, [](Tox *tox, const Tox_Event_File_Recv *event, void *user_data) { - assert(event == nullptr); - }); - tox_events_callback_file_recv_chunk( - dispatch, [](Tox *tox, const Tox_Event_File_Recv_Chunk *event, void *user_data) { + dispatch, [](const Tox_Event_File_Chunk_Request *event, void *user_data) { assert(event == nullptr); }); + tox_events_callback_file_recv(dispatch, + [](const Tox_Event_File_Recv *event, void *user_data) { assert(event == nullptr); }); + tox_events_callback_file_recv_chunk(dispatch, + [](const Tox_Event_File_Recv_Chunk *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_file_recv_control( - dispatch, [](Tox *tox, const Tox_Event_File_Recv_Control *event, void *user_data) { + dispatch, [](const Tox_Event_File_Recv_Control *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_friend_connection_status( - dispatch, [](Tox *tox, const Tox_Event_Friend_Connection_Status *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Connection_Status *event, void *user_data) { + Tox *tox = static_cast(user_data); // OK: friend came online. const uint32_t friend_number = tox_event_friend_connection_status_get_friend_number(event); @@ -71,15 +66,16 @@ void setup_callbacks(Tox_Dispatch *dispatch) assert(err == TOX_ERR_FRIEND_SEND_MESSAGE_OK); }); tox_events_callback_friend_lossless_packet( - dispatch, [](Tox *tox, const Tox_Event_Friend_Lossless_Packet *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Lossless_Packet *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_friend_lossy_packet( - dispatch, [](Tox *tox, const Tox_Event_Friend_Lossy_Packet *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Lossy_Packet *event, void *user_data) { assert(event == nullptr); }); tox_events_callback_friend_message( - dispatch, [](Tox *tox, const Tox_Event_Friend_Message *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Message *event, void *user_data) { + Tox *tox = static_cast(user_data); const uint32_t friend_number = tox_event_friend_message_get_friend_number(event); assert(friend_number == 0); const uint32_t message_length = tox_event_friend_message_get_message_length(event); @@ -91,12 +87,12 @@ void setup_callbacks(Tox_Dispatch *dispatch) assert(err == TOX_ERR_FRIEND_SEND_MESSAGE_OK); }); tox_events_callback_friend_name( - dispatch, [](Tox *tox, const Tox_Event_Friend_Name *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Name *event, void *user_data) { const uint32_t friend_number = tox_event_friend_name_get_friend_number(event); assert(friend_number == 0); }); tox_events_callback_friend_read_receipt( - dispatch, [](Tox *tox, const Tox_Event_Friend_Read_Receipt *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Read_Receipt *event, void *user_data) { const uint32_t friend_number = tox_event_friend_read_receipt_get_friend_number(event); assert(friend_number == 0); const uint32_t message_id = tox_event_friend_read_receipt_get_message_id(event); @@ -104,28 +100,29 @@ void setup_callbacks(Tox_Dispatch *dispatch) *done = std::max(*done, message_id); }); tox_events_callback_friend_request( - dispatch, [](Tox *tox, const Tox_Event_Friend_Request *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Request *event, void *user_data) { + Tox *tox = static_cast(user_data); Tox_Err_Friend_Add err; tox_friend_add_norequest(tox, tox_event_friend_request_get_public_key(event), &err); }); tox_events_callback_friend_status( - dispatch, [](Tox *tox, const Tox_Event_Friend_Status *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Status *event, void *user_data) { const uint32_t friend_number = tox_event_friend_status_get_friend_number(event); assert(friend_number == 0); }); tox_events_callback_friend_status_message( - dispatch, [](Tox *tox, const Tox_Event_Friend_Status_Message *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Status_Message *event, void *user_data) { const uint32_t friend_number = tox_event_friend_status_message_get_friend_number(event); assert(friend_number == 0); }); tox_events_callback_friend_typing( - dispatch, [](Tox *tox, const Tox_Event_Friend_Typing *event, void *user_data) { + dispatch, [](const Tox_Event_Friend_Typing *event, void *user_data) { const uint32_t friend_number = tox_event_friend_typing_get_friend_number(event); assert(friend_number == 0); assert(!tox_event_friend_typing_get_typing(event)); }); tox_events_callback_self_connection_status( - dispatch, [](Tox *tox, const Tox_Event_Self_Connection_Status *event, void *user_data) { + dispatch, [](const Tox_Event_Self_Connection_Status *event, void *user_data) { // OK: we got connected. }); } @@ -179,7 +176,7 @@ void TestEndToEnd(Fuzz_Data &input) Tox_Err_Events_Iterate error_iterate; Tox_Events *events = tox_events_iterate(tox, true, &error_iterate); tox_events_equal(tox_get_system(tox), events, events); // TODO(iphydf): assert? - tox_dispatch_invoke(dispatch, events, tox, nullptr); + tox_dispatch_invoke(dispatch, events, tox); tox_events_free(events); const uint8_t clock_increment = random_u08(sys.rng.get()); if (PROTODUMP_DEBUG) { diff --git a/testing/fuzzing/toxsave_fuzz_test.cc b/testing/fuzzing/toxsave_fuzz_test.cc index a5ac0f15..2cb134cb 100644 --- a/testing/fuzzing/toxsave_fuzz_test.cc +++ b/testing/fuzzing/toxsave_fuzz_test.cc @@ -4,7 +4,7 @@ #include "../../toxcore/tox.h" #include "../../toxcore/tox_private.h" -#include "fuzz_support.h" +#include "fuzz_support.hh" namespace { diff --git a/testing/misc_tools.c b/testing/misc_tools.c index e274e5a7..a2b950c1 100644 --- a/testing/misc_tools.c +++ b/testing/misc_tools.c @@ -138,7 +138,6 @@ int cmdline_parsefor_ipv46(int argc, char **argv, bool *ipv6enabled) return argvoffset; } - static const char *test_rng_name(void) { return "test_rng"; diff --git a/testing/misc_tools.h b/testing/misc_tools.h index 3e5627d5..a6513c76 100644 --- a/testing/misc_tools.h +++ b/testing/misc_tools.h @@ -1,7 +1,9 @@ #ifndef C_TOXCORE_TESTING_MISC_TOOLS_H #define C_TOXCORE_TESTING_MISC_TOOLS_H -#include "../toxcore/tox.h" +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -13,7 +15,6 @@ extern "C" { void c_sleep(uint32_t x); uint8_t *hex_string_to_bin(const char *hex_string); -char *id_toa(const uint8_t *id); void to_hex(char *out, uint8_t *in, int size); int tox_strncasecmp(const char *s1, const char *s2, size_t n); int cmdline_parsefor_ipv46(int argc, char **argv, bool *ipv6enabled); @@ -21,7 +22,7 @@ int cmdline_parsefor_ipv46(int argc, char **argv, bool *ipv6enabled); int use_test_rng(uint32_t seed); #ifdef __cplusplus -} +} /* extern "C" */ #endif #endif diff --git a/third_party/BUILD.bazel b/third_party/BUILD.bazel index 45344cb2..528558fb 100644 --- a/third_party/BUILD.bazel +++ b/third_party/BUILD.bazel @@ -9,7 +9,10 @@ cc_library( ) filegroup( - name = "headers", - srcs = ["cmp/cmp.h"], + name = "cimple_files", + srcs = [ + "cmp/cmp.c", + "cmp/cmp.h", + ], visibility = ["//c-toxcore:__subpackages__"], ) diff --git a/third_party/cmp b/third_party/cmp index e8367032..643e6a62 160000 --- a/third_party/cmp +++ b/third_party/cmp @@ -1 +1 @@ -Subproject commit e836703291392aba9db92b46fb47929521fac71f +Subproject commit 643e6a62d4eb0ec2277de269cda33da02cba2756 diff --git a/toxav/audio.c b/toxav/audio.c index 4070b25f..2cbc02d2 100644 --- a/toxav/audio.c +++ b/toxav/audio.c @@ -25,8 +25,6 @@ static bool reconfigure_audio_encoder(const Logger *log, OpusEncoder **e, uint32 uint8_t new_ch, uint32_t *old_br, uint32_t *old_sr, uint8_t *old_ch); static bool reconfigure_audio_decoder(ACSession *ac, uint32_t sampling_rate, uint8_t channels); - - ACSession *ac_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t friend_number, toxav_audio_receive_frame_cb *cb, void *cb_data) { @@ -194,9 +192,9 @@ void ac_iterate(ACSession *ac) free(temp_audio_buffer); } -int ac_queue_message(Mono_Time *mono_time, void *acp, struct RTPMessage *msg) +int ac_queue_message(Mono_Time *mono_time, void *cs, struct RTPMessage *msg) { - ACSession *ac = (ACSession *)acp; + ACSession *ac = (ACSession *)cs; if (ac == nullptr || msg == nullptr) { free(msg); @@ -242,8 +240,6 @@ int ac_reconfigure_encoder(ACSession *ac, uint32_t bit_rate, uint32_t sampling_r return 0; } - - struct JitterBuffer { struct RTPMessage **queue; uint32_t size; @@ -365,7 +361,6 @@ static OpusEncoder *create_audio_encoder(const Logger *log, uint32_t bit_rate, u return nullptr; } - /* * Rates from 500 to 512000 bits per second are meaningful as well as the special * values OPUS_BITRATE_AUTO and OPUS_BITRATE_MAX. The value OPUS_BITRATE_MAX can @@ -382,7 +377,6 @@ static OpusEncoder *create_audio_encoder(const Logger *log, uint32_t bit_rate, u goto FAILURE; } - /* * Configures the encoder's use of inband forward error correction. * Note: @@ -398,7 +392,6 @@ static OpusEncoder *create_audio_encoder(const Logger *log, uint32_t bit_rate, u goto FAILURE; } - /* * Configures the encoder's expected packet loss percentage. * Higher values with trigger progressively more loss resistant behavior in @@ -418,7 +411,6 @@ static OpusEncoder *create_audio_encoder(const Logger *log, uint32_t bit_rate, u goto FAILURE; } - /* * Configures the encoder's computational complexity. * diff --git a/toxav/audio.h b/toxav/audio.h index 358fe4e8..3ae42511 100644 --- a/toxav/audio.h +++ b/toxav/audio.h @@ -67,7 +67,7 @@ ACSession *ac_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t f toxav_audio_receive_frame_cb *cb, void *cb_data); void ac_kill(ACSession *ac); void ac_iterate(ACSession *ac); -int ac_queue_message(Mono_Time *mono_time, void *acp, struct RTPMessage *msg); +int ac_queue_message(Mono_Time *mono_time, void *cs, struct RTPMessage *msg); int ac_reconfigure_encoder(ACSession *ac, uint32_t bit_rate, uint32_t sampling_rate, uint8_t channels); -#endif // C_TOXCORE_TOXAV_AUDIO_H +#endif /* C_TOXCORE_TOXAV_AUDIO_H */ diff --git a/toxav/bwcontroller.c b/toxav/bwcontroller.c index b051a1a3..e9ceb96b 100644 --- a/toxav/bwcontroller.c +++ b/toxav/bwcontroller.c @@ -56,7 +56,7 @@ struct BWCMessage { uint32_t recv; }; -static int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object); +static int bwc_handle_data(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object); static int bwc_send_custom_lossy_packet(Tox *tox, int32_t friendnumber, const uint8_t *data, uint32_t length); static void send_update(BWController *bwc); @@ -206,7 +206,7 @@ static int bwc_send_custom_lossy_packet(Tox *tox, int32_t friendnumber, const ui return -1; } -static int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object) +static int bwc_handle_data(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object) { BWController *bwc = (BWController *)object; diff --git a/toxav/bwcontroller.h b/toxav/bwcontroller.h index 628b3856..53931c03 100644 --- a/toxav/bwcontroller.h +++ b/toxav/bwcontroller.h @@ -10,7 +10,7 @@ typedef struct BWController BWController; -typedef void m_cb(BWController *bwc, uint32_t friend_number, float todo, void *user_data); +typedef void m_cb(BWController *bwc, uint32_t friend_number, float loss, void *user_data); BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb, void *mcb_user_data, Mono_Time *bwc_mono_time); @@ -20,4 +20,4 @@ void bwc_kill(BWController *bwc); void bwc_add_lost(BWController *bwc, uint32_t bytes_lost); void bwc_add_recv(BWController *bwc, uint32_t recv_bytes); -#endif // C_TOXCORE_TOXAV_BWCONTROLLER_H +#endif /* C_TOXCORE_TOXAV_BWCONTROLLER_H */ diff --git a/toxav/groupav.c b/toxav/groupav.c index a0e52036..63dd569d 100644 --- a/toxav/groupav.c +++ b/toxav/groupav.c @@ -255,7 +255,7 @@ static Group_AV *new_group_av(const Logger *log, Tox *tox, Group_Chats *g_c, aud return group_av; } -static void group_av_peer_new(void *object, uint32_t groupnumber, uint32_t friendgroupnumber) +static void group_av_peer_new(void *object, uint32_t conference_number, uint32_t peer_number) { const Group_AV *group_av = (const Group_AV *)object; Group_Peer_AV *peer_av = (Group_Peer_AV *)calloc(1, sizeof(Group_Peer_AV)); @@ -267,12 +267,12 @@ static void group_av_peer_new(void *object, uint32_t groupnumber, uint32_t frien peer_av->mono_time = g_mono_time(group_av->g_c); peer_av->buffer = create_queue(GROUP_JBUF_SIZE); - if (group_peer_set_object(group_av->g_c, groupnumber, friendgroupnumber, peer_av) == -1) { + if (group_peer_set_object(group_av->g_c, conference_number, peer_number, peer_av) == -1) { free(peer_av); } } -static void group_av_peer_delete(void *object, uint32_t groupnumber, void *peer_object) +static void group_av_peer_delete(void *object, uint32_t conference_number, void *peer_object) { Group_Peer_AV *peer_av = (Group_Peer_AV *)peer_object; @@ -288,7 +288,7 @@ static void group_av_peer_delete(void *object, uint32_t groupnumber, void *peer_ free(peer_object); } -static void group_av_groupchat_delete(void *object, uint32_t groupnumber) +static void group_av_groupchat_delete(void *object, uint32_t conference_number) { Group_AV *group_av = (Group_AV *)object; if (group_av != nullptr) { @@ -296,8 +296,8 @@ static void group_av_groupchat_delete(void *object, uint32_t groupnumber) } } -static int decode_audio_packet(Group_AV *group_av, Group_Peer_AV *peer_av, uint32_t groupnumber, - uint32_t friendgroupnumber) +static int decode_audio_packet(Group_AV *group_av, Group_Peer_AV *peer_av, uint32_t conference_number, + uint32_t peer_number) { if (group_av == nullptr || peer_av == nullptr) { return -1; @@ -391,7 +391,7 @@ static int decode_audio_packet(Group_AV *group_av, Group_Peer_AV *peer_av, uint3 if (out_audio != nullptr) { if (group_av->audio_data != nullptr) { - group_av->audio_data(group_av->tox, groupnumber, friendgroupnumber, out_audio, out_audio_samples, + group_av->audio_data(group_av->tox, conference_number, peer_number, out_audio, out_audio_samples, peer_av->decoder_channels, sample_rate, group_av->userdata); } @@ -402,7 +402,7 @@ static int decode_audio_packet(Group_AV *group_av, Group_Peer_AV *peer_av, uint3 return -1; } -static int handle_group_audio_packet(void *object, uint32_t groupnumber, uint32_t friendgroupnumber, void *peer_object, +static int handle_group_audio_packet(void *object, uint32_t conference_number, uint32_t peer_number, void *peer_object, const uint8_t *packet, uint16_t length) { Group_AV *group_av = (Group_AV *)object; @@ -435,23 +435,23 @@ static int handle_group_audio_packet(void *object, uint32_t groupnumber, uint32_ return -1; } - while (decode_audio_packet(group_av, peer_av, groupnumber, friendgroupnumber) == 0) { + while (decode_audio_packet(group_av, peer_av, conference_number, peer_number) == 0) { /* Continue. */ } return 0; } -/** @brief Enable A/V in a groupchat. +/** @brief Enable A/V in a conference. * * @retval 0 on success. * @retval -1 on failure. */ -int groupchat_enable_av(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t groupnumber, +int groupchat_enable_av(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t conference_number, audio_data_cb *audio_callback, void *userdata) { - if (group_get_type(g_c, groupnumber) != GROUPCHAT_TYPE_AV - || group_get_object(g_c, groupnumber) != nullptr) { + if (group_get_type(g_c, conference_number) != GROUPCHAT_TYPE_AV + || group_get_object(g_c, conference_number) != nullptr) { return -1; } @@ -461,15 +461,15 @@ int groupchat_enable_av(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t return -1; } - if (group_set_object(g_c, groupnumber, group_av) == -1 - || callback_groupchat_peer_new(g_c, groupnumber, group_av_peer_new) == -1 - || callback_groupchat_peer_delete(g_c, groupnumber, group_av_peer_delete) == -1 - || callback_groupchat_delete(g_c, groupnumber, group_av_groupchat_delete) == -1) { + if (group_set_object(g_c, conference_number, group_av) == -1 + || callback_groupchat_peer_new(g_c, conference_number, group_av_peer_new) == -1 + || callback_groupchat_peer_delete(g_c, conference_number, group_av_peer_delete) == -1 + || callback_groupchat_delete(g_c, conference_number, group_av_groupchat_delete) == -1) { kill_group_av(group_av); return -1; } - const int numpeers = group_number_peers(g_c, groupnumber, false); + const int numpeers = group_number_peers(g_c, conference_number, false); if (numpeers < 0) { kill_group_av(group_av); @@ -477,31 +477,31 @@ int groupchat_enable_av(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t } for (uint32_t i = 0; i < numpeers; ++i) { - group_av_peer_new(group_av, groupnumber, i); + group_av_peer_new(group_av, conference_number, i); } group_lossy_packet_registerhandler(g_c, GROUP_AUDIO_PACKET_ID, &handle_group_audio_packet); return 0; } -/** @brief Disable A/V in a groupchat. +/** @brief Disable A/V in a conference. * * @retval 0 on success. * @retval -1 on failure. */ -int groupchat_disable_av(const Group_Chats *g_c, uint32_t groupnumber) +int groupchat_disable_av(const Group_Chats *g_c, uint32_t conference_number) { - if (group_get_type(g_c, groupnumber) != GROUPCHAT_TYPE_AV) { + if (group_get_type(g_c, conference_number) != GROUPCHAT_TYPE_AV) { return -1; } - Group_AV *group_av = (Group_AV *)group_get_object(g_c, groupnumber); + Group_AV *group_av = (Group_AV *)group_get_object(g_c, conference_number); if (group_av == nullptr) { return -1; } - const int numpeers = group_number_peers(g_c, groupnumber, false); + const int numpeers = group_number_peers(g_c, conference_number, false); if (numpeers < 0) { kill_group_av(group_av); @@ -509,77 +509,77 @@ int groupchat_disable_av(const Group_Chats *g_c, uint32_t groupnumber) } for (uint32_t i = 0; i < numpeers; ++i) { - group_av_peer_delete(group_av, groupnumber, group_peer_get_object(g_c, groupnumber, i)); - group_peer_set_object(g_c, groupnumber, i, nullptr); + group_av_peer_delete(group_av, conference_number, group_peer_get_object(g_c, conference_number, i)); + group_peer_set_object(g_c, conference_number, i, nullptr); } kill_group_av(group_av); - if (group_set_object(g_c, groupnumber, nullptr) == -1 - || callback_groupchat_peer_new(g_c, groupnumber, nullptr) == -1 - || callback_groupchat_peer_delete(g_c, groupnumber, nullptr) == -1 - || callback_groupchat_delete(g_c, groupnumber, nullptr) == -1) { + if (group_set_object(g_c, conference_number, nullptr) == -1 + || callback_groupchat_peer_new(g_c, conference_number, nullptr) == -1 + || callback_groupchat_peer_delete(g_c, conference_number, nullptr) == -1 + || callback_groupchat_delete(g_c, conference_number, nullptr) == -1) { return -1; } return 0; } -/** Return whether A/V is enabled in the groupchat. */ -bool groupchat_av_enabled(const Group_Chats *g_c, uint32_t groupnumber) +/** Return whether A/V is enabled in the conference. */ +bool groupchat_av_enabled(const Group_Chats *g_c, uint32_t conference_number) { - return group_get_object(g_c, groupnumber) != nullptr; + return group_get_object(g_c, conference_number) != nullptr; } /** @brief Create and connect to a new toxav group. * - * @return group number on success. + * @return conference number on success. * @retval -1 on failure. */ int add_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, audio_data_cb *audio_callback, void *userdata) { - const int groupnumber = add_groupchat(g_c, tox->sys.rng, GROUPCHAT_TYPE_AV); + const int conference_number = add_groupchat(g_c, tox->sys.rng, GROUPCHAT_TYPE_AV); - if (groupnumber == -1) { + if (conference_number == -1) { return -1; } - if (groupchat_enable_av(log, tox, g_c, groupnumber, audio_callback, userdata) == -1) { - del_groupchat(g_c, groupnumber, true); + if (groupchat_enable_av(log, tox, g_c, conference_number, audio_callback, userdata) == -1) { + del_groupchat(g_c, conference_number, true); return -1; } - return groupnumber; + return conference_number; } /** @brief Join a AV group (you need to have been invited first). * - * @return group number on success + * @return conference number on success * @retval -1 on failure. */ -int join_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t friendnumber, const uint8_t *data, +int join_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t peer_number, const uint8_t *data, uint16_t length, audio_data_cb *audio_callback, void *userdata) { - const int groupnumber = join_groupchat(g_c, friendnumber, GROUPCHAT_TYPE_AV, data, length); + const int conference_number = join_groupchat(g_c, peer_number, GROUPCHAT_TYPE_AV, data, length); - if (groupnumber == -1) { + if (conference_number == -1) { return -1; } - if (groupchat_enable_av(log, tox, g_c, groupnumber, audio_callback, userdata) == -1) { - del_groupchat(g_c, groupnumber, true); + if (groupchat_enable_av(log, tox, g_c, conference_number, audio_callback, userdata) == -1) { + del_groupchat(g_c, conference_number, true); return -1; } - return groupnumber; + return conference_number; } -/** @brief Send an encoded audio packet to the group chat. +/** @brief Send an encoded audio packet to the conference. * * @retval 0 on success. * @retval -1 on failure. */ -static int send_audio_packet(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t *packet, uint16_t length) +static int send_audio_packet(const Group_Chats *g_c, uint32_t conference_number, const uint8_t *packet, uint16_t length) { if (length == 0 || length > MAX_CRYPTO_DATA_SIZE - 1 - sizeof(uint16_t)) { return -1; @@ -587,7 +587,7 @@ static int send_audio_packet(const Group_Chats *g_c, uint32_t groupnumber, const const uint16_t plen = 1 + sizeof(uint16_t) + length; - Group_AV *const group_av = (Group_AV *)group_get_object(g_c, groupnumber); + Group_AV *const group_av = (Group_AV *)group_get_object(g_c, conference_number); if (group_av == nullptr) { return -1; @@ -601,7 +601,7 @@ static int send_audio_packet(const Group_Chats *g_c, uint32_t groupnumber, const ptr += net_pack_u16(ptr, group_av->audio_sequnum); memcpy(ptr, packet, length); - if (send_group_lossy_packet(g_c, groupnumber, data, plen) == -1) { + if (send_group_lossy_packet(g_c, conference_number, data, plen) == -1) { return -1; } @@ -609,15 +609,15 @@ static int send_audio_packet(const Group_Chats *g_c, uint32_t groupnumber, const return 0; } -/** @brief Send audio to the group chat. +/** @brief Send audio to the conference. * * @retval 0 on success. * @retval -1 on failure. */ -int group_send_audio(const Group_Chats *g_c, uint32_t groupnumber, const int16_t *pcm, unsigned int samples, uint8_t channels, +int group_send_audio(const Group_Chats *g_c, uint32_t conference_number, const int16_t *pcm, unsigned int samples, uint8_t channels, uint32_t sample_rate) { - Group_AV *group_av = (Group_AV *)group_get_object(g_c, groupnumber); + Group_AV *group_av = (Group_AV *)group_get_object(g_c, conference_number); if (group_av == nullptr) { return -1; @@ -655,5 +655,5 @@ int group_send_audio(const Group_Chats *g_c, uint32_t groupnumber, const int16_t return -1; } - return send_audio_packet(g_c, groupnumber, encoded, size); + return send_audio_packet(g_c, conference_number, encoded, size); } diff --git a/toxav/groupav.h b/toxav/groupav.h index e85bc5f2..67778036 100644 --- a/toxav/groupav.h +++ b/toxav/groupav.h @@ -14,51 +14,50 @@ #define GROUP_AUDIO_PACKET_ID 192 // TODO(iphydf): Use this better typed one instead of the void-pointer one below. -// typedef void audio_data_cb(Tox *tox, uint32_t groupnumber, uint32_t peernumber, const int16_t *pcm, +// typedef void audio_data_cb(Tox *tox, uint32_t conference_number, uint32_t peernumber, const int16_t *pcm, // uint32_t samples, uint8_t channels, uint32_t sample_rate, void *userdata); -typedef void audio_data_cb(void *tox, uint32_t groupnumber, uint32_t peernumber, const int16_t *pcm, +typedef void audio_data_cb(void *tox, uint32_t conference_number, uint32_t peernumber, const int16_t *pcm, uint32_t samples, uint8_t channels, uint32_t sample_rate, void *userdata); /** @brief Create and connect to a new toxav group. * - * @return group number on success. + * @return conference number on success. * @retval -1 on failure. */ int add_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, audio_data_cb *audio_callback, void *userdata); /** @brief Join a AV group (you need to have been invited first). * - * @return group number on success + * @return conference number on success * @retval -1 on failure. */ -int join_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t friendnumber, const uint8_t *data, +int join_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t peer_number, const uint8_t *data, uint16_t length, audio_data_cb *audio_callback, void *userdata); - -/** @brief Send audio to the group chat. +/** @brief Send audio to the conference. * * @retval 0 on success. * @retval -1 on failure. */ -int group_send_audio(const Group_Chats *g_c, uint32_t groupnumber, const int16_t *pcm, unsigned int samples, uint8_t channels, +int group_send_audio(const Group_Chats *g_c, uint32_t conference_number, const int16_t *pcm, unsigned int samples, uint8_t channels, uint32_t sample_rate); -/** @brief Enable A/V in a groupchat. +/** @brief Enable A/V in a conference. * * @retval 0 on success. * @retval -1 on failure. */ -int groupchat_enable_av(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t groupnumber, +int groupchat_enable_av(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t conference_number, audio_data_cb *audio_callback, void *userdata); -/** @brief Disable A/V in a groupchat. +/** @brief Disable A/V in a conference. * * @retval 0 on success. * @retval -1 on failure. */ -int groupchat_disable_av(const Group_Chats *g_c, uint32_t groupnumber); +int groupchat_disable_av(const Group_Chats *g_c, uint32_t conference_number); -/** Return whether A/V is enabled in the groupchat. */ -bool groupchat_av_enabled(const Group_Chats *g_c, uint32_t groupnumber); +/** Return whether A/V is enabled in the conference. */ +bool groupchat_av_enabled(const Group_Chats *g_c, uint32_t conference_number); -#endif // C_TOXCORE_TOXAV_GROUPAV_H +#endif /* C_TOXCORE_TOXAV_GROUPAV_H */ diff --git a/toxav/msi.c b/toxav/msi.c index aaa8d551..1b375410 100644 --- a/toxav/msi.c +++ b/toxav/msi.c @@ -27,14 +27,12 @@ typedef enum MSIHeaderID { ID_CAPABILITIES, } MSIHeaderID; - typedef enum MSIRequest { REQU_INIT, REQU_PUSH, REQU_POP, } MSIRequest; - typedef struct MSIHeaderRequest { MSIRequest value; bool exists; @@ -50,14 +48,12 @@ typedef struct MSIHeaderCapabilities { bool exists; } MSIHeaderCapabilities; - typedef struct MSIMessage { MSIHeaderRequest request; MSIHeaderError error; MSIHeaderCapabilities capabilities; } MSIMessage; - static void msg_init(MSIMessage *dest, MSIRequest request); static int msg_parse_in(const Logger *log, MSIMessage *dest, const uint8_t *data, uint16_t length); static uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const uint8_t *value, uint8_t value_len, @@ -68,12 +64,11 @@ static bool invoke_callback(MSICall *call, MSICallbackID cb); static MSICall *get_call(MSISession *session, uint32_t friend_number); static MSICall *new_call(MSISession *session, uint32_t friend_number); static void kill_call(MSICall *call); -static void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *data); +static void on_peer_status(Messenger *m, uint32_t friend_number, bool is_online, void *user_data); static void handle_init(MSICall *call, const MSIMessage *msg); static void handle_push(MSICall *call, const MSIMessage *msg); static void handle_pop(MSICall *call, const MSIMessage *msg); -static void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object); - +static void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *user_data); /* * Public functions @@ -318,7 +313,6 @@ int msi_change_capabilities(MSICall *call, uint8_t capabilities) return 0; } - /** * Private functions */ @@ -357,7 +351,6 @@ static bool check_enum_high(const Logger *log, const uint8_t *bytes, uint8_t enu return true; } - static int msg_parse_in(const Logger *log, MSIMessage *dest, const uint8_t *data, uint16_t length) { /* Parse raw data received from socket into MSIMessage struct */ @@ -449,7 +442,7 @@ static int send_message(const Messenger *m, uint32_t friend_number, const MSIMes /* Parse and send message */ assert(m != nullptr); - uint8_t parsed [MSI_MAXMSG_SIZE]; + uint8_t parsed[MSI_MAXMSG_SIZE]; uint8_t *it = parsed; uint16_t size = 0; @@ -587,7 +580,7 @@ static MSICall *new_call(MSISession *session, uint32_t friend_number) session->calls_tail = friend_number; session->calls_head = friend_number; } else if (session->calls_tail < friend_number) { /* Appending */ - MSICall **tmp = (MSICall **)realloc(session->calls, (friend_number + 1) * sizeof(MSICall *)); + MSICall **tmp = (MSICall **)realloc(session->calls, (friend_number + 1) * sizeof(MSICall *)); if (tmp == nullptr) { free(rc); @@ -655,11 +648,11 @@ CLEAR_CONTAINER: free(call); session->calls = nullptr; } -static void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *data) +static void on_peer_status(Messenger *m, uint32_t friend_number, bool is_online, void *user_data) { - MSISession *session = (MSISession *)data; + MSISession *session = (MSISession *)user_data; - if (status != 0) { + if (is_online) { // Friend is online. return; } @@ -850,9 +843,9 @@ static void handle_pop(MSICall *call, const MSIMessage *msg) kill_call(call); } -static void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object) +static void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *user_data) { - MSISession *session = (MSISession *)object; + MSISession *session = (MSISession *)user_data; LOGGER_DEBUG(m->log, "Got msi message"); diff --git a/toxav/msi.h b/toxav/msi.h index 547f4c76..f034a35c 100644 --- a/toxav/msi.h +++ b/toxav/msi.h @@ -38,7 +38,6 @@ typedef enum MSICapabilities { MSI_CAP_R_VIDEO = 32, /* receiving video */ } MSICapabilities; - /** * Call state identifiers. */ @@ -80,13 +79,12 @@ typedef struct MSICall { struct MSICall *prev; } MSICall; - /** * Expected return on success is 0, if any other number is * returned the call is considered errored and will be handled * as such which means it will be terminated without any notice. */ -typedef int msi_action_cb(void *av, MSICall *call); +typedef int msi_action_cb(void *object, MSICall *call); /** * Control session struct. Please do not modify outside msi.c @@ -144,4 +142,4 @@ int msi_answer(MSICall *call, uint8_t capabilities); */ int msi_change_capabilities(MSICall *call, uint8_t capabilities); -#endif // C_TOXCORE_TOXAV_MSI_H +#endif /* C_TOXCORE_TOXAV_MSI_H */ diff --git a/toxav/ring_buffer.h b/toxav/ring_buffer.h index 775bf503..d89e25e2 100644 --- a/toxav/ring_buffer.h +++ b/toxav/ring_buffer.h @@ -25,7 +25,7 @@ uint16_t rb_size(const RingBuffer *b); uint16_t rb_data(const RingBuffer *b, void **dest); #ifdef __cplusplus -} +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXAV_RING_BUFFER_H +#endif /* C_TOXCORE_TOXAV_RING_BUFFER_H */ diff --git a/toxav/rtp.c b/toxav/rtp.c index 878a70ca..8ad4ce67 100644 --- a/toxav/rtp.c +++ b/toxav/rtp.c @@ -23,7 +23,6 @@ */ #define VIDEO_KEEP_KEYFRAME_IN_BUFFER_FOR_MS 15 - /** * return -1 on failure, 0 on success * @@ -440,7 +439,7 @@ static int handle_video_packet(RTPSession *session, const struct RTPHeader *head * @retval -1 on error. * @retval 0 on success. */ -static int handle_rtp_packet(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object) +static int handle_rtp_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object) { RTPSession *session = (RTPSession *)object; @@ -806,8 +805,9 @@ int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length, header.flags |= RTP_KEY_FRAME; } - VLA(uint8_t, rdata, length + RTP_HEADER_SIZE + 1); - memset(rdata, 0, SIZEOF_VLA(rdata)); + const uint16_t rdata_size = length + RTP_HEADER_SIZE + 1; + VLA(uint8_t, rdata, rdata_size); + memset(rdata, 0, rdata_size); rdata[0] = session->payload_type; // packet id == payload_type if (MAX_CRYPTO_DATA_SIZE > (length + RTP_HEADER_SIZE + 1)) { @@ -818,10 +818,10 @@ int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length, rtp_header_pack(rdata + 1, &header); memcpy(rdata + 1 + RTP_HEADER_SIZE, data, length); - if (-1 == rtp_send_custom_lossy_packet(session->tox, session->friend_number, rdata, SIZEOF_VLA(rdata))) { + if (-1 == rtp_send_custom_lossy_packet(session->tox, session->friend_number, rdata, rdata_size)) { char *netstrerror = net_new_strerror(net_error()); LOGGER_WARNING(session->m->log, "RTP send failed (len: %u)! net error: %s", - (unsigned)SIZEOF_VLA(rdata), netstrerror); + rdata_size, netstrerror); net_kill_strerror(netstrerror); } } else { diff --git a/toxav/rtp.h b/toxav/rtp.h index 6144c639..8acd48d0 100644 --- a/toxav/rtp.h +++ b/toxav/rtp.h @@ -52,7 +52,6 @@ typedef enum RTPFlags { RTP_KEY_FRAME = 1 << 1, } RTPFlags; - struct RTPHeader { /* Standard RTP header */ unsigned ve: 2; /* Version has only 2 bits! */ @@ -100,7 +99,6 @@ struct RTPHeader { uint16_t data_length_lower; }; - struct RTPMessage { /** * This is used in the old code that doesn't deal with large frames, i.e. @@ -167,7 +165,6 @@ typedef struct RTPSession { rtp_m_cb *mcb; } RTPSession; - /** * Serialise an RTPHeader to bytes to be sent over the network. * @@ -204,7 +201,7 @@ int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length, bool is_keyframe, const Logger *log); #ifdef __cplusplus -} // extern "C" +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXAV_RTP_H +#endif /* C_TOXCORE_TOXAV_RTP_H */ diff --git a/toxav/rtp_test.cc b/toxav/rtp_test.cc index b29c937a..674bc4b4 100644 --- a/toxav/rtp_test.cc +++ b/toxav/rtp_test.cc @@ -29,7 +29,7 @@ RTPHeader random_header(const Random *rng) TEST(Rtp, Deserialisation) { - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); RTPHeader const header = random_header(rng); diff --git a/toxav/toxav.c b/toxav/toxav.c index ea220838..6bae7a91 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c @@ -65,7 +65,6 @@ typedef struct ToxAVCall { struct ToxAVCall *next; } ToxAVCall; - /** Decode time statistics */ typedef struct DecodeTimeStats { /** Measure count */ @@ -118,11 +117,11 @@ struct ToxAV { static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *user_data); -static int callback_invite(void *toxav_inst, MSICall *call); -static int callback_start(void *toxav_inst, MSICall *call); -static int callback_end(void *toxav_inst, MSICall *call); -static int callback_error(void *toxav_inst, MSICall *call); -static int callback_capabilites(void *toxav_inst, MSICall *call); +static int callback_invite(void *object, MSICall *call); +static int callback_start(void *object, MSICall *call); +static int callback_end(void *object, MSICall *call); +static int callback_error(void *object, MSICall *call); +static int callback_capabilites(void *object, MSICall *call); static bool audio_bit_rate_invalid(uint32_t bit_rate); static bool video_bit_rate_invalid(uint32_t bit_rate); @@ -850,12 +849,14 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc goto RETURN; } - VLA(uint8_t, dest, sample_count + sizeof(sampling_rate)); /* This is more than enough always */ + /* This is more than enough always */ + const uint16_t dest_size = sample_count + sizeof(sampling_rate); + VLA(uint8_t, dest, dest_size); sampling_rate = net_htonl(sampling_rate); memcpy(dest, &sampling_rate, sizeof(sampling_rate)); const int vrc = opus_encode(call->audio->encoder, pcm, sample_count, - dest + sizeof(sampling_rate), SIZEOF_VLA(dest) - sizeof(sampling_rate)); + dest + sizeof(sampling_rate), dest_size - sizeof(sampling_rate)); if (vrc < 0) { LOGGER_WARNING(av->m->log, "Failed to encode frame %s", opus_strerror(vrc)); @@ -1002,7 +1003,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u memcpy(img.planes[VPX_PLANE_V], v, (width / 2) * (height / 2)); const vpx_codec_err_t vrc = vpx_codec_encode(call->video->encoder, &img, - call->video->frame_counter, 1, vpx_encode_flags, MAX_ENCODE_TIME_US); + call->video->frame_counter, 1, vpx_encode_flags, MAX_ENCODE_TIME_US); vpx_img_free(&img); @@ -1095,9 +1096,9 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, pthread_mutex_unlock(call->av->mutex); } -static int callback_invite(void *toxav_inst, MSICall *call) +static int callback_invite(void *object, MSICall *call) { - ToxAV *toxav = (ToxAV *)toxav_inst; + ToxAV *toxav = (ToxAV *)object; pthread_mutex_lock(toxav->mutex); ToxAVCall *av_call = call_new(toxav, call->friend_number, nullptr); @@ -1123,9 +1124,9 @@ static int callback_invite(void *toxav_inst, MSICall *call) pthread_mutex_unlock(toxav->mutex); return 0; } -static int callback_start(void *toxav_inst, MSICall *call) +static int callback_start(void *object, MSICall *call) { - ToxAV *toxav = (ToxAV *)toxav_inst; + ToxAV *toxav = (ToxAV *)object; pthread_mutex_lock(toxav->mutex); ToxAVCall *av_call = call_get(toxav, call->friend_number); @@ -1137,13 +1138,13 @@ static int callback_start(void *toxav_inst, MSICall *call) } if (!call_prepare_transmission(av_call)) { - callback_error(toxav_inst, call); + callback_error(toxav, call); pthread_mutex_unlock(toxav->mutex); return -1; } if (!invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities)) { - callback_error(toxav_inst, call); + callback_error(toxav, call); pthread_mutex_unlock(toxav->mutex); return -1; } @@ -1151,9 +1152,9 @@ static int callback_start(void *toxav_inst, MSICall *call) pthread_mutex_unlock(toxav->mutex); return 0; } -static int callback_end(void *toxav_inst, MSICall *call) +static int callback_end(void *object, MSICall *call) { - ToxAV *toxav = (ToxAV *)toxav_inst; + ToxAV *toxav = (ToxAV *)object; pthread_mutex_lock(toxav->mutex); invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_FINISHED); @@ -1166,9 +1167,9 @@ static int callback_end(void *toxav_inst, MSICall *call) pthread_mutex_unlock(toxav->mutex); return 0; } -static int callback_error(void *toxav_inst, MSICall *call) +static int callback_error(void *object, MSICall *call) { - ToxAV *toxav = (ToxAV *)toxav_inst; + ToxAV *toxav = (ToxAV *)object; pthread_mutex_lock(toxav->mutex); invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_ERROR); @@ -1181,9 +1182,9 @@ static int callback_error(void *toxav_inst, MSICall *call) pthread_mutex_unlock(toxav->mutex); return 0; } -static int callback_capabilites(void *toxav_inst, MSICall *call) +static int callback_capabilites(void *object, MSICall *call) { - ToxAV *toxav = (ToxAV *)toxav_inst; + ToxAV *toxav = (ToxAV *)object; pthread_mutex_lock(toxav->mutex); if ((call->peer_capabilities & MSI_CAP_S_AUDIO) != 0) { diff --git a/toxav/toxav.h b/toxav/toxav.h index ff65c3fa..07d8d0ee 100644 --- a/toxav/toxav.h +++ b/toxav/toxav.h @@ -83,7 +83,6 @@ typedef struct Tox Tox; */ typedef struct ToxAV ToxAV; - /** @{ * @brief Creation and destruction */ @@ -113,7 +112,6 @@ typedef enum Toxav_Err_New { } Toxav_Err_New; - /** * Start new A/V session. There can only be only one session per Tox instance. */ @@ -135,7 +133,6 @@ Tox *toxav_get_tox(const ToxAV *av); /** @} */ - /** @{ * @brief A/V event loop, single thread */ @@ -156,7 +153,6 @@ void toxav_iterate(ToxAV *av); /** @} */ - /** @{ * @brief A/V event loop, multiple threads */ @@ -195,7 +191,6 @@ void toxav_video_iterate(ToxAV *av); /** @} */ - /** @{ * @brief Call setup */ @@ -241,7 +236,6 @@ typedef enum Toxav_Err_Call { } Toxav_Err_Call; - /** * Call a friend. This will start ringing the friend. * @@ -268,7 +262,6 @@ bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint */ typedef void toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data); - /** * Set the callback for the `call` event. Pass NULL to unset. * @@ -312,7 +305,6 @@ typedef enum Toxav_Err_Answer { } Toxav_Err_Answer; - /** * Accept an incoming call. * @@ -331,7 +323,6 @@ bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, ui /** @} */ - /** @{ * @brief Call state graph */ @@ -380,7 +371,6 @@ enum Toxav_Friend_Call_State { }; - /** * The function type for the call_state callback. * @@ -392,7 +382,6 @@ enum Toxav_Friend_Call_State { */ typedef void toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data); - /** * Set the callback for the `call_state` event. Pass NULL to unset. * @@ -401,7 +390,6 @@ void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *u /** @} */ - /** @{ * @brief Call control */ @@ -451,7 +439,6 @@ typedef enum Toxav_Call_Control { } Toxav_Call_Control; - typedef enum Toxav_Err_Call_Control { /** @@ -483,7 +470,6 @@ typedef enum Toxav_Err_Call_Control { } Toxav_Err_Call_Control; - /** * Sends a call control command to a friend. * @@ -497,7 +483,6 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, Toxav_Call_Control co /** @} */ - /** @{ * @brief Controlling bit rates */ @@ -533,8 +518,6 @@ typedef enum Toxav_Err_Bit_Rate_Set { /** @} */ - - /** @{ * @brief A/V sending */ @@ -586,7 +569,6 @@ typedef enum Toxav_Err_Send_Frame { } Toxav_Err_Send_Frame; - /** * Send an audio frame to a friend. * @@ -632,7 +614,6 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra */ typedef void toxav_audio_bit_rate_cb(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, void *user_data); - /** * Set the callback for the `audio_bit_rate` event. Pass NULL to unset. * @@ -655,11 +636,11 @@ void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback, * @param v V (Chroma) plane data. */ bool toxav_video_send_frame( - ToxAV *av, uint32_t friend_number, uint16_t width, uint16_t height, - const uint8_t y[/*! height * width */], - const uint8_t u[/*! height/2 * width/2 */], - const uint8_t v[/*! height/2 * width/2 */], - Toxav_Err_Send_Frame *error); + ToxAV *av, uint32_t friend_number, uint16_t width, uint16_t height, + const uint8_t y[/*! height * width */], + const uint8_t u[/*! height/2 * width/2 */], + const uint8_t v[/*! height/2 * width/2 */], + Toxav_Err_Send_Frame *error); /** * Set the bit rate to be used in subsequent video frames. @@ -683,7 +664,6 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra */ typedef void toxav_video_bit_rate_cb(ToxAV *av, uint32_t friend_number, uint32_t video_bit_rate, void *user_data); - /** * Set the callback for the `video_bit_rate` event. Pass NULL to unset. * @@ -692,7 +672,6 @@ void toxav_callback_video_bit_rate(ToxAV *av, toxav_video_bit_rate_cb *callback, /** @} */ - /** @{ * @brief A/V receiving */ @@ -712,7 +691,6 @@ void toxav_callback_video_bit_rate(ToxAV *av, toxav_video_bit_rate_cb *callback, typedef void toxav_audio_receive_frame_cb(ToxAV *av, uint32_t friend_number, const int16_t pcm[], size_t sample_count, uint8_t channels, uint32_t sampling_rate, void *user_data); - /** * Set the callback for the `audio_receive_frame` event. Pass NULL to unset. * @@ -742,14 +720,13 @@ void toxav_callback_audio_receive_frame(ToxAV *av, toxav_audio_receive_frame_cb * @param vstride V chroma plane stride. */ typedef void toxav_video_receive_frame_cb( - ToxAV *av, uint32_t friend_number, - uint16_t width, uint16_t height, - const uint8_t y[/*! max(width, abs(ystride)) * height */], - const uint8_t u[/*! max(width/2, abs(ustride)) * (height/2) */], - const uint8_t v[/*! max(width/2, abs(vstride)) * (height/2) */], - int32_t ystride, int32_t ustride, int32_t vstride, - void *user_data); - + ToxAV *av, uint32_t friend_number, + uint16_t width, uint16_t height, + const uint8_t y[/*! max(width, abs(ystride)) * height */], + const uint8_t u[/*! max(width/2, abs(ustride)) * (height/2) */], + const uint8_t v[/*! max(width/2, abs(vstride)) * (height/2) */], + int32_t ystride, int32_t ustride, int32_t vstride, + void *user_data); /** * Set the callback for the `video_receive_frame` event. Pass NULL to unset. @@ -791,8 +768,8 @@ int32_t toxav_add_av_groupchat(Tox *tox, toxav_audio_data_cb *audio_callback, vo * Note that total size of pcm in bytes is equal to `samples * channels * sizeof(int16_t)`. */ int32_t toxav_join_av_groupchat( - Tox *tox, uint32_t friendnumber, const uint8_t data[], uint16_t length, - toxav_audio_data_cb *audio_callback, void *userdata); + Tox *tox, uint32_t friendnumber, const uint8_t data[], uint16_t length, + toxav_audio_data_cb *audio_callback, void *userdata); /** @brief Send audio to the group chat. * @@ -809,8 +786,8 @@ int32_t toxav_join_av_groupchat( * Recommended values are: samples = 960, channels = 1, sample_rate = 48000 */ int32_t toxav_group_send_audio( - Tox *tox, uint32_t groupnumber, const int16_t pcm[], uint32_t samples, uint8_t channels, - uint32_t sample_rate); + Tox *tox, uint32_t groupnumber, const int16_t pcm[], uint32_t samples, uint8_t channels, + uint32_t sample_rate); /** @brief Enable A/V in a groupchat. * @@ -828,8 +805,8 @@ int32_t toxav_group_send_audio( * Note that total size of pcm in bytes is equal to `samples * channels * sizeof(int16_t)`. */ int32_t toxav_groupchat_enable_av( - Tox *tox, uint32_t groupnumber, - toxav_audio_data_cb *audio_callback, void *userdata); + Tox *tox, uint32_t groupnumber, + toxav_audio_data_cb *audio_callback, void *userdata); /** @brief Disable A/V in a groupchat. * @@ -846,7 +823,7 @@ bool toxav_groupchat_av_enabled(Tox *tox, uint32_t groupnumber); /** @} */ #ifdef __cplusplus -} +} /* extern "C" */ #endif //!TOKSTYLE- @@ -865,4 +842,4 @@ typedef enum Toxav_Friend_Call_State TOXAV_FRIEND_CALL_STATE; #endif //!TOKSTYLE+ -#endif // C_TOXCORE_TOXAV_TOXAV_H +#endif /* C_TOXCORE_TOXAV_TOXAV_H */ diff --git a/toxav/video.c b/toxav/video.c index e8212cf2..301400b0 100644 --- a/toxav/video.c +++ b/toxav/video.c @@ -140,7 +140,7 @@ static void vc_init_encoder_cfg(const Logger *log, vpx_codec_enc_cfg_t *cfg, int cfg->rc_buf_initial_sz = 500; cfg->rc_buf_optimal_sz = 600; cfg->rc_buf_sz = 1000; -#endif +#endif /* 0 */ } VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t friend_number, @@ -249,7 +249,7 @@ VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t f goto BASE_CLEANUP_1; } -#endif +#endif /* 0 */ vc->linfts = current_time_monotonic(mono_time); vc->lcfd = 60; vc->vcb = cb; @@ -343,9 +343,9 @@ void vc_iterate(VCSession *vc) } } -int vc_queue_message(Mono_Time *mono_time, void *vcp, struct RTPMessage *msg) +int vc_queue_message(Mono_Time *mono_time, void *cs, struct RTPMessage *msg) { - VCSession *vc = (VCSession *)vcp; + VCSession *vc = (VCSession *)cs; /* This function is called with complete messages * they have already been assembled. diff --git a/toxav/video.h b/toxav/video.h index 1fd4c04e..57db74ac 100644 --- a/toxav/video.h +++ b/toxav/video.h @@ -48,7 +48,7 @@ VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t f toxav_video_receive_frame_cb *cb, void *cb_data); void vc_kill(VCSession *vc); void vc_iterate(VCSession *vc); -int vc_queue_message(Mono_Time *mono_time, void *vcp, struct RTPMessage *msg); +int vc_queue_message(Mono_Time *mono_time, void *cs, struct RTPMessage *msg); int vc_reconfigure_encoder(VCSession *vc, uint32_t bit_rate, uint16_t width, uint16_t height, int16_t kf_max_dist); -#endif // C_TOXCORE_TOXAV_VIDEO_H +#endif /* C_TOXCORE_TOXAV_VIDEO_H */ diff --git a/toxcore/BUILD.bazel b/toxcore/BUILD.bazel index 534ead32..0f313e2a 100644 --- a/toxcore/BUILD.bazel +++ b/toxcore/BUILD.bazel @@ -21,7 +21,9 @@ cc_test( size = "small", srcs = ["test_util_test.cc"], deps = [ + ":crypto_core", ":crypto_core_test_util", + ":test_util", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -154,6 +156,7 @@ cc_test( deps = [ ":bin_pack", ":bin_unpack", + ":logger", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -167,10 +170,25 @@ cc_library( deps = [ ":attributes", ":ccompat", + ":util", "@libsodium", ], ) +cc_library( + name = "crypto_core_pack", + srcs = ["crypto_core_pack.c"], + hdrs = ["crypto_core_pack.h"], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":attributes", + ":bin_pack", + ":bin_unpack", + ":ccompat", + ":crypto_core", + ], +) + cc_library( name = "crypto_core_test_util", testonly = True, @@ -222,6 +240,7 @@ cc_library( srcs = ["state.c"], hdrs = ["state.h"], deps = [ + ":attributes", ":ccompat", ":logger", ], @@ -271,6 +290,7 @@ cc_library( "//c-toxcore/toxav:__pkg__", ], deps = [ + ":attributes", ":ccompat", ":crypto_core", ":logger", @@ -291,6 +311,8 @@ cc_library( "//c-toxcore/toxav:__pkg__", ], deps = [ + ":attributes", + ":bin_pack", ":ccompat", ":crypto_core", ":logger", @@ -332,6 +354,7 @@ cc_library( srcs = ["timed_auth.c"], hdrs = ["timed_auth.h"], deps = [ + ":attributes", ":ccompat", ":crypto_core", ":mono_time", @@ -343,6 +366,7 @@ cc_library( srcs = ["ping_array.c"], hdrs = ["ping_array.h"], deps = [ + ":attributes", ":ccompat", ":crypto_core", ":mem", @@ -356,6 +380,7 @@ cc_test( size = "small", srcs = ["ping_array_test.cc"], deps = [ + ":crypto_core_test_util", ":mem_test_util", ":mono_time", ":ping_array", @@ -374,10 +399,12 @@ cc_library( "//c-toxcore/testing:__pkg__", ], deps = [ + ":attributes", ":ccompat", ":crypto_core", ":network", ":util", + "@psocket", ], ) @@ -422,6 +449,7 @@ cc_library( ":DHT", ":crypto_core", ":crypto_core_test_util", + ":network", ":network_test_util", ":test_util", ], @@ -435,8 +463,13 @@ cc_test( ":DHT", ":DHT_test_util", ":crypto_core", + ":crypto_core_test_util", + ":logger", ":mem_test_util", + ":mono_time", + ":network", ":network_test_util", + ":test_util", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -460,10 +493,13 @@ cc_library( visibility = ["//c-toxcore/auto_tests:__pkg__"], deps = [ ":DHT", + ":attributes", ":ccompat", ":crypto_core", ":logger", + ":mem", ":mono_time", + ":network", ":shared_key_cache", ":util", ], @@ -476,7 +512,11 @@ cc_library( visibility = ["//c-toxcore/auto_tests:__pkg__"], deps = [ ":DHT", + ":attributes", ":ccompat", + ":crypto_core", + ":logger", + ":mono_time", ":network", ":timed_auth", ], @@ -503,9 +543,16 @@ cc_library( "//c-toxcore/other/bootstrap_daemon:__pkg__", ], deps = [ + ":DHT", ":LAN_discovery", + ":attributes", ":ccompat", + ":crypto_core", ":forwarding", + ":logger", + ":mem", + ":mono_time", + ":network", ":shared_key_cache", ":timed_auth", ":util", @@ -521,6 +568,7 @@ cc_library( ":attributes", ":ccompat", ":crypto_core", + ":logger", ":mem", ":network", ], @@ -541,13 +589,18 @@ cc_library( ], deps = [ ":TCP_common", + ":attributes", ":ccompat", ":crypto_core", ":forwarding", ":list", + ":logger", + ":mem", ":mono_time", + ":network", ":onion", ":util", + "@psocket", ], ) @@ -558,9 +611,12 @@ cc_library( visibility = ["//c-toxcore/auto_tests:__pkg__"], deps = [ ":TCP_common", + ":attributes", ":ccompat", ":crypto_core", ":forwarding", + ":logger", + ":mem", ":mono_time", ":network", ":util", @@ -576,10 +632,15 @@ cc_library( ":DHT", ":TCP_client", ":TCP_common", + ":attributes", ":ccompat", ":crypto_core", + ":forwarding", ":list", + ":logger", + ":mem", ":mono_time", + ":network", ":onion", ":util", ], @@ -604,12 +665,18 @@ cc_library( deps = [ ":DHT", ":LAN_discovery", + ":TCP_client", ":TCP_connection", + ":attributes", ":ccompat", + ":crypto_core", ":list", ":logger", + ":mem", ":mono_time", + ":network", ":util", + "@pthread", ], ) @@ -625,9 +692,13 @@ cc_library( deps = [ ":DHT", ":LAN_discovery", + ":attributes", ":ccompat", + ":crypto_core", ":logger", + ":mem", ":mono_time", + ":network", ":onion", ":shared_key_cache", ":timed_auth", @@ -647,8 +718,12 @@ cc_library( deps = [ ":DHT", ":LAN_discovery", + ":attributes", ":ccompat", + ":crypto_core", + ":logger", ":mono_time", + ":network", ":util", ], ) @@ -658,9 +733,13 @@ cc_test( size = "small", srcs = ["group_announce_test.cc"], deps = [ + ":DHT", + ":crypto_core", ":group_announce", + ":logger", ":mem_test_util", ":mono_time", + ":network", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -689,9 +768,16 @@ cc_library( "//c-toxcore/other/bootstrap_daemon:__pkg__", ], deps = [ + ":DHT", + ":attributes", ":ccompat", + ":crypto_core", ":group_announce", + ":logger", + ":mono_time", + ":network", ":onion_announce", + ":timed_auth", ], ) @@ -703,13 +789,21 @@ cc_library( deps = [ ":DHT", ":LAN_discovery", + ":TCP_connection", + ":attributes", ":ccompat", + ":crypto_core", + ":group_announce", ":group_onion_announce", + ":logger", + ":mem", ":mono_time", ":net_crypto", ":network", + ":onion", ":onion_announce", ":ping_array", + ":timed_auth", ":util", ], ) @@ -722,9 +816,16 @@ cc_library( deps = [ ":DHT", ":LAN_discovery", + ":TCP_connection", + ":attributes", ":ccompat", + ":crypto_core", + ":logger", ":mono_time", ":net_crypto", + ":network", + ":onion", + ":onion_announce", ":onion_client", ":util", ], @@ -740,9 +841,14 @@ cc_library( "//c-toxcore/testing:__pkg__", ], deps = [ + ":attributes", ":ccompat", + ":crypto_core", ":friend_connection", ":network", + ":onion", + ":onion_announce", + ":onion_client", ":util", ], ) @@ -753,9 +859,11 @@ cc_library( hdrs = ["group_moderation.h"], deps = [ ":DHT", + ":attributes", ":ccompat", ":crypto_core", ":logger", + ":mem", ":mono_time", ":network", ":util", @@ -768,6 +876,7 @@ cc_test( size = "small", srcs = ["group_moderation_test.cc"], deps = [ + ":DHT", ":crypto_core", ":crypto_core_test_util", ":group_moderation", @@ -816,13 +925,16 @@ cc_library( deps = [ ":DHT", ":LAN_discovery", + ":TCP_client", ":TCP_connection", ":TCP_server", ":announce", + ":attributes", ":bin_pack", ":bin_unpack", ":ccompat", ":crypto_core", + ":crypto_core_pack", ":forwarding", ":friend_connection", ":friend_requests", @@ -830,10 +942,13 @@ cc_library( ":group_moderation", ":group_onion_announce", ":logger", + ":mem", ":mono_time", ":net_crypto", ":network", + ":onion", ":onion_announce", + ":onion_client", ":state", ":util", "@libsodium", @@ -846,9 +961,16 @@ cc_library( hdrs = ["group.h"], visibility = ["//c-toxcore/toxav:__pkg__"], deps = [ + ":DHT", ":Messenger", + ":attributes", ":ccompat", + ":crypto_core", + ":friend_connection", + ":logger", ":mono_time", + ":net_crypto", + ":network", ":state", ":util", ], @@ -868,15 +990,25 @@ cc_library( ], visibility = ["//c-toxcore:__subpackages__"], deps = [ + ":DHT", ":Messenger", + ":TCP_client", + ":attributes", ":ccompat", + ":crypto_core", + ":friend_requests", ":group", ":group_moderation", ":logger", ":mem", ":mono_time", + ":net_crypto", ":network", + ":onion_client", + ":state", + ":util", "//c-toxcore/toxencryptsave:defines", + "@pthread", ], ) @@ -937,6 +1069,7 @@ cc_library( ":bin_pack", ":bin_unpack", ":ccompat", + ":logger", ":mem", ":tox", ":tox_pack", @@ -976,7 +1109,9 @@ cc_library( hdrs = ["tox_dispatch.h"], visibility = ["//c-toxcore:__subpackages__"], deps = [ + ":attributes", ":ccompat", + ":tox", ":tox_events", ], ) diff --git a/toxcore/DHT.c b/toxcore/DHT.c index d83d48c9..2567d1b5 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -9,11 +9,11 @@ #include "DHT.h" #include -#include #include #include #include "LAN_discovery.h" +#include "attributes.h" #include "bin_pack.h" #include "ccompat.h" #include "crypto_core.h" @@ -84,7 +84,7 @@ struct DHT_Friend { static const DHT_Friend empty_dht_friend = {{0}}; const Node_format empty_node_format = {{0}}; -static_assert(sizeof (empty_dht_friend.lock_flags) * 8 == DHT_FRIEND_MAX_LOCKS, "Bitfield size and number of locks don't match"); +static_assert(sizeof(empty_dht_friend.lock_flags) * 8 == DHT_FRIEND_MAX_LOCKS, "Bitfield size and number of locks don't match"); typedef struct Cryptopacket_Handler { cryptopacket_handler_cb *function; @@ -363,85 +363,6 @@ int packed_node_size(Family ip_family) return -1; } - -/** @brief Packs an IP structure. - * - * It's the caller's responsibility to make sure `is_ipv4` tells the truth. This - * function is an implementation detail of @ref bin_pack_ip_port. - * - * @param is_ipv4 whether this IP is an IP4 or IP6. - * - * @retval true on success. - */ -non_null() -static bool bin_pack_ip(Bin_Pack *bp, const IP *ip, bool is_ipv4) -{ - if (is_ipv4) { - return bin_pack_bin_b(bp, ip->ip.v4.uint8, SIZE_IP4); - } else { - return bin_pack_bin_b(bp, ip->ip.v6.uint8, SIZE_IP6); - } -} - -/** @brief Packs an IP_Port structure. - * - * @retval true on success. - */ -non_null() -static bool bin_pack_ip_port(Bin_Pack *bp, const Logger *logger, const IP_Port *ip_port) -{ - bool is_ipv4; - uint8_t family; - - if (net_family_is_ipv4(ip_port->ip.family)) { - // TODO(irungentoo): use functions to convert endianness - is_ipv4 = true; - family = TOX_AF_INET; - } else if (net_family_is_tcp_ipv4(ip_port->ip.family)) { - is_ipv4 = true; - family = TOX_TCP_INET; - } else if (net_family_is_ipv6(ip_port->ip.family)) { - is_ipv4 = false; - family = TOX_AF_INET6; - } else if (net_family_is_tcp_ipv6(ip_port->ip.family)) { - is_ipv4 = false; - family = TOX_TCP_INET6; - } else { - Ip_Ntoa ip_str; - // TODO(iphydf): Find out why we're trying to pack invalid IPs, stop - // doing that, and turn this into an error. - LOGGER_TRACE(logger, "cannot pack invalid IP: %s", net_ip_ntoa(&ip_port->ip, &ip_str)); - return false; - } - - return bin_pack_u08_b(bp, family) - && bin_pack_ip(bp, &ip_port->ip, is_ipv4) - && bin_pack_u16_b(bp, net_ntohs(ip_port->port)); -} - -non_null() -static bool bin_pack_ip_port_handler(Bin_Pack *bp, const Logger *logger, const void *obj) -{ - const IP_Port *ip_port = (const IP_Port *)obj; - return bin_pack_ip_port(bp, logger, ip_port); -} - -int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_Port *ip_port) -{ - const uint32_t size = bin_pack_obj_size(bin_pack_ip_port_handler, logger, ip_port); - - if (size > length) { - return -1; - } - - if (!bin_pack_obj(bin_pack_ip_port_handler, logger, ip_port, data, length)) { - return -1; - } - - assert(size < INT_MAX); - return (int)size; -} - int dht_create_packet(const Memory *mem, const Random *rng, const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t *shared_key, const uint8_t type, @@ -478,72 +399,12 @@ int dht_create_packet(const Memory *mem, const Random *rng, return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length; } -int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool tcp_enabled) -{ - if (data == nullptr) { - return -1; - } - - bool is_ipv4; - Family host_family; - - if (data[0] == TOX_AF_INET) { - is_ipv4 = true; - host_family = net_family_ipv4(); - } else if (data[0] == TOX_TCP_INET) { - if (!tcp_enabled) { - return -1; - } - - is_ipv4 = true; - host_family = net_family_tcp_ipv4(); - } else if (data[0] == TOX_AF_INET6) { - is_ipv4 = false; - host_family = net_family_ipv6(); - } else if (data[0] == TOX_TCP_INET6) { - if (!tcp_enabled) { - return -1; - } - - is_ipv4 = false; - host_family = net_family_tcp_ipv6(); - } else { - return -1; - } - - ipport_reset(ip_port); - - if (is_ipv4) { - const uint32_t size = 1 + SIZE_IP4 + sizeof(uint16_t); - - if (size > length) { - return -1; - } - - ip_port->ip.family = host_family; - memcpy(&ip_port->ip.ip.v4, data + 1, SIZE_IP4); - memcpy(&ip_port->port, data + 1 + SIZE_IP4, sizeof(uint16_t)); - return size; - } else { - const uint32_t size = 1 + SIZE_IP6 + sizeof(uint16_t); - - if (size > length) { - return -1; - } - - ip_port->ip.family = host_family; - memcpy(&ip_port->ip.ip.v6, data + 1, SIZE_IP6); - memcpy(&ip_port->port, data + 1 + SIZE_IP6, sizeof(uint16_t)); - return size; - } -} - /** @brief Pack a single node from a node array. * * @retval true on success. */ non_null() -static bool bin_pack_node_handler(Bin_Pack *bp, const Logger *logger, const void *arr, uint32_t index) +static bool bin_pack_node_handler(const void *arr, uint32_t index, const Logger *logger, Bin_Pack *bp) { const Node_format *nodes = (const Node_format *)arr; return bin_pack_ip_port(bp, logger, &nodes[index].ip_port) @@ -552,8 +413,8 @@ static bool bin_pack_node_handler(Bin_Pack *bp, const Logger *logger, const void int pack_nodes(const Logger *logger, uint8_t *data, uint16_t length, const Node_format *nodes, uint16_t number) { - const uint32_t size = bin_pack_obj_array_size(bin_pack_node_handler, logger, nodes, number); - if (!bin_pack_obj_array(bin_pack_node_handler, logger, nodes, number, data, length)) { + const uint32_t size = bin_pack_obj_array_b_size(bin_pack_node_handler, nodes, number, logger); + if (!bin_pack_obj_array_b(bin_pack_node_handler, nodes, number, logger, data, length)) { return -1; } return size; @@ -585,7 +446,7 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed #ifndef NDEBUG const uint32_t increment = ipp_size + CRYPTO_PUBLIC_KEY_SIZE; assert(increment == PACKED_NODE_SIZE_IP4 || increment == PACKED_NODE_SIZE_IP6); -#endif +#endif /* NDEBUG */ } if (processed_data_len != nullptr) { @@ -751,8 +612,8 @@ static bool client_or_ip_port_in_list(const Logger *log, const Mono_Time *mono_t } bool add_to_list( - Node_format *nodes_list, uint32_t length, const uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE], - const IP_Port *ip_port, const uint8_t cmp_pk[CRYPTO_PUBLIC_KEY_SIZE]) + Node_format *nodes_list, uint32_t length, const uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE], + const IP_Port *ip_port, const uint8_t cmp_pk[CRYPTO_PUBLIC_KEY_SIZE]) { for (uint32_t i = 0; i < length; ++i) { Node_format *node = &nodes_list[i]; @@ -782,10 +643,10 @@ bool add_to_list( */ non_null() static void get_close_nodes_inner( - uint64_t cur_time, const uint8_t *public_key, - Node_format *nodes_list, uint32_t *num_nodes_ptr, - Family sa_family, const Client_data *client_list, uint32_t client_list_length, - bool is_lan, bool want_announce) + uint64_t cur_time, const uint8_t *public_key, + Node_format *nodes_list, uint32_t *num_nodes_ptr, + Family sa_family, const Client_data *client_list, uint32_t client_list_length, + bool is_lan, bool want_announce) { if (!net_family_is_ipv4(sa_family) && !net_family_is_ipv6(sa_family) && !net_family_is_unspec(sa_family)) { return; @@ -829,7 +690,7 @@ static void get_close_nodes_inner( continue; } -#endif +#endif /* CHECK_ANNOUNCE_NODE */ if (num_nodes < MAX_SENT_NODES) { memcpy(nodes_list[num_nodes].public_key, client->public_key, CRYPTO_PUBLIC_KEY_SIZE); @@ -853,43 +714,45 @@ static void get_close_nodes_inner( */ non_null() static int get_somewhat_close_nodes( - uint64_t cur_time, const uint8_t *public_key, Node_format *nodes_list, - Family sa_family, const Client_data *close_clientlist, - const DHT_Friend *friends_list, uint16_t friends_list_size, - bool is_lan, bool want_announce) + uint64_t cur_time, const uint8_t *public_key, Node_format nodes_list[MAX_SENT_NODES], + Family sa_family, const Client_data *close_clientlist, + const DHT_Friend *friends_list, uint16_t friends_list_size, + bool is_lan, bool want_announce) { - memset(nodes_list, 0, MAX_SENT_NODES * sizeof(Node_format)); + for (uint16_t i = 0; i < MAX_SENT_NODES; ++i) { + nodes_list[i] = empty_node_format; + } uint32_t num_nodes = 0; get_close_nodes_inner( - cur_time, public_key, - nodes_list, &num_nodes, - sa_family, close_clientlist, LCLIENT_LIST, - is_lan, want_announce); + cur_time, public_key, + nodes_list, &num_nodes, + sa_family, close_clientlist, LCLIENT_LIST, + is_lan, want_announce); for (uint16_t i = 0; i < friends_list_size; ++i) { const DHT_Friend *dht_friend = &friends_list[i]; get_close_nodes_inner( - cur_time, public_key, - nodes_list, &num_nodes, - sa_family, dht_friend->client_list, MAX_FRIEND_CLIENTS, - is_lan, want_announce); + cur_time, public_key, + nodes_list, &num_nodes, + sa_family, dht_friend->client_list, MAX_FRIEND_CLIENTS, + is_lan, want_announce); } return num_nodes; } int get_close_nodes( - const DHT *dht, const uint8_t *public_key, - Node_format *nodes_list, Family sa_family, - bool is_lan, bool want_announce) + const DHT *dht, const uint8_t *public_key, + Node_format nodes_list[MAX_SENT_NODES], Family sa_family, + bool is_lan, bool want_announce) { return get_somewhat_close_nodes( - dht->cur_time, public_key, nodes_list, - sa_family, dht->close_clientlist, - dht->friends_list, dht->num_friends, - is_lan, want_announce); + dht->cur_time, public_key, nodes_list, + sa_family, dht->close_clientlist, + dht->friends_list, dht->num_friends, + is_lan, want_announce); } typedef struct DHT_Cmp_Data { @@ -1035,7 +898,7 @@ static int handle_data_search_response(void *object, const IP_Port *source, return 0; } -#endif +#endif /* CHECK_ANNOUNCE_NODE */ /** @brief Is it ok to store node with public_key in client. * @@ -1101,7 +964,8 @@ static void update_client_with_reset(const Mono_Time *mono_time, Client_data *cl ipptp_write->ret_ip_self = false; /* zero out other address */ - memset(ipptp_clear, 0, sizeof(*ipptp_clear)); + const IPPTsPng empty_ipptp = {{{{0}}}}; + *ipptp_clear = empty_ipptp; } /** @@ -1180,7 +1044,7 @@ static bool add_to_close(DHT *dht, const uint8_t *public_key, const IP_Port *ip_ #ifdef CHECK_ANNOUNCE_NODE client->announce_node = false; send_announce_ping(dht, public_key, ip_port); -#endif +#endif /* CHECK_ANNOUNCE_NODE */ return true; } @@ -1298,7 +1162,7 @@ static bool ping_node_from_getnodes_ok(DHT *dht, const uint8_t *public_key, cons */ uint32_t addto_lists(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key) { - IP_Port ipp_copy = ip_port_normalize(ip_port); + const IP_Port ipp_copy = ip_port_normalize(ip_port); uint32_t used = 0; @@ -1384,7 +1248,7 @@ static bool update_client_data(const Mono_Time *mono_time, Client_data *array, s non_null() static void returnedip_ports(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *nodepublic_key) { - IP_Port ipp_copy = ip_port_normalize(ip_port); + const IP_Port ipp_copy = ip_port_normalize(ip_port); if (pk_equal(public_key, dht->self_public_key)) { update_client_data(dht->mono_time, dht->close_clientlist, LCLIENT_LIST, &ipp_copy, nodepublic_key, true); @@ -1484,13 +1348,14 @@ static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t memcpy(plain + 1 + nodes_length, sendback_data, length); const uint32_t crypto_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE; - VLA(uint8_t, data, 1 + nodes_length + length + crypto_size); + const uint32_t data_size = 1 + nodes_length + length + crypto_size; + 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, - plain, 1 + nodes_length + length, data, SIZEOF_VLA(data)); + plain, 1 + nodes_length + length, data, data_size); - if (len != SIZEOF_VLA(data)) { + if (len != data_size) { return -1; } @@ -1573,7 +1438,8 @@ static bool handle_sendnodes_core(void *object, const IP_Port *source, const uin return false; } - VLA(uint8_t, plain, 1 + data_size + sizeof(uint64_t)); + const uint32_t plain_size = 1 + data_size + sizeof(uint64_t); + VLA(uint8_t, plain, plain_size); const uint8_t *shared_key = dht_get_shared_key_sent(dht, packet + 1); const int len = decrypt_data_symmetric( shared_key, @@ -1582,7 +1448,7 @@ static bool handle_sendnodes_core(void *object, const IP_Port *source, const uin 1 + data_size + sizeof(uint64_t) + CRYPTO_MAC_SIZE, plain); - if ((unsigned int)len != SIZEOF_VLA(plain)) { + if ((uint32_t)len != plain_size) { return false; } @@ -1655,7 +1521,7 @@ static int handle_sendnodes_ipv6(void *object, const IP_Port *source, const uint non_null(1) nullable(2, 3) static uint32_t dht_friend_lock(DHT_Friend *const dht_friend, dht_ip_cb *ip_callback, - void *data, int32_t number) + void *data, int32_t number) { // find first free slot uint8_t lock_num; @@ -1974,8 +1840,8 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key) return dht_getnodes(dht, ip_port, public_key, dht->self_public_key); } -int dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, - uint16_t port, const uint8_t *public_key) +bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, + uint16_t port, const uint8_t *public_key) { IP_Port ip_port_v64; IP *ip_extra = nullptr; @@ -1998,10 +1864,10 @@ int dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, dht_bootstrap(dht, &ip_port_v4, public_key); } - return 1; + return true; } - return 0; + return false; } int route_packet(const DHT *dht, const uint8_t *public_key, const uint8_t *packet, uint16_t length) @@ -2103,7 +1969,6 @@ static int friend_iplist(const DHT *dht, IP_Port *ip_portlist, uint16_t friend_n #endif /* !FRIEND_IPLIST_PAD */ } - /** * Callback invoked for each IP/port of each client of a friend. * @@ -2190,7 +2055,6 @@ uint32_t route_to_friend(const DHT *dht, const uint8_t *friend_id, const Packet return 0; } - IP_Port ip_list[MAX_FRIEND_CLIENTS]; const int ip_num = friend_iplist(dht, ip_list, num); @@ -2426,7 +2290,7 @@ static void punch_holes(DHT *dht, const IP *ip, const uint16_t *port_list, uint1 uint16_t i; for (i = 0; i < MAX_PUNCHING_PORTS; ++i) { - uint32_t it = i + dht->friends_list[friend_num].nat.punching_index2; + const uint32_t it = i + dht->friends_list[friend_num].nat.punching_index2; const uint16_t port = 1024; pinging.port = net_htons(port + it); ping_send_request(dht->ping, &pinging, dht->friends_list[friend_num].public_key); @@ -2691,7 +2555,7 @@ DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Netw #ifdef CHECK_ANNOUNCE_NODE networking_registerhandler(dht->net, NET_PACKET_DATA_SEARCH_RESPONSE, &handle_data_search_response, dht); -#endif +#endif /* CHECK_ANNOUNCE_NODE */ crypto_new_keypair(rng, dht->self_public_key, dht->self_secret_key); @@ -2704,7 +2568,6 @@ DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Netw return nullptr; } - dht->dht_ping_array = ping_array_new(mem, DHT_PING_ARRAY_SIZE, PING_TIMEOUT); if (dht->dht_ping_array == nullptr) { @@ -2795,21 +2658,21 @@ uint32_t dht_size(const DHT *dht) uint32_t numv6 = 0; for (uint32_t i = 0; i < dht->loaded_num_nodes; ++i) { - numv4 += net_family_is_ipv4(dht->loaded_nodes_list[i].ip_port.ip.family); - numv6 += net_family_is_ipv6(dht->loaded_nodes_list[i].ip_port.ip.family); + numv4 += net_family_is_ipv4(dht->loaded_nodes_list[i].ip_port.ip.family) ? 1 : 0; + numv6 += net_family_is_ipv6(dht->loaded_nodes_list[i].ip_port.ip.family) ? 1 : 0; } for (uint32_t i = 0; i < LCLIENT_LIST; ++i) { - numv4 += dht->close_clientlist[i].assoc4.timestamp != 0; - numv6 += dht->close_clientlist[i].assoc6.timestamp != 0; + numv4 += dht->close_clientlist[i].assoc4.timestamp != 0 ? 1 : 0; + numv6 += dht->close_clientlist[i].assoc6.timestamp != 0 ? 1 : 0; } for (uint32_t i = 0; i < DHT_FAKE_FRIEND_NUMBER && i < dht->num_friends; ++i) { const DHT_Friend *const fr = &dht->friends_list[i]; for (uint32_t j = 0; j < MAX_FRIEND_CLIENTS; ++j) { - numv4 += fr->client_list[j].assoc4.timestamp != 0; - numv6 += fr->client_list[j].assoc6.timestamp != 0; + numv4 += fr->client_list[j].assoc4.timestamp != 0 ? 1 : 0; + numv6 += fr->client_list[j].assoc6.timestamp != 0 ? 1 : 0; } } @@ -2877,8 +2740,8 @@ void dht_save(const DHT *dht, uint8_t *data) } state_write_section_header( - old_data, DHT_STATE_COOKIE_TYPE, pack_nodes(dht->log, data, sizeof(Node_format) * num, clients, num), - DHT_STATE_TYPE_NODES); + old_data, DHT_STATE_COOKIE_TYPE, pack_nodes(dht->log, data, sizeof(Node_format) * num, clients, num), + DHT_STATE_TYPE_NODES); mem_delete(dht->mem, clients); } @@ -3017,7 +2880,8 @@ bool dht_non_lan_connected(const DHT *dht) return false; } -uint16_t dht_get_num_closelist(const DHT *dht) { +uint16_t dht_get_num_closelist(const DHT *dht) +{ uint16_t num_valid_close_clients = 0; for (uint32_t i = 0; i < LCLIENT_LIST; ++i) { const Client_data *const client = dht_get_close_client(dht, i); @@ -3031,7 +2895,8 @@ uint16_t dht_get_num_closelist(const DHT *dht) { return num_valid_close_clients; } -uint16_t dht_get_num_closelist_announce_capable(const DHT *dht) { +uint16_t dht_get_num_closelist_announce_capable(const DHT *dht) +{ uint16_t num_valid_close_clients_with_cap = 0; for (uint32_t i = 0; i < LCLIENT_LIST; ++i) { const Client_data *const client = dht_get_close_client(dht, i); diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 8dedc470..19a9e1d9 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -23,20 +23,6 @@ extern "C" { #endif -/* Encryption and signature keys definition */ -#define ENC_PUBLIC_KEY_SIZE CRYPTO_PUBLIC_KEY_SIZE -#define ENC_SECRET_KEY_SIZE CRYPTO_SECRET_KEY_SIZE -#define SIG_PUBLIC_KEY_SIZE CRYPTO_SIGN_PUBLIC_KEY_SIZE -#define SIG_SECRET_KEY_SIZE CRYPTO_SIGN_SECRET_KEY_SIZE - -/* Size of the group chat_id */ -#define CHAT_ID_SIZE SIG_PUBLIC_KEY_SIZE - -/* Extended keys for group chats */ -#define EXT_SECRET_KEY_SIZE (ENC_SECRET_KEY_SIZE + SIG_SECRET_KEY_SIZE) -#define EXT_PUBLIC_KEY_SIZE (ENC_PUBLIC_KEY_SIZE + SIG_PUBLIC_KEY_SIZE) - - /* Maximum size of a signature (may be smaller) */ #define SIGNATURE_SIZE CRYPTO_SIGNATURE_SIZE /** Maximum number of clients stored per friend. */ @@ -169,7 +155,7 @@ typedef struct Client_data { #ifdef CHECK_ANNOUNCE_NODE /* Responded to data search? */ bool announce_node; -#endif +#endif /* CHECK_ANNOUNCE_NODE */ } Client_data; /*----------------------------------------------------------------------------------*/ @@ -204,26 +190,6 @@ non_null() const Client_data *dht_friend_client(const DHT_Friend *dht_friend, si */ int packed_node_size(Family ip_family); -/** @brief Pack an IP_Port structure into data of max size length. - * - * Packed_length is the offset of data currently packed. - * - * @return size of packed IP_Port data on success. - * @retval -1 on failure. - */ -non_null() -int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_Port *ip_port); - -/** @brief Unpack IP_Port structure from data of max size length into ip_port. - * - * len_processed is the offset of data currently unpacked. - * - * @return size of unpacked ip_port on success. - * @retval -1 on failure. - */ -non_null() -int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool tcp_enabled); - /** @brief Encrypt plain and write resulting DHT packet into packet with max size length. * * @return size of packet on success. @@ -257,8 +223,8 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed /*----------------------------------------------------------------------------------*/ -typedef int cryptopacket_handler_cb(void *object, const IP_Port *ip_port, const uint8_t *source_pubkey, - const uint8_t *data, uint16_t len, void *userdata); +typedef int cryptopacket_handler_cb(void *object, const IP_Port *source, const uint8_t *source_pubkey, + const uint8_t *packet, uint16_t length, void *userdata); typedef struct DHT DHT; @@ -370,8 +336,8 @@ unsigned int bit_by_bit_cmp(const uint8_t *pk1, const uint8_t *pk2); */ non_null() bool add_to_list( - Node_format *nodes_list, uint32_t length, const uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE], - const IP_Port *ip_port, const uint8_t cmp_pk[CRYPTO_PUBLIC_KEY_SIZE]); + Node_format *nodes_list, uint32_t length, const uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE], + const IP_Port *ip_port, const uint8_t cmp_pk[CRYPTO_PUBLIC_KEY_SIZE]); /** Return 1 if node can be added to close list, 0 if it can't. */ non_null() @@ -381,7 +347,7 @@ bool node_addable_to_close_list(DHT *dht, const uint8_t *public_key, const IP_Po /** Set node as announce node. */ non_null() void set_announce_node(DHT *dht, const uint8_t *public_key); -#endif +#endif /* CHECK_ANNOUNCE_NODE */ /** * @brief Get the (maximum MAX_SENT_NODES) closest nodes to public_key we know @@ -395,10 +361,9 @@ void set_announce_node(DHT *dht, const uint8_t *public_key); */ non_null() int get_close_nodes( - const DHT *dht, const uint8_t *public_key, - Node_format *nodes_list, Family sa_family, - bool is_lan, bool want_announce); - + const DHT *dht, const uint8_t *public_key, + Node_format nodes_list[MAX_SENT_NODES], Family sa_family, + bool is_lan, bool want_announce); /** @brief Put up to max_num nodes in nodes from the random friends. * @@ -440,12 +405,12 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key); * @param ipv6enabled if false, the resolving sticks STRICTLY to IPv4 addresses. * Otherwise, the resolving looks for IPv6 addresses first, then IPv4 addresses. * - * @retval 1 if the address could be converted into an IP address - * @retval 0 otherwise + * @retval true if the address could be converted into an IP address + * @retval false otherwise */ non_null() -int dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, - uint16_t port, const uint8_t *public_key); +bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, + uint16_t port, const uint8_t *public_key); /** @brief Start sending packets after DHT loaded_friends_list and loaded_clients_list are set. * @@ -558,7 +523,7 @@ non_null() unsigned int ipport_self_copy(const DHT *dht, IP_Port *dest); #ifdef __cplusplus -} // extern "C" +} /* extern "C" */ #endif -#endif +#endif /* C_TOXCORE_TOXCORE_DHT_H */ diff --git a/toxcore/DHT_fuzz_test.cc b/toxcore/DHT_fuzz_test.cc index e741e9b2..868aedec 100644 --- a/toxcore/DHT_fuzz_test.cc +++ b/toxcore/DHT_fuzz_test.cc @@ -5,7 +5,7 @@ #include #include -#include "../testing/fuzzing/fuzz_support.h" +#include "../testing/fuzzing/fuzz_support.hh" namespace { diff --git a/toxcore/DHT_test.cc b/toxcore/DHT_test.cc index 34841c74..1028fc7f 100644 --- a/toxcore/DHT_test.cc +++ b/toxcore/DHT_test.cc @@ -11,8 +11,12 @@ #include "DHT_test_util.hh" #include "crypto_core.h" #include "crypto_core_test_util.hh" +#include "logger.h" #include "mem_test_util.hh" +#include "mono_time.h" +#include "network.h" #include "network_test_util.hh" +#include "test_util.hh" namespace { diff --git a/toxcore/DHT_test_util.cc b/toxcore/DHT_test_util.cc index 15e679f2..b87b5859 100644 --- a/toxcore/DHT_test_util.cc +++ b/toxcore/DHT_test_util.cc @@ -3,7 +3,10 @@ #include #include +#include "DHT.h" +#include "crypto_core.h" #include "crypto_core_test_util.hh" +#include "network.h" #include "network_test_util.hh" Node_format random_node_format(const Random *rng) diff --git a/toxcore/DHT_test_util.hh b/toxcore/DHT_test_util.hh index 5fa75b7f..9c510c45 100644 --- a/toxcore/DHT_test_util.hh +++ b/toxcore/DHT_test_util.hh @@ -4,6 +4,7 @@ #include #include "DHT.h" +#include "crypto_core.h" #include "test_util.hh" template <> diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index ce34551d..aead9759 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -9,7 +9,6 @@ #include "LAN_discovery.h" #include -#include #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) // The mingw32/64 Windows library warns about including winsock2.h after @@ -21,7 +20,7 @@ #include #include -#endif +#endif /* WIN32 */ #if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) #include @@ -29,23 +28,23 @@ #include #include #include -#endif +#endif /* Linux/BSD */ #ifdef __linux__ #include -#endif +#endif /* Linux */ #if defined(__FreeBSD__) || defined(__DragonFly__) #include -#endif +#endif /* BSD */ +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "network.h" #define MAX_INTERFACES 16 - struct Broadcast_Info { uint32_t count; IP ips[MAX_INTERFACES]; @@ -143,14 +142,13 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns) } /* Configure ifconf for the ioctl call. */ - struct ifreq i_faces[MAX_INTERFACES]; - memset(i_faces, 0, sizeof(struct ifreq) * MAX_INTERFACES); + struct ifreq i_faces[MAX_INTERFACES] = {{{0}}}; struct ifconf ifc; ifc.ifc_buf = (char *)i_faces; ifc.ifc_len = sizeof(i_faces); - if (ioctl(sock.sock, SIOCGIFCONF, &ifc) < 0) { + if (ioctl(net_socket_to_native(sock), SIOCGIFCONF, &ifc) < 0) { kill_sock(ns, sock); free(broadcast); return nullptr; @@ -165,7 +163,7 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns) for (int i = 0; i < n; ++i) { /* there are interfaces with are incapable of broadcast */ - if (ioctl(sock.sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) { + if (ioctl(net_socket_to_native(sock), SIOCGIFBRDADDR, &i_faces[i]) < 0) { continue; } @@ -204,7 +202,7 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns) return (Broadcast_Info *)calloc(1, sizeof(Broadcast_Info)); } -#endif +#endif /* platforms */ /** @brief Send packet to all IPv4 broadcast addresses * @@ -241,8 +239,8 @@ static IP broadcast_ip(Family family_socket, Family family_broadcast) /* `FF02::1` is - according to RFC 4291 - multicast all-nodes link-local */ /* `FE80::*:` MUST be exact, for that we would need to look over all * interfaces and check in which status they are */ - ip.ip.v6.uint8[ 0] = 0xFF; - ip.ip.v6.uint8[ 1] = 0x02; + ip.ip.v6.uint8[0] = 0xFF; + ip.ip.v6.uint8[1] = 0x02; ip.ip.v6.uint8[15] = 0x01; } else if (net_family_is_ipv4(family_broadcast)) { ip.family = net_family_ipv6(); @@ -341,7 +339,6 @@ bool ip_is_lan(const IP *ip) return false; } - bool lan_discovery_send(const Networking_Core *net, const Broadcast_Info *broadcast, const uint8_t *dht_pk, uint16_t port) { @@ -378,7 +375,6 @@ bool lan_discovery_send(const Networking_Core *net, const Broadcast_Info *broadc return res; } - Broadcast_Info *lan_discovery_init(const Network *ns) { return fetch_broadcast_info(ns); diff --git a/toxcore/LAN_discovery.h b/toxcore/LAN_discovery.h index 5d9c8333..94e5d358 100644 --- a/toxcore/LAN_discovery.h +++ b/toxcore/LAN_discovery.h @@ -9,6 +9,7 @@ #ifndef C_TOXCORE_TOXCORE_LAN_DISCOVERY_H #define C_TOXCORE_TOXCORE_LAN_DISCOVERY_H +#include "attributes.h" #include "network.h" /** @@ -53,4 +54,4 @@ bool ip_is_local(const IP *ip); non_null() bool ip_is_lan(const IP *ip); -#endif // C_TOXCORE_TOXCORE_LAN_DISCOVERY_H +#endif /* C_TOXCORE_TOXCORE_LAN_DISCOVERY_H */ diff --git a/toxcore/Makefile.inc b/toxcore/Makefile.inc index 0663171f..db3e1932 100644 --- a/toxcore/Makefile.inc +++ b/toxcore/Makefile.inc @@ -1,8 +1,7 @@ lib_LTLIBRARIES += libtoxcore.la libtoxcore_la_include_HEADERS = \ - ../toxcore/tox.h \ - ../toxcore/tox_private.h + ../toxcore/tox.h libtoxcore_la_includedir = $(includedir)/tox @@ -21,6 +20,7 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.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/events_alloc.c \ ../toxcore/events/events_alloc.h \ ../toxcore/events/file_chunk_request.c \ @@ -66,6 +66,8 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \ ../toxcore/network.c \ ../toxcore/crypto_core.h \ ../toxcore/crypto_core.c \ + ../toxcore/crypto_core_pack.h \ + ../toxcore/crypto_core_pack.c \ ../toxcore/timed_auth.h \ ../toxcore/timed_auth.c \ ../toxcore/ping_array.h \ diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index bdf17112..947edef7 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -18,6 +18,7 @@ #include "TCP_connection.h" #include "TCP_server.h" #include "announce.h" +#include "attributes.h" #include "bin_pack.h" #include "bin_unpack.h" #include "ccompat.h" @@ -138,25 +139,25 @@ void getaddress(const Messenger *m, uint8_t *address) non_null() static bool send_online_packet(Messenger *m, int friendcon_id) { - uint8_t packet = PACKET_ID_ONLINE; - return write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, friendcon_id), &packet, + const uint8_t packet[1] = {PACKET_ID_ONLINE}; + return write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, friendcon_id), packet, sizeof(packet), false) != -1; } non_null() static bool send_offline_packet(Messenger *m, int friendcon_id) { - uint8_t packet = PACKET_ID_OFFLINE; - return write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, friendcon_id), &packet, + const uint8_t packet[1] = {PACKET_ID_OFFLINE}; + return write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, friendcon_id), packet, sizeof(packet), false) != -1; } non_null(1) nullable(4) -static int m_handle_status(void *object, int i, bool status, void *userdata); +static int m_handle_status(void *object, int friendcon_id, bool status, void *userdata); non_null(1, 3) nullable(5) -static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t len, void *userdata); +static int m_handle_packet(void *object, int friendcon_id, const uint8_t *data, uint16_t length, void *userdata); non_null(1, 3) nullable(5) -static int m_handle_lossy_packet(void *object, int friend_num, const uint8_t *packet, uint16_t length, +static int m_handle_lossy_packet(void *object, int friendcon_id, const uint8_t *data, uint16_t length, void *userdata); non_null() @@ -403,7 +404,7 @@ bool m_create_group_connection(Messenger *m, GC_Chat *chat) const int onion_friend_number = friend_conn_get_onion_friendnum(connection); Onion_Friend *onion_friend = onion_get_friend(m->onion_c, (uint16_t)onion_friend_number); - onion_friend_set_gc_public_key(onion_friend, get_chat_id(chat->chat_public_key)); + onion_friend_set_gc_public_key(onion_friend, get_chat_id(&chat->chat_public_key)); onion_friend_set_gc_data(onion_friend, nullptr, 0); return true; @@ -472,7 +473,7 @@ int m_delfriend(Messenger *m, int32_t friendnumber) } if (m->friend_connectionstatuschange_internal != nullptr) { - m->friend_connectionstatuschange_internal(m, friendnumber, 0, m->friend_connectionstatuschange_internal_userdata); + m->friend_connectionstatuschange_internal(m, friendnumber, false, m->friend_connectionstatuschange_internal_userdata); } clear_receipts(m, friendnumber); @@ -591,7 +592,7 @@ int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, con memcpy(packet + 1, message, length); const int64_t packet_num = write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, - m->friendlist[friendnumber].friendcon_id), packet, length + 1, false); + m->friendlist[friendnumber].friendcon_id), packet, length + 1, false); if (packet_num == -1) { return -4; @@ -857,7 +858,7 @@ int m_copy_statusmessage(const Messenger *m, int32_t friendnumber, uint8_t *buf, const uint32_t msglen = min_u32(maxlen, m->friendlist[friendnumber].statusmessage_length); memcpy(buf, m->friendlist[friendnumber].statusmessage, msglen); - memset(buf + msglen, 0, maxlen - msglen); + memzero(buf + msglen, maxlen - msglen); return msglen; } @@ -1097,7 +1098,6 @@ static void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status /*** CONFERENCES */ - /** @brief Set the callback for conference invites. */ void m_callback_conference_invite(Messenger *m, m_conference_invite_cb *function) { @@ -1120,20 +1120,17 @@ bool send_conference_invite_packet(const Messenger *m, int32_t friendnumber, con return write_cryptpacket_id(m, friendnumber, PACKET_ID_INVITE_CONFERENCE, data, length, false); } - /** @brief Send a group invite packet. * * @retval true if success */ -bool send_group_invite_packet(const Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length) +bool send_group_invite_packet(const Messenger *m, uint32_t friendnumber, const uint8_t *packet, uint16_t length) { - return write_cryptpacket_id(m, friendnumber, PACKET_ID_INVITE_GROUPCHAT, data, length, false); + return write_cryptpacket_id(m, friendnumber, PACKET_ID_INVITE_GROUPCHAT, packet, length, false); } - /*** FILE SENDING */ - /** @brief Set the callback for file send requests. */ void callback_file_sendrequest(Messenger *m, m_file_recv_cb *function) { @@ -1195,8 +1192,8 @@ int file_get_id(const Messenger *m, int32_t friendnumber, uint32_t filenumber, u file_number = temp_filenum; const struct File_Transfers *const ft = inbound - ? &m->friendlist[friendnumber].file_receiving[file_number] - : &m->friendlist[friendnumber].file_sending[file_number]; + ? &m->friendlist[friendnumber].file_receiving[file_number] + : &m->friendlist[friendnumber].file_sending[file_number]; if (ft->status == FILESTATUS_NONE) { return -2; @@ -1223,7 +1220,8 @@ static bool file_sendrequest(const Messenger *m, int32_t friendnumber, uint8_t f return false; } - VLA(uint8_t, packet, 1 + sizeof(file_type) + sizeof(filesize) + FILE_ID_LENGTH + filename_length); + const uint16_t packet_size = 1 + sizeof(file_type) + sizeof(filesize) + FILE_ID_LENGTH + filename_length; + VLA(uint8_t, packet, packet_size); packet[0] = filenumber; file_type = net_htonl(file_type); memcpy(packet + 1, &file_type, sizeof(file_type)); @@ -1234,7 +1232,7 @@ static bool file_sendrequest(const Messenger *m, int32_t friendnumber, uint8_t f memcpy(packet + 1 + sizeof(file_type) + sizeof(filesize) + FILE_ID_LENGTH, filename, filename_length); } - return write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_SENDREQUEST, packet, SIZEOF_VLA(packet), false); + return write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_SENDREQUEST, packet, packet_size, false); } /** @brief Send a file send request. @@ -1301,7 +1299,8 @@ static bool send_file_control_packet(const Messenger *m, int32_t friendnumber, b return false; } - VLA(uint8_t, packet, 3 + data_length); + const uint16_t packet_size = 3 + data_length; + VLA(uint8_t, packet, packet_size); packet[0] = inbound ? 1 : 0; packet[1] = filenumber; @@ -1311,7 +1310,7 @@ static bool send_file_control_packet(const Messenger *m, int32_t friendnumber, b memcpy(packet + 3, data, data_length); } - return write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_CONTROL, packet, SIZEOF_VLA(packet), false); + return write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_CONTROL, packet, packet_size, false); } /** @brief Send a file control request. @@ -1501,7 +1500,8 @@ static int64_t send_file_data_packet(const Messenger *m, int32_t friendnumber, u return -1; } - VLA(uint8_t, packet, 2 + length); + const uint16_t packet_size = 2 + length; + VLA(uint8_t, packet, packet_size); packet[0] = PACKET_ID_FILE_DATA; packet[1] = filenumber; @@ -1510,7 +1510,7 @@ static int64_t send_file_data_packet(const Messenger *m, int32_t friendnumber, u } return write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, - m->friendlist[friendnumber].friendcon_id), packet, SIZEOF_VLA(packet), true); + m->friendlist[friendnumber].friendcon_id), packet, packet_size, true); } #define MAX_FILE_DATA_SIZE (MAX_CRYPTO_DATA_SIZE - 2) @@ -1712,7 +1712,6 @@ static void do_reqchunk_filecb(Messenger *m, int32_t friendnumber, void *userdat } } - /** @brief Run this when the friend disconnects. * Kill all current file transfers. */ @@ -1873,28 +1872,28 @@ bool m_msi_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, return write_cryptpacket_id(m, friendnumber, PACKET_ID_MSI, data, length, false); } -static int m_handle_lossy_packet(void *object, int friend_num, const uint8_t *packet, uint16_t length, +static int m_handle_lossy_packet(void *object, int friendcon_id, const uint8_t *data, uint16_t length, void *userdata) { Messenger *m = (Messenger *)object; - if (!m_friend_exists(m, friend_num)) { + if (!m_friend_exists(m, friendcon_id)) { return 1; } - if (packet[0] <= PACKET_ID_RANGE_LOSSY_AV_END) { + if (data[0] <= PACKET_ID_RANGE_LOSSY_AV_END) { const RTP_Packet_Handler *const ph = - &m->friendlist[friend_num].lossy_rtp_packethandlers[packet[0] % PACKET_ID_RANGE_LOSSY_AV_SIZE]; + &m->friendlist[friendcon_id].lossy_rtp_packethandlers[data[0] % PACKET_ID_RANGE_LOSSY_AV_SIZE]; if (ph->function != nullptr) { - return ph->function(m, friend_num, packet, length, ph->object); + return ph->function(m, friendcon_id, data, length, ph->object); } return 1; } if (m->lossy_packethandler != nullptr) { - m->lossy_packethandler(m, friend_num, packet[0], packet, length, userdata); + m->lossy_packethandler(m, friendcon_id, data[0], data, length, userdata); } return 1; @@ -1921,7 +1920,6 @@ int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte, m_lo return 0; } - /** @brief High level function to send custom lossy packets. * * TODO(oxij): this name is confusing, because this function sends both av and custom lossy packets. @@ -2020,11 +2018,11 @@ int send_custom_lossless_packet(const Messenger *m, int32_t friendnumber, const /** Function to filter out some friend requests*/ non_null() -static int friend_already_added(const uint8_t *real_pk, void *data) +static int friend_already_added(void *object, const uint8_t *public_key) { - const Messenger *m = (const Messenger *)data; + const Messenger *m = (const Messenger *)object; - if (getfriend_id(m, real_pk) == -1) { + if (getfriend_id(m, public_key) == -1) { return 0; } @@ -2034,16 +2032,16 @@ static int friend_already_added(const uint8_t *real_pk, void *data) /** @brief Check for and handle a timed-out friend request. * * If the request has timed-out then the friend status is set back to FRIEND_ADDED. - * @param i friendlist index of the timed-out friend + * @param friendcon_id friendlist index of the timed-out friend * @param t time */ non_null(1) nullable(4) -static void check_friend_request_timed_out(Messenger *m, uint32_t i, uint64_t t, void *userdata) +static void check_friend_request_timed_out(Messenger *m, uint32_t friendcon_id, uint64_t t, void *userdata) { - Friend *f = &m->friendlist[i]; + Friend *f = &m->friendlist[friendcon_id]; if (f->friendrequest_lastsent + f->friendrequest_timeout < t) { - set_friend_status(m, i, FRIEND_ADDED, userdata); + set_friend_status(m, friendcon_id, FRIEND_ADDED, userdata); /* Double the default timeout every time if friendrequest is assumed * to have been sent unsuccessfully. */ @@ -2052,15 +2050,15 @@ static void check_friend_request_timed_out(Messenger *m, uint32_t i, uint64_t t, } non_null(1) nullable(4) -static int m_handle_status(void *object, int i, bool status, void *userdata) +static int m_handle_status(void *object, int friendcon_id, bool status, void *userdata) { Messenger *m = (Messenger *)object; if (status) { /* Went online. */ - send_online_packet(m, m->friendlist[i].friendcon_id); + send_online_packet(m, m->friendlist[friendcon_id].friendcon_id); } else { /* Went offline. */ - if (m->friendlist[i].status == FRIEND_ONLINE) { - set_friend_status(m, i, FRIEND_CONFIRMED, userdata); + if (m->friendlist[friendcon_id].status == FRIEND_ONLINE) { + set_friend_status(m, friendcon_id, FRIEND_CONFIRMED, userdata); } } @@ -2068,17 +2066,17 @@ static int m_handle_status(void *object, int i, bool status, void *userdata) } non_null(1, 3) nullable(5) -static int m_handle_packet_offline(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +static int m_handle_packet_offline(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata) { if (data_length == 0) { - set_friend_status(m, i, FRIEND_CONFIRMED, userdata); + set_friend_status(m, friendcon_id, FRIEND_CONFIRMED, userdata); } return 0; } non_null(1, 3) nullable(5) -static int m_handle_packet_nickname(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +static int m_handle_packet_nickname(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata) { if (data_length > MAX_NAME_LENGTH) { return 0; @@ -2091,17 +2089,17 @@ static int m_handle_packet_nickname(Messenger *m, const int i, const uint8_t *da /* inform of namechange before we overwrite the old name */ if (m->friend_namechange != nullptr) { - m->friend_namechange(m, i, data_terminated, data_length, userdata); + m->friend_namechange(m, friendcon_id, data_terminated, data_length, userdata); } - memcpy(m->friendlist[i].name, data_terminated, data_length); - m->friendlist[i].name_length = data_length; + memcpy(m->friendlist[friendcon_id].name, data_terminated, data_length); + m->friendlist[friendcon_id].name_length = data_length; return 0; } non_null(1, 3) nullable(5) -static int m_handle_packet_statusmessage(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +static int m_handle_packet_statusmessage(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata) { if (data_length > MAX_STATUSMESSAGE_LENGTH) { return 0; @@ -2113,16 +2111,16 @@ static int m_handle_packet_statusmessage(Messenger *m, const int i, const uint8_ data_terminated[data_length] = 0; if (m->friend_statusmessagechange != nullptr) { - m->friend_statusmessagechange(m, i, data_terminated, data_length, userdata); + m->friend_statusmessagechange(m, friendcon_id, data_terminated, data_length, userdata); } - set_friend_statusmessage(m, i, data_terminated, data_length); + set_friend_statusmessage(m, friendcon_id, data_terminated, data_length); return 0; } non_null(1, 3) nullable(5) -static int m_handle_packet_userstatus(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +static int m_handle_packet_userstatus(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata) { if (data_length != 1) { return 0; @@ -2134,16 +2132,16 @@ static int m_handle_packet_userstatus(Messenger *m, const int i, const uint8_t * } if (m->friend_userstatuschange != nullptr) { - m->friend_userstatuschange(m, i, status, userdata); + m->friend_userstatuschange(m, friendcon_id, status, userdata); } - set_friend_userstatus(m, i, status); + set_friend_userstatus(m, friendcon_id, status); return 0; } non_null(1, 3) nullable(5) -static int m_handle_packet_typing(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +static int m_handle_packet_typing(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata) { if (data_length != 1) { return 0; @@ -2151,17 +2149,17 @@ static int m_handle_packet_typing(Messenger *m, const int i, const uint8_t *data const bool typing = data[0] != 0; - set_friend_typing(m, i, typing); + set_friend_typing(m, friendcon_id, typing); if (m->friend_typingchange != nullptr) { - m->friend_typingchange(m, i, typing, userdata); + m->friend_typingchange(m, friendcon_id, typing, userdata); } return 0; } non_null(1, 3) nullable(6) -static int m_handle_packet_message(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, const Message_Type message_type, void *userdata) +static int m_handle_packet_message(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, const Message_Type message_type, void *userdata) { if (data_length == 0) { return 0; @@ -2176,28 +2174,28 @@ static int m_handle_packet_message(Messenger *m, const int i, const uint8_t *dat message_terminated[message_length] = 0; if (m->friend_message != nullptr) { - m->friend_message(m, i, message_type, message_terminated, message_length, userdata); + m->friend_message(m, friendcon_id, message_type, message_terminated, message_length, userdata); } return 0; } non_null(1, 3) nullable(5) -static int m_handle_packet_invite_conference(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +static int m_handle_packet_invite_conference(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata) { if (data_length == 0) { return 0; } if (m->conference_invite != nullptr) { - m->conference_invite(m, i, data, data_length, userdata); + m->conference_invite(m, friendcon_id, data, data_length, userdata); } return 0; } non_null(1, 3) nullable(5) -static int m_handle_packet_file_sendrequest(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +static int m_handle_packet_file_sendrequest(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata) { const unsigned int head_length = 1 + sizeof(uint32_t) + sizeof(uint64_t) + FILE_ID_LENGTH; @@ -2213,7 +2211,7 @@ static int m_handle_packet_file_sendrequest(Messenger *m, const int i, const uin return 0; } -#endif +#endif /* UINT8_MAX >= MAX_CONCURRENT_FILE_PIPES */ uint64_t filesize; uint32_t file_type; @@ -2227,7 +2225,7 @@ static int m_handle_packet_file_sendrequest(Messenger *m, const int i, const uin file_type = net_ntohl(file_type); net_unpack_u64(data + 1 + sizeof(uint32_t), &filesize); - struct File_Transfers *ft = &m->friendlist[i].file_receiving[filenumber]; + struct File_Transfers *ft = &m->friendlist[friendcon_id].file_receiving[filenumber]; if (ft->status != FILESTATUS_NONE) { return 0; @@ -2254,7 +2252,7 @@ static int m_handle_packet_file_sendrequest(Messenger *m, const int i, const uin real_filenumber <<= 16; if (m->file_sendrequest != nullptr) { - m->file_sendrequest(m, i, real_filenumber, file_type, filesize, filename, filename_length, + m->file_sendrequest(m, friendcon_id, real_filenumber, file_type, filesize, filename, filename_length, userdata); } @@ -2262,7 +2260,7 @@ static int m_handle_packet_file_sendrequest(Messenger *m, const int i, const uin } non_null(1, 3) nullable(5) -static int m_handle_packet_file_control(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +static int m_handle_packet_file_control(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata) { if (data_length < 3) { return 0; @@ -2281,9 +2279,9 @@ static int m_handle_packet_file_control(Messenger *m, const int i, const uint8_t return 0; } -#endif +#endif /* UINT8_MAX >= MAX_CONCURRENT_FILE_PIPES */ - if (handle_filecontrol(m, i, outbound, filenumber, control_type, data + 3, data_length - 3, userdata) == -1) { + if (handle_filecontrol(m, friendcon_id, outbound, filenumber, control_type, data + 3, data_length - 3, userdata) == -1) { // TODO(iphydf): Do something different here? Right now, this // check is pointless. return 0; @@ -2293,7 +2291,7 @@ static int m_handle_packet_file_control(Messenger *m, const int i, const uint8_t } non_null(1, 3) nullable(5) -static int m_handle_packet_file_data(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +static int m_handle_packet_file_data(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata) { if (data_length < 1) { return 0; @@ -2307,9 +2305,9 @@ static int m_handle_packet_file_data(Messenger *m, const int i, const uint8_t *d return 0; } -#endif +#endif /* UINT8_MAX >= MAX_CONCURRENT_FILE_PIPES */ - struct File_Transfers *ft = &m->friendlist[i].file_receiving[filenumber]; + struct File_Transfers *ft = &m->friendlist[friendcon_id].file_receiving[filenumber]; if (ft->status != FILESTATUS_TRANSFERRING) { return 0; @@ -2334,7 +2332,7 @@ static int m_handle_packet_file_data(Messenger *m, const int i, const uint8_t *d } if (m->file_filedata != nullptr) { - m->file_filedata(m, i, real_filenumber, position, file_data, file_data_length, userdata); + m->file_filedata(m, friendcon_id, real_filenumber, position, file_data, file_data_length, userdata); } ft->transferred += file_data_length; @@ -2346,7 +2344,7 @@ static int m_handle_packet_file_data(Messenger *m, const int i, const uint8_t *d /* Full file received. */ if (m->file_filedata != nullptr) { - m->file_filedata(m, i, real_filenumber, position, file_data, file_data_length, userdata); + m->file_filedata(m, friendcon_id, real_filenumber, position, file_data, file_data_length, userdata); } } @@ -2359,21 +2357,21 @@ static int m_handle_packet_file_data(Messenger *m, const int i, const uint8_t *d } non_null(1, 3) nullable(5) -static int m_handle_packet_msi(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +static int m_handle_packet_msi(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata) { if (data_length == 0) { return 0; } if (m->msi_packet != nullptr) { - m->msi_packet(m, i, data, data_length, m->msi_packet_userdata); + m->msi_packet(m, friendcon_id, data, data_length, m->msi_packet_userdata); } return 0; } non_null(1, 3) nullable(5) -static int m_handle_packet_invite_groupchat(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +static int m_handle_packet_invite_groupchat(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata) { // first two bytes are messenger packet type and group invite type if (data_length < 2 + GC_JOIN_DATA_LENGTH) { @@ -2386,35 +2384,35 @@ static int m_handle_packet_invite_groupchat(Messenger *m, const int i, const uin if (m->group_invite != nullptr && data[1] == GROUP_INVITE && data_length != 2 + GC_JOIN_DATA_LENGTH) { if (group_not_added(m->group_handler, join_data, join_data_len)) { - m->group_invite(m, i, join_data, GC_JOIN_DATA_LENGTH, + m->group_invite(m, friendcon_id, join_data, GC_JOIN_DATA_LENGTH, join_data + GC_JOIN_DATA_LENGTH, join_data_len - GC_JOIN_DATA_LENGTH, userdata); } } else if (invite_type == GROUP_INVITE_ACCEPTED) { - handle_gc_invite_accepted_packet(m->group_handler, i, join_data, join_data_len); + handle_gc_invite_accepted_packet(m->group_handler, friendcon_id, join_data, join_data_len); } else if (invite_type == GROUP_INVITE_CONFIRMATION) { - handle_gc_invite_confirmed_packet(m->group_handler, i, join_data, join_data_len); + handle_gc_invite_confirmed_packet(m->group_handler, friendcon_id, join_data, join_data_len); } return 0; } non_null(1, 3) nullable(5) -static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t len, void *userdata) +static int m_handle_packet(void *object, int friendcon_id, const uint8_t *data, uint16_t length, void *userdata) { Messenger *m = (Messenger *)object; - if (len == 0) { + if (length == 0) { return -1; } - const uint8_t packet_id = temp[0]; - const uint8_t *data = temp + 1; - const uint16_t data_length = len - 1; + const uint8_t packet_id = data[0]; + const uint8_t *payload = data + 1; + const uint16_t payload_length = length - 1; - if (m->friendlist[i].status != FRIEND_ONLINE) { - if (packet_id == PACKET_ID_ONLINE && len == 1) { - set_friend_status(m, i, FRIEND_ONLINE, userdata); - send_online_packet(m, m->friendlist[i].friendcon_id); + if (m->friendlist[friendcon_id].status != FRIEND_ONLINE) { + if (packet_id == PACKET_ID_ONLINE && length == 1) { + set_friend_status(m, friendcon_id, FRIEND_ONLINE, userdata); + send_online_packet(m, m->friendlist[friendcon_id].friendcon_id); } else { return -1; } @@ -2423,34 +2421,34 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le switch (packet_id) { // TODO(Green-Sky): now all return 0 on error AND success, make errors errors? case PACKET_ID_OFFLINE: - return m_handle_packet_offline(m, i, data, data_length, userdata); + return m_handle_packet_offline(m, friendcon_id, payload, payload_length, userdata); case PACKET_ID_NICKNAME: - return m_handle_packet_nickname(m, i, data, data_length, userdata); + return m_handle_packet_nickname(m, friendcon_id, payload, payload_length, userdata); case PACKET_ID_STATUSMESSAGE: - return m_handle_packet_statusmessage(m, i, data, data_length, userdata); + return m_handle_packet_statusmessage(m, friendcon_id, payload, payload_length, userdata); case PACKET_ID_USERSTATUS: - return m_handle_packet_userstatus(m, i, data, data_length, userdata); + return m_handle_packet_userstatus(m, friendcon_id, payload, payload_length, userdata); case PACKET_ID_TYPING: - return m_handle_packet_typing(m, i, data, data_length, userdata); + return m_handle_packet_typing(m, friendcon_id, payload, payload_length, userdata); case PACKET_ID_MESSAGE: - return m_handle_packet_message(m, i, data, data_length, MESSAGE_NORMAL, userdata); + return m_handle_packet_message(m, friendcon_id, payload, payload_length, MESSAGE_NORMAL, userdata); case PACKET_ID_ACTION: - return m_handle_packet_message(m, i, data, data_length, MESSAGE_ACTION, userdata); + return m_handle_packet_message(m, friendcon_id, payload, payload_length, MESSAGE_ACTION, userdata); case PACKET_ID_INVITE_CONFERENCE: - return m_handle_packet_invite_conference(m, i, data, data_length, userdata); + return m_handle_packet_invite_conference(m, friendcon_id, payload, payload_length, userdata); case PACKET_ID_FILE_SENDREQUEST: - return m_handle_packet_file_sendrequest(m, i, data, data_length, userdata); + return m_handle_packet_file_sendrequest(m, friendcon_id, payload, payload_length, userdata); case PACKET_ID_FILE_CONTROL: - return m_handle_packet_file_control(m, i, data, data_length, userdata); + return m_handle_packet_file_control(m, friendcon_id, payload, payload_length, userdata); case PACKET_ID_FILE_DATA: - return m_handle_packet_file_data(m, i, data, data_length, userdata); + return m_handle_packet_file_data(m, friendcon_id, payload, payload_length, userdata); case PACKET_ID_MSI: - return m_handle_packet_msi(m, i, data, data_length, userdata); + return m_handle_packet_msi(m, friendcon_id, payload, payload_length, userdata); case PACKET_ID_INVITE_GROUPCHAT: - return m_handle_packet_invite_groupchat(m, i, data, data_length, userdata); + return m_handle_packet_invite_groupchat(m, friendcon_id, payload, payload_length, userdata); } - return handle_custom_lossless_packet(object, i, temp, len, userdata); + return handle_custom_lossless_packet(object, friendcon_id, data, length, userdata); } non_null(1) nullable(2) @@ -2461,8 +2459,8 @@ static void do_friends(Messenger *m, void *userdata) for (uint32_t i = 0; i < m->numfriends; ++i) { if (m->friendlist[i].status == FRIEND_ADDED) { const int fr = send_friend_request_packet(m->fr_c, m->friendlist[i].friendcon_id, m->friendlist[i].friendrequest_nospam, - m->friendlist[i].info, - m->friendlist[i].info_size); + m->friendlist[i].info, + m->friendlist[i].info_size); if (fr >= 0) { set_friend_status(m, i, FRIEND_REQUESTED, userdata); @@ -2528,7 +2526,6 @@ static void m_connection_status_callback(Messenger *m, void *userdata) } } - #define DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS 60UL #define IDSTRING_LEN (CRYPTO_PUBLIC_KEY_SIZE * 2 + 1) @@ -2591,14 +2588,14 @@ static bool self_announce_group(const Messenger *m, GC_Chat *chat, Onion_Friend } announce.base_announce.tcp_relays_count = (uint8_t)tcp_num; - announce.base_announce.ip_port_is_set = (uint8_t)(ip_port_is_set ? 1 : 0); + announce.base_announce.ip_port_is_set = ip_port_is_set; if (ip_port_is_set) { memcpy(&announce.base_announce.ip_port, &chat->self_ip_port, sizeof(IP_Port)); } - memcpy(announce.base_announce.peer_public_key, chat->self_public_key, ENC_PUBLIC_KEY_SIZE); - memcpy(announce.chat_public_key, get_chat_id(chat->chat_public_key), ENC_PUBLIC_KEY_SIZE); + memcpy(announce.base_announce.peer_public_key, chat->self_public_key.enc, ENC_PUBLIC_KEY_SIZE); + memcpy(announce.chat_public_key, get_chat_id(&chat->chat_public_key), ENC_PUBLIC_KEY_SIZE); uint8_t gc_data[GCA_MAX_DATA_LENGTH]; const int length = gca_pack_public_announce(m->log, gc_data, GCA_MAX_DATA_LENGTH, &announce); @@ -2620,7 +2617,7 @@ static bool self_announce_group(const Messenger *m, GC_Chat *chat, Onion_Friend if (tcp_num > 0) { pk_copy(chat->announced_tcp_relay_pk, announce.base_announce.tcp_relays[0].public_key); } else { - memset(chat->announced_tcp_relay_pk, 0, sizeof(chat->announced_tcp_relay_pk)); + memzero(chat->announced_tcp_relay_pk, sizeof(chat->announced_tcp_relay_pk)); } LOGGER_DEBUG(chat->log, "Published group announce. TCP relays: %d, UDP status: %d", tcp_num, @@ -2721,7 +2718,6 @@ void do_messenger(Messenger *m, void *userdata) } } - /* dht contains additional "friends" (requests) */ const uint32_t num_dhtfriends = dht_get_num_friends(m->dht); VLA(int32_t, m2dht, num_dhtfriends); @@ -2889,7 +2885,6 @@ static uint8_t *friend_save(const struct Saved_Friend *temp, uint8_t *data) return data; } - non_null() static const uint8_t *friend_load(struct Saved_Friend *temp, const uint8_t *data) { @@ -2927,7 +2922,6 @@ static const uint8_t *friend_load(struct Saved_Friend *temp, const uint8_t *data return data; } - non_null() static uint32_t m_state_plugins_size(const Messenger *m) { @@ -2956,7 +2950,7 @@ bool m_register_state_plugin(Messenger *m, State_Type type, m_state_size_cb *siz { const uint32_t new_length = m->options.state_plugins_length + 1; Messenger_State_Plugin *temp = (Messenger_State_Plugin *)mem_vrealloc( - m->mem, m->options.state_plugins, new_length, sizeof(Messenger_State_Plugin)); + m->mem, m->options.state_plugins, new_length, sizeof(Messenger_State_Plugin)); if (temp == nullptr) { return false; @@ -3117,7 +3111,7 @@ static uint8_t *friends_list_save(const Messenger *m, uint8_t *data) assert(next_data - cur_data == friend_size()); #ifdef __LP64__ assert(memcmp(cur_data, &temp, friend_size()) == 0); -#endif +#endif /* __LP64__ */ cur_data = next_data; ++num; } @@ -3191,7 +3185,7 @@ static void pack_groupchats(const GC_Session *c, Bin_Pack *bp) } non_null() -static bool pack_groupchats_handler(Bin_Pack *bp, const Logger *log, const void *obj) +static bool pack_groupchats_handler(const void *obj, const Logger *logger, Bin_Pack *bp) { const GC_Session *session = (const GC_Session *)obj; pack_groupchats(session, bp); @@ -3201,8 +3195,8 @@ static bool pack_groupchats_handler(Bin_Pack *bp, const Logger *log, const void non_null() static uint32_t saved_groups_size(const Messenger *m) { - const GC_Session *c = m->group_handler; - return bin_pack_obj_size(pack_groupchats_handler, m->log, c); + const GC_Session *session = m->group_handler; + return bin_pack_obj_size(pack_groupchats_handler, session, m->log); } non_null() @@ -3224,7 +3218,7 @@ static uint8_t *groups_save(const Messenger *m, uint8_t *data) data = state_write_section_header(data, STATE_COOKIE_TYPE, len, STATE_TYPE_GROUPS); - if (!bin_pack_obj(pack_groupchats_handler, m->log, c, data, len)) { + if (!bin_pack_obj(pack_groupchats_handler, c, m->log, data, len)) { LOGGER_FATAL(m->log, "failed to pack group chats into buffer of length %u", len); return data; } @@ -3237,22 +3231,17 @@ static uint8_t *groups_save(const Messenger *m, uint8_t *data) } non_null() -static State_Load_Status groups_load(Messenger *m, const uint8_t *data, uint32_t length) +static bool handle_groups_load(void *obj, Bin_Unpack *bu) { - Bin_Unpack *bu = bin_unpack_new(data, length); - if (bu == nullptr) { - LOGGER_ERROR(m->log, "failed to allocate binary unpacker"); - return STATE_LOAD_STATUS_ERROR; - } + Messenger *m = (Messenger *)obj; uint32_t num_groups; if (!bin_unpack_array(bu, &num_groups)) { LOGGER_ERROR(m->log, "msgpack failed to unpack groupchats array: expected array"); - bin_unpack_free(bu); - return STATE_LOAD_STATUS_ERROR; + return false; } - LOGGER_DEBUG(m->log, "Loading %u groups (length %u)", num_groups, length); + LOGGER_DEBUG(m->log, "Loading %u groups", num_groups); for (uint32_t i = 0; i < num_groups; ++i) { const int group_number = gc_group_load(m->group_handler, bu); @@ -3266,7 +3255,16 @@ static State_Load_Status groups_load(Messenger *m, const uint8_t *data, uint32_t LOGGER_DEBUG(m->log, "Successfully loaded %u groups", gc_count_groups(m->group_handler)); - bin_unpack_free(bu); + return true; +} + +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)) { + LOGGER_ERROR(m->log, "msgpack failed to unpack groupchats array"); + return STATE_LOAD_STATUS_ERROR; + } return STATE_LOAD_STATUS_CONTINUE; } @@ -3412,10 +3410,9 @@ static uint32_t path_node_size(const Messenger *m) non_null() static uint8_t *save_path_nodes(const Messenger *m, uint8_t *data) { - Node_format nodes[NUM_SAVED_PATH_NODES]; + Node_format nodes[NUM_SAVED_PATH_NODES] = {{{0}}}; uint8_t *temp_data = data; data = state_write_section_header(data, STATE_COOKIE_TYPE, 0, STATE_TYPE_PATH_NODE); - memset(nodes, 0, sizeof(nodes)); const unsigned int num = onion_backup_nodes(m->onion_c, nodes, NUM_SAVED_PATH_NODES); const int l = pack_nodes(m->log, data, NUM_SAVED_PATH_NODES * packed_node_size(net_family_tcp_ipv6()), nodes, num); @@ -3457,7 +3454,9 @@ static void m_register_default_plugins(Messenger *m) m_register_state_plugin(m, STATE_TYPE_STATUSMESSAGE, status_message_size, load_status_message, save_status_message); m_register_state_plugin(m, STATE_TYPE_STATUS, status_size, load_status, save_status); - m_register_state_plugin(m, STATE_TYPE_GROUPS, saved_groups_size, groups_load, groups_save); + if (m->options.groups_persistence_enabled) { + m_register_state_plugin(m, STATE_TYPE_GROUPS, saved_groups_size, groups_load, groups_save); + } m_register_state_plugin(m, STATE_TYPE_TCP_RELAY, tcp_relay_size, load_tcp_relays, save_tcp_relays); m_register_state_plugin(m, STATE_TYPE_PATH_NODE, path_node_size, load_path_nodes, save_path_nodes); } diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 0ea88d70..cace3340 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -10,15 +10,25 @@ #ifndef C_TOXCORE_TOXCORE_MESSENGER_H #define C_TOXCORE_TOXCORE_MESSENGER_H +#include "DHT.h" +#include "TCP_client.h" #include "TCP_server.h" #include "announce.h" +#include "attributes.h" +#include "crypto_core.h" #include "forwarding.h" #include "friend_connection.h" #include "friend_requests.h" #include "group_announce.h" #include "group_common.h" #include "logger.h" +#include "mem.h" +#include "mono_time.h" #include "net_crypto.h" +#include "network.h" +#include "onion.h" +#include "onion_announce.h" +#include "onion_client.h" #include "state.h" #define MAX_NAME_LENGTH 128 @@ -29,7 +39,6 @@ /* This cannot be bigger than 256 */ #define MAX_CONCURRENT_FILE_PIPES 256 - #define FRIEND_ADDRESS_SIZE (CRYPTO_PUBLIC_KEY_SIZE + sizeof(uint32_t) + sizeof(uint16_t)) typedef enum Message_Type { @@ -41,7 +50,7 @@ typedef enum Message_Type { #ifndef MESSENGER_DEFINED #define MESSENGER_DEFINED typedef struct Messenger Messenger; -#endif // MESSENGER_DEFINED +#endif /* MESSENGER_DEFINED */ // Returns the size of the data typedef uint32_t m_state_size_cb(const Messenger *m); @@ -69,6 +78,7 @@ typedef struct Messenger_Options { bool hole_punching_enabled; bool local_discovery_enabled; bool dht_announcements_enabled; + bool groups_persistence_enabled; logger_cb *log_callback; void *log_context; @@ -78,7 +88,6 @@ typedef struct Messenger_Options { uint8_t state_plugins_length; } Messenger_Options; - struct Receipts { uint32_t packet_num; uint32_t msg_id; @@ -108,7 +117,6 @@ typedef enum Friend_Add_Error { FAERR_NOMEM = -8, } Friend_Add_Error; - /** Default start timeout in seconds between friend requests. */ #define FRIENDREQUEST_TIMEOUT 5 @@ -166,7 +174,6 @@ typedef enum Filekind { FILEKIND_AVATAR, } Filekind; - typedef void m_self_connection_status_cb(Messenger *m, Onion_Connection_Status connection_status, void *user_data); typedef void m_friend_status_cb(Messenger *m, uint32_t friend_number, unsigned int status, void *user_data); typedef void m_friend_connection_status_cb(Messenger *m, uint32_t friend_number, unsigned int connection_status, @@ -194,14 +201,14 @@ typedef void m_friend_lossy_packet_cb(Messenger *m, uint32_t friend_number, uint typedef void m_friend_lossless_packet_cb(Messenger *m, uint32_t friend_number, uint8_t packet_id, const uint8_t *data, size_t length, void *user_data); typedef void m_friend_connectionstatuschange_internal_cb(Messenger *m, uint32_t friend_number, - uint8_t connection_status, void *user_data); + bool is_online, void *user_data); typedef void m_conference_invite_cb(Messenger *m, uint32_t friend_number, const uint8_t *cookie, uint16_t length, void *user_data); -typedef void m_group_invite_cb(const Messenger *m, uint32_t friendnumber, const uint8_t *data, size_t length, - const uint8_t *group_name, size_t group_name_length, void *userdata); +typedef void m_group_invite_cb(const Messenger *m, uint32_t friend_number, const uint8_t *invite_data, size_t length, + const uint8_t *group_name, size_t group_name_length, void *user_data); typedef void m_msi_packet_cb(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *user_data); -typedef int m_lossy_rtp_packet_cb(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t len, void *object); +typedef int m_lossy_rtp_packet_cb(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object); typedef struct RTP_Packet_Handler { m_lossy_rtp_packet_cb *function; @@ -359,7 +366,6 @@ void getaddress(const Messenger *m, uint8_t *address); non_null() int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, uint16_t length); - /** @brief Add a friend without sending a friendrequest. * @return the friend number if success. * @retval -3 if user's own key. @@ -449,7 +455,6 @@ non_null(1, 4) nullable(6) int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, const uint8_t *message, uint32_t length, uint32_t *message_id); - /** @brief Set the name and name_length of a friend. * * name must be a string of maximum MAX_NAME_LENGTH length. @@ -540,7 +545,6 @@ non_null() int m_copy_self_statusmessage(const Messenger *m, uint8_t *buf); non_null() uint8_t m_get_userstatus(const Messenger *m, int32_t friendnumber); non_null() uint8_t m_get_self_userstatus(const Messenger *m); - /** @brief returns timestamp of last time friendnumber was seen online or 0 if never seen. * if friendnumber is invalid this function will return UINT64_MAX. */ @@ -614,7 +618,6 @@ non_null() void m_callback_connectionstatus(Messenger *m, m_friend_connection_st non_null() void m_callback_connectionstatus_internal_av( Messenger *m, m_friend_connectionstatuschange_internal_cb *function, void *userdata); - /** @brief Set the callback for typing changes. */ non_null() void m_callback_core_connection(Messenger *m, m_self_connection_status_cb *function); @@ -629,7 +632,6 @@ void m_callback_conference_invite(Messenger *m, m_conference_invite_cb *function non_null(1) nullable(2) void m_callback_group_invite(Messenger *m, m_group_invite_cb *function); - /** @brief Send a conference invite packet. * * return true on success @@ -646,16 +648,13 @@ bool send_conference_invite_packet(const Messenger *m, int32_t friendnumber, con * return true on success */ non_null() -bool send_group_invite_packet(const Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length); - +bool send_group_invite_packet(const Messenger *m, uint32_t friendnumber, const uint8_t *packet, uint16_t length); /*** FILE SENDING */ - /** @brief Set the callback for file send requests. */ non_null() void callback_file_sendrequest(Messenger *m, m_file_recv_cb *function); - /** @brief Set the callback for file control requests. */ non_null() void callback_file_control(Messenger *m, m_file_recv_control_cb *function); @@ -665,7 +664,6 @@ non_null() void callback_file_data(Messenger *m, m_file_recv_chunk_cb *function) /** @brief Set the callback for file request chunk. */ non_null() void callback_file_reqchunk(Messenger *m, m_file_chunk_request_cb *function); - /** @brief Copy the file transfer file id to file_id * * @retval 0 on success. @@ -780,7 +778,6 @@ non_null() void custom_lossy_packet_registerhandler(Messenger *m, m_friend_lossy non_null() int m_send_custom_lossy_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint32_t length); - /** @brief Set handlers for custom lossless packets. */ non_null() void custom_lossless_packet_registerhandler(Messenger *m, m_friend_lossless_packet_cb *lossless_packethandler); @@ -890,4 +887,4 @@ uint32_t copy_friendlist(const Messenger *m, uint32_t *out_list, uint32_t list_s non_null() bool m_is_receiving_file(Messenger *m); -#endif +#endif /* C_TOXCORE_TOXCORE_MESSENGER_H */ diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index 06476ebb..2b8c6e44 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c @@ -12,8 +12,8 @@ #include #include -#include "DHT.h" #include "TCP_common.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "forwarding.h" @@ -285,7 +285,7 @@ static int proxy_socks5_read_connection_response(const Logger *logger, const TCP } else { uint8_t data[4 + sizeof(IP6) + sizeof(uint16_t)]; const TCP_Connection *con = &tcp_conn->con; - int ret = read_tcp_packet(logger, con->mem, con->ns, con->sock, data, sizeof(data), &con->ip_port); + const int ret = read_tcp_packet(logger, con->mem, con->ns, con->sock, data, sizeof(data), &con->ip_port); if (ret == -1) { return 0; @@ -313,7 +313,7 @@ static int generate_handshake(TCP_Client_Connection *tcp_conn) memcpy(tcp_conn->con.last_packet, tcp_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); random_nonce(tcp_conn->con.rng, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE); const int len = encrypt_data_symmetric(tcp_conn->con.shared_key, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain, - sizeof(plain), tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); + sizeof(plain), tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); if (len != sizeof(plain) + CRYPTO_MAC_SIZE) { return -1; @@ -335,7 +335,7 @@ static int handle_handshake(TCP_Client_Connection *tcp_conn, const uint8_t *data { uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE]; const int len = decrypt_data_symmetric(tcp_conn->con.shared_key, data, data + CRYPTO_NONCE_SIZE, - TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain); + TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain); if (len != sizeof(plain)) { return -1; @@ -394,10 +394,11 @@ int send_data(const Logger *logger, TCP_Client_Connection *con, uint8_t con_id, return 0; } - VLA(uint8_t, packet, 1 + length); + const uint16_t packet_size = 1 + length; + VLA(uint8_t, packet, packet_size); packet[0] = con_id + NUM_RESERVED_PORTS; memcpy(packet + 1, data, length); - return write_packet_tcp_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), false); + return write_packet_tcp_secure_connection(logger, &con->con, packet, packet_size, false); } /** @@ -412,14 +413,14 @@ int send_oob_packet(const Logger *logger, TCP_Client_Connection *con, const uint return -1; } - VLA(uint8_t, packet, 1 + CRYPTO_PUBLIC_KEY_SIZE + length); + const uint16_t packet_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + length; + VLA(uint8_t, packet, packet_size); packet[0] = TCP_PACKET_OOB_SEND; memcpy(packet + 1, public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length); - return write_packet_tcp_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), false); + return write_packet_tcp_secure_connection(logger, &con->con, packet, packet_size, false); } - /** @brief Set the number that will be used as an argument in the callbacks related to con_id. * * When not set by this function, the number is -1. @@ -536,10 +537,11 @@ int send_disconnect_request(const Logger *logger, TCP_Client_Connection *con, ui */ int send_onion_request(const Logger *logger, TCP_Client_Connection *con, const uint8_t *data, uint16_t length) { - VLA(uint8_t, packet, 1 + length); + const uint16_t packet_size = 1 + length; + VLA(uint8_t, packet, packet_size); packet[0] = TCP_PACKET_ONION_REQUEST; memcpy(packet + 1, data, length); - return write_packet_tcp_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), false); + return write_packet_tcp_secure_connection(logger, &con->con, packet, packet_size, false); } void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *onion_callback, void *object) @@ -578,9 +580,9 @@ void forwarding_handler(TCP_Client_Connection *con, forwarded_response_cb *forwa /** Create new TCP connection to ip_port/public_key */ TCP_Client_Connection *new_tcp_connection( - const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns, - const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, - const TCP_Proxy_Info *proxy_info) + const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns, + const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, + const TCP_Proxy_Info *proxy_info) { assert(logger != nullptr); assert(mem != nullptr); @@ -871,7 +873,8 @@ non_null(1, 2) nullable(3) static bool tcp_process_packet(const Logger *logger, TCP_Client_Connection *conn, void *userdata) { uint8_t packet[MAX_PACKET_SIZE]; - const int len = read_packet_tcp_secure_connection(logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->ip_port); + const int len = read_packet_tcp_secure_connection(logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), + &conn->ip_port); if (len == 0) { return false; @@ -949,7 +952,7 @@ void do_tcp_connection(const Logger *logger, const Mono_Time *mono_time, if (tcp_connection->status == TCP_CLIENT_PROXY_SOCKS5_CONNECTING) { if (send_pending_data(logger, &tcp_connection->con) == 0) { - int ret = socks5_read_handshake_response(logger, tcp_connection); + const int ret = socks5_read_handshake_response(logger, tcp_connection); if (ret == -1) { tcp_connection->kill_at = 0; @@ -965,7 +968,7 @@ void do_tcp_connection(const Logger *logger, const Mono_Time *mono_time, if (tcp_connection->status == TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED) { if (send_pending_data(logger, &tcp_connection->con) == 0) { - int ret = proxy_socks5_read_connection_response(logger, tcp_connection); + const int ret = proxy_socks5_read_connection_response(logger, tcp_connection); if (ret == -1) { tcp_connection->kill_at = 0; diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h index eceed047..ea2654b9 100644 --- a/toxcore/TCP_client.h +++ b/toxcore/TCP_client.h @@ -9,8 +9,11 @@ #ifndef C_TOXCORE_TOXCORE_TCP_CLIENT_H #define C_TOXCORE_TOXCORE_TCP_CLIENT_H +#include "attributes.h" #include "crypto_core.h" #include "forwarding.h" +#include "logger.h" +#include "mem.h" #include "mono_time.h" #include "network.h" @@ -59,9 +62,9 @@ void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value); /** Create new TCP connection to ip_port/public_key */ non_null(1, 2, 3, 4, 5, 6, 7, 8, 9) nullable(10) TCP_Client_Connection *new_tcp_connection( - const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns, - const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, - const TCP_Proxy_Info *proxy_info); + const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns, + const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, + const TCP_Proxy_Info *proxy_info); /** Run the TCP connection */ non_null(1, 2, 3) nullable(4) @@ -150,5 +153,4 @@ int send_oob_packet(const Logger *logger, TCP_Client_Connection *con, const uint non_null() void oob_data_handler(TCP_Client_Connection *con, tcp_oob_data_cb *oob_data_callback, void *object); - -#endif +#endif /* C_TOXCORE_TOXCORE_TCP_CLIENT_H */ diff --git a/toxcore/TCP_common.c b/toxcore/TCP_common.c index 13c17da9..bd3b7ca4 100644 --- a/toxcore/TCP_common.c +++ b/toxcore/TCP_common.c @@ -7,6 +7,7 @@ #include +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "logger.h" @@ -151,18 +152,19 @@ int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con } } - VLA(uint8_t, packet, sizeof(uint16_t) + length + CRYPTO_MAC_SIZE); + const uint16_t packet_size = sizeof(uint16_t) + length + CRYPTO_MAC_SIZE; + VLA(uint8_t, packet, packet_size); uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE); memcpy(packet, &c_length, sizeof(uint16_t)); int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); - if ((unsigned int)len != (SIZEOF_VLA(packet) - sizeof(uint16_t))) { + if ((unsigned int)len != (packet_size - sizeof(uint16_t))) { return -1; } if (priority) { - len = sendpriority ? net_send(con->ns, logger, con->sock, packet, SIZEOF_VLA(packet), &con->ip_port) : 0; + len = sendpriority ? net_send(con->ns, logger, con->sock, packet, packet_size, &con->ip_port) : 0; if (len <= 0) { len = 0; @@ -170,14 +172,14 @@ int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con increment_nonce(con->sent_nonce); - if ((unsigned int)len == SIZEOF_VLA(packet)) { + if ((unsigned int)len == packet_size) { return 1; } - return add_priority(con, packet, SIZEOF_VLA(packet), len) ? 1 : 0; + return add_priority(con, packet, packet_size, len) ? 1 : 0; } - len = net_send(con->ns, logger, con->sock, packet, SIZEOF_VLA(packet), &con->ip_port); + len = net_send(con->ns, logger, con->sock, packet, packet_size, &con->ip_port); if (len <= 0) { return 0; @@ -185,12 +187,12 @@ int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con increment_nonce(con->sent_nonce); - if ((unsigned int)len == SIZEOF_VLA(packet)) { + if ((unsigned int)len == packet_size) { return 1; } - memcpy(con->last_packet, packet, SIZEOF_VLA(packet)); - con->last_packet_length = SIZEOF_VLA(packet); + memcpy(con->last_packet, packet, packet_size); + con->last_packet_length = packet_size; con->last_packet_sent = len; return 1; } @@ -201,7 +203,7 @@ int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con * return -1 on failure/no data in buffer. */ int read_tcp_packet( - const Logger *logger, const Memory *mem, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port) + const Logger *logger, const Memory *mem, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port) { const uint16_t count = net_socket_data_recv_buffer(ns, sock); @@ -265,10 +267,10 @@ static uint16_t read_tcp_length(const Logger *logger, const Memory *mem, const N * @retval -1 on failure (connection must be killed). */ int read_packet_tcp_secure_connection( - const Logger *logger, const Memory *mem, const Network *ns, - Socket sock, uint16_t *next_packet_length, - const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data, - uint16_t max_len, const IP_Port *ip_port) + const Logger *logger, const Memory *mem, const Network *ns, + Socket sock, uint16_t *next_packet_length, + const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data, + 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); diff --git a/toxcore/TCP_common.h b/toxcore/TCP_common.h index 778962f8..9fa13660 100644 --- a/toxcore/TCP_common.h +++ b/toxcore/TCP_common.h @@ -6,7 +6,9 @@ #ifndef C_TOXCORE_TOXCORE_TCP_COMMON_H #define C_TOXCORE_TOXCORE_TCP_COMMON_H +#include "attributes.h" #include "crypto_core.h" +#include "logger.h" #include "mem.h" #include "network.h" @@ -87,8 +89,8 @@ int send_pending_data(const Logger *logger, TCP_Connection *con); */ non_null() int write_packet_tcp_secure_connection( - const Logger *logger, TCP_Connection *con, const uint8_t *data, uint16_t length, - bool priority); + const Logger *logger, TCP_Connection *con, const uint8_t *data, uint16_t length, + bool priority); /** @brief Read length bytes from socket. * @@ -97,7 +99,7 @@ int write_packet_tcp_secure_connection( */ non_null() int read_tcp_packet( - const Logger *logger, const Memory *mem, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port); + const Logger *logger, const Memory *mem, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port); /** * @return length of received packet on success. @@ -106,9 +108,9 @@ int read_tcp_packet( */ non_null() int read_packet_tcp_secure_connection( - const Logger *logger, const Memory *mem, const Network *ns, - Socket sock, uint16_t *next_packet_length, - const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data, - uint16_t max_len, const IP_Port *ip_port); + const Logger *logger, const Memory *mem, const Network *ns, + Socket sock, uint16_t *next_packet_length, + const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data, + uint16_t max_len, const IP_Port *ip_port); -#endif +#endif /* C_TOXCORE_TOXCORE_TCP_COMMON_H */ diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c index 8e379442..c7161a92 100644 --- a/toxcore/TCP_connection.c +++ b/toxcore/TCP_connection.c @@ -13,6 +13,7 @@ #include "DHT.h" #include "TCP_client.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "forwarding.h" @@ -57,17 +58,14 @@ struct TCP_Connections { uint16_t onion_num_conns; }; - static const TCP_Connection_to empty_tcp_connection_to = {0}; static const TCP_con empty_tcp_con = {0}; - const uint8_t *tcp_connections_public_key(const TCP_Connections *tcp_c) { return tcp_c->self_public_key; } - uint32_t tcp_connections_count(const TCP_Connections *tcp_c) { return tcp_c->tcp_connections_length; @@ -119,7 +117,6 @@ static int realloc_tcp_con(const Memory *mem, TCP_con **array, size_t num) return 0; } - /** * Return true if the connections_number is valid. */ @@ -752,7 +749,7 @@ int set_tcp_connection_to_status(const TCP_Connections *tcp_c, int connections_n } if (tcp_con->status == TCP_CONN_SLEEPING) { - tcp_con->unsleep = 1; + tcp_con->unsleep = true; } } } @@ -768,7 +765,7 @@ int set_tcp_connection_to_status(const TCP_Connections *tcp_c, int connections_n for (uint32_t i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { if (con_to->connections[i].tcp_connection > 0) { - unsigned int tcp_connections_number = con_to->connections[i].tcp_connection - 1; + const unsigned int tcp_connections_number = con_to->connections[i].tcp_connection - 1; TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); if (tcp_con == nullptr) { @@ -927,7 +924,7 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec return -1; } - IP_Port ip_port = tcp_con_ip_port(tcp_con->connection); + const IP_Port ip_port = tcp_con_ip_port(tcp_con->connection); uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE]; memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE); kill_tcp_connection(tcp_con->connection); @@ -948,14 +945,14 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec if (tcp_con->onion) { --tcp_c->onion_num_conns; - tcp_con->onion = 0; + tcp_con->onion = false; } tcp_con->lock_count = 0; tcp_con->sleep_count = 0; tcp_con->connected_time = 0; tcp_con->status = TCP_CONN_VALID; - tcp_con->unsleep = 0; + tcp_con->unsleep = false; return 0; } @@ -993,14 +990,14 @@ static int sleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connection if (tcp_con->onion) { --tcp_c->onion_num_conns; - tcp_con->onion = 0; + tcp_con->onion = false; } tcp_con->lock_count = 0; tcp_con->sleep_count = 0; tcp_con->connected_time = 0; tcp_con->status = TCP_CONN_SLEEPING; - tcp_con->unsleep = 0; + tcp_con->unsleep = false; return 0; } @@ -1019,8 +1016,8 @@ static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connecti } tcp_con->connection = new_tcp_connection( - tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &tcp_con->ip_port, - tcp_con->relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); + tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &tcp_con->ip_port, + tcp_con->relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); if (tcp_con->connection == nullptr) { kill_tcp_relay_connection(tcp_c, tcp_connections_number); @@ -1031,7 +1028,7 @@ static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connecti tcp_con->sleep_count = 0; tcp_con->connected_time = 0; tcp_con->status = TCP_CONN_VALID; - tcp_con->unsleep = 0; + tcp_con->unsleep = false; return 0; } @@ -1286,7 +1283,7 @@ static int tcp_relay_on_online(TCP_Connections *tcp_c, int tcp_connections_numbe } if (tcp_c->onion_status && tcp_c->onion_num_conns < NUM_ONION_TCP_CONNECTIONS) { - tcp_con->onion = 1; + tcp_con->onion = true; ++tcp_c->onion_num_conns; } @@ -1317,8 +1314,8 @@ static int add_tcp_relay_instance(TCP_Connections *tcp_c, const IP_Port *ip_port TCP_con *tcp_con = &tcp_c->tcp_connections[tcp_connections_number]; tcp_con->connection = new_tcp_connection( - tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ipp_copy, - relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); + tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ipp_copy, + relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); if (tcp_con->connection == nullptr) { return -1; @@ -1372,7 +1369,7 @@ int add_tcp_number_relay_connection(const TCP_Connections *tcp_c, int connection } if (con_to->status != TCP_CONN_SLEEPING && tcp_con->status == TCP_CONN_SLEEPING) { - tcp_con->unsleep = 1; + tcp_con->unsleep = true; } if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) { @@ -1540,7 +1537,7 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status) if (tcp_con != nullptr) { if (tcp_con->status == TCP_CONN_CONNECTED && !tcp_con->onion) { ++tcp_c->onion_num_conns; - tcp_con->onion = 1; + tcp_con->onion = true; } } @@ -1557,7 +1554,7 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status) if (tcp_con != nullptr) { if (tcp_con->status == TCP_CONN_SLEEPING) { - tcp_con->unsleep = 1; + tcp_con->unsleep = true; } } @@ -1567,7 +1564,7 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status) } } - tcp_c->onion_status = 1; + tcp_c->onion_status = true; } else { for (uint32_t i = 0; i < tcp_c->tcp_connections_length; ++i) { TCP_con *tcp_con = get_tcp_connection(tcp_c, i); @@ -1575,12 +1572,12 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status) if (tcp_con != nullptr) { if (tcp_con->onion) { --tcp_c->onion_num_conns; - tcp_con->onion = 0; + tcp_con->onion = false; } } } - tcp_c->onion_status = 0; + tcp_c->onion_status = false; } return 0; diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h index 04b48525..2d35919f 100644 --- a/toxcore/TCP_connection.h +++ b/toxcore/TCP_connection.h @@ -10,10 +10,18 @@ #define C_TOXCORE_TOXCORE_TCP_CONNECTION_H #include +#include #include "DHT.h" // for Node_format #include "TCP_client.h" #include "TCP_common.h" +#include "attributes.h" +#include "crypto_core.h" +#include "forwarding.h" +#include "logger.h" +#include "mem.h" +#include "mono_time.h" +#include "network.h" #define TCP_CONN_NONE 0 #define TCP_CONN_VALID 1 @@ -156,7 +164,7 @@ non_null() int tcp_send_oob_packet(const TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *public_key, const uint8_t *packet, uint16_t length); -typedef int tcp_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); +typedef int tcp_data_cb(void *object, int crypt_connection_id, const uint8_t *packet, uint16_t length, void *userdata); non_null() int tcp_send_oob_packet_using_relay(const TCP_Connections *tcp_c, const uint8_t *relay_pk, const uint8_t *public_key, @@ -178,9 +186,8 @@ void set_forwarding_packet_tcp_connection_callback(TCP_Connections *tcp_c, forwarded_response_cb *tcp_forwarded_response_callback, void *object); - typedef int tcp_oob_cb(void *object, const uint8_t *public_key, unsigned int tcp_connections_number, - const uint8_t *data, uint16_t length, void *userdata); + const uint8_t *packet, uint16_t length, void *userdata); /** @brief Set the callback for TCP oob data packets. */ non_null() @@ -310,4 +317,4 @@ void do_tcp_connections(const Logger *logger, TCP_Connections *tcp_c, void *user nullable(1) void kill_tcp_connections(TCP_Connections *tcp_c); -#endif +#endif /* C_TOXCORE_TOXCORE_TCP_CONNECTION_H */ diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index 1a3c7aff..1363d902 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c @@ -11,15 +11,15 @@ #include #if !defined(_WIN32) && !defined(__WIN32__) && !defined (WIN32) #include -#endif +#endif /* !WIN32 */ #ifdef TCP_SERVER_USE_EPOLL #include #include -#endif +#endif /* TCP_SERVER_USE_EPOLL */ -#include "DHT.h" #include "TCP_common.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "forwarding.h" @@ -35,7 +35,7 @@ #define TCP_SOCKET_INCOMING 1 #define TCP_SOCKET_UNCONFIRMED 2 #define TCP_SOCKET_CONFIRMED 3 -#endif +#endif /* TCP_SERVER_USE_EPOLL */ typedef struct TCP_Secure_Conn { uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -60,6 +60,7 @@ typedef struct TCP_Secure_Connection { uint64_t ping_id; } TCP_Secure_Connection; +static const TCP_Secure_Connection empty_tcp_secure_connection = {{nullptr}}; struct TCP_Server { const Logger *logger; @@ -72,7 +73,7 @@ struct TCP_Server { #ifdef TCP_SERVER_USE_EPOLL int efd; uint64_t last_run_pinged; -#endif +#endif /* TCP_SERVER_USE_EPOLL */ Socket *socks_listening; unsigned int num_listening_socks; @@ -109,8 +110,8 @@ size_t tcp_server_listen_count(const TCP_Server *tcp_server) #ifdef TCP_SERVER_USE_EPOLL #ifndef EPOLLRDHUP #define EPOLLRDHUP 0x2000 -#endif -#endif +#endif /* EPOLLRDHUP */ +#endif /* TCP_SERVER_USE_EPOLL */ /** @brief Increase the size of the connection list * @@ -135,8 +136,9 @@ static int alloc_new_connections(TCP_Server *tcp_server, uint32_t num) } const uint32_t old_size = tcp_server->size_accepted_connections; - const uint32_t size_new_entries = num * sizeof(TCP_Secure_Connection); - memset(new_connections + old_size, 0, size_new_entries); + for (uint32_t i = 0; i < num; ++i) { + new_connections[old_size + i] = empty_tcp_secure_connection; + } tcp_server->accepted_connection_array = new_connections; tcp_server->size_accepted_connections = new_size; @@ -185,7 +187,6 @@ static int get_tcp_connection_index(const TCP_Server *tcp_server, const uint8_t return bs_list_find(&tcp_server->accepted_key_list, public_key); } - non_null() static int kill_accepted(TCP_Server *tcp_server, int index); @@ -354,7 +355,7 @@ static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con return -1; } - IP_Port ipp = {{{0}}}; + const IP_Port ipp = {{{0}}}; if (TCP_SERVER_HANDSHAKE_SIZE != net_send(con->con.ns, logger, con->con.sock, response, TCP_SERVER_HANDSHAKE_SIZE, &ipp)) { crypto_memzero(shared_key, sizeof(shared_key)); @@ -529,12 +530,13 @@ static int handle_tcp_oob_send(TCP_Server *tcp_server, uint32_t con_id, const ui const int other_index = get_tcp_connection_index(tcp_server, public_key); if (other_index != -1) { - VLA(uint8_t, resp_packet, 1 + CRYPTO_PUBLIC_KEY_SIZE + length); + const uint16_t resp_packet_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + length; + VLA(uint8_t, resp_packet, resp_packet_size); resp_packet[0] = TCP_PACKET_OOB_RECV; memcpy(resp_packet + 1, con->public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(resp_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length); write_packet_tcp_secure_connection(tcp_server->logger, &tcp_server->accepted_connection_array[other_index].con, - resp_packet, SIZEOF_VLA(resp_packet), false); + resp_packet, resp_packet_size, false); } return 0; @@ -617,11 +619,12 @@ static int handle_onion_recv_1(void *object, const IP_Port *dest, const uint8_t TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[index]; - VLA(uint8_t, packet, 1 + length); + const uint16_t packet_size = 1 + length; + VLA(uint8_t, packet, packet_size); memcpy(packet + 1, data, length); packet[0] = TCP_PACKET_ONION_RESPONSE; - if (write_packet_tcp_secure_connection(tcp_server->logger, &con->con, packet, SIZEOF_VLA(packet), false) != 1) { + if (write_packet_tcp_secure_connection(tcp_server->logger, &con->con, packet, packet_size, false) != 1) { return 1; } @@ -657,11 +660,12 @@ static bool handle_forward_reply_tcp(void *object, const uint8_t *sendback_data, return false; } - VLA(uint8_t, packet, 1 + length); + const uint16_t packet_size = 1 + length; + VLA(uint8_t, packet, packet_size); memcpy(packet + 1, data, length); packet[0] = TCP_PACKET_FORWARDING; - return write_packet_tcp_secure_connection(tcp_server->logger, &con->con, packet, SIZEOF_VLA(packet), false) == 1; + return write_packet_tcp_secure_connection(tcp_server->logger, &con->con, packet, packet_size, false) == 1; } /** @@ -759,7 +763,7 @@ static int handle_tcp_packet(TCP_Server *tcp_server, uint32_t con_id, const uint return -1; } - IP_Port source = con_id_to_ip_port(con_id, con->identifier); + const IP_Port source = con_id_to_ip_port(con_id, con->identifier); onion_send_1(tcp_server->onion, data + 1 + CRYPTO_NONCE_SIZE, length - (1 + CRYPTO_NONCE_SIZE), &source, data + 1); } @@ -844,7 +848,6 @@ static int handle_tcp_packet(TCP_Server *tcp_server, uint32_t con_id, const uint return 0; } - non_null() static int confirm_tcp_connection(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_Secure_Connection *con, const uint8_t *data, uint16_t length) @@ -991,7 +994,7 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random return nullptr; } -#endif +#endif /* TCP_SERVER_USE_EPOLL */ const Family family = ipv6_enabled ? net_family_ipv6() : net_family_ipv4(); @@ -1006,13 +1009,13 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random struct epoll_event ev; ev.events = EPOLLIN | EPOLLET; - ev.data.u64 = sock.sock | ((uint64_t)TCP_SOCKET_LISTENING << 32); + ev.data.u64 = net_socket_to_native(sock) | ((uint64_t)TCP_SOCKET_LISTENING << 32); - if (epoll_ctl(temp->efd, EPOLL_CTL_ADD, sock.sock, &ev) == -1) { + if (epoll_ctl(temp->efd, EPOLL_CTL_ADD, net_socket_to_native(sock), &ev) == -1) { continue; } -#endif +#endif /* TCP_SERVER_USE_EPOLL */ temp->socks_listening[temp->num_listening_socks] = sock; ++temp->num_listening_socks; @@ -1037,7 +1040,7 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random memcpy(temp->secret_key, secret_key, CRYPTO_SECRET_KEY_SIZE); crypto_derive_public_key(temp->public_key, temp->secret_key); - bs_list_init(&temp->accepted_key_list, CRYPTO_PUBLIC_KEY_SIZE, 8); + bs_list_init(&temp->accepted_key_list, CRYPTO_PUBLIC_KEY_SIZE, 8, memcmp); return temp; } @@ -1057,7 +1060,7 @@ static void do_tcp_accept_new(TCP_Server *tcp_server) } } } -#endif +#endif /* TCP_SERVER_USE_EPOLL */ non_null() static int do_incoming(TCP_Server *tcp_server, uint32_t i) @@ -1109,7 +1112,8 @@ static int do_unconfirmed(TCP_Server *tcp_server, const Mono_Time *mono_time, ui LOGGER_TRACE(tcp_server->logger, "handling unconfirmed TCP connection %d", i); uint8_t packet[MAX_PACKET_SIZE]; - const int len = read_packet_tcp_secure_connection(tcp_server->logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port); + const int len = read_packet_tcp_secure_connection(tcp_server->logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, + sizeof(packet), &conn->con.ip_port); if (len == 0) { return -1; @@ -1129,7 +1133,8 @@ static bool tcp_process_secure_packet(TCP_Server *tcp_server, uint32_t i) TCP_Secure_Connection *const conn = &tcp_server->accepted_connection_array[i]; uint8_t packet[MAX_PACKET_SIZE]; - const int len = read_packet_tcp_secure_connection(tcp_server->logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port); + const int len = read_packet_tcp_secure_connection(tcp_server->logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, + sizeof(packet), &conn->con.ip_port); LOGGER_TRACE(tcp_server->logger, "processing packet for %d: %d", i, len); if (len == 0) { @@ -1174,7 +1179,7 @@ static void do_tcp_unconfirmed(TCP_Server *tcp_server, const Mono_Time *mono_tim do_unconfirmed(tcp_server, mono_time, i); } } -#endif +#endif /* TCP_SERVER_USE_EPOLL */ non_null() static void do_tcp_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time) @@ -1186,7 +1191,7 @@ static void do_tcp_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time) } tcp_server->last_run_pinged = mono_time_get(mono_time); -#endif +#endif /* TCP_SERVER_USE_EPOLL */ for (uint32_t i = 0; i < tcp_server->size_accepted_connections; ++i) { TCP_Secure_Connection *conn = &tcp_server->accepted_connection_array[i]; @@ -1229,7 +1234,7 @@ static void do_tcp_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time) do_confirmed_recv(tcp_server, i); -#endif +#endif /* TCP_SERVER_USE_EPOLL */ } } @@ -1243,7 +1248,7 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time #undef MAX_EVENTS for (int n = 0; n < nfds; ++n) { - const Socket sock = {(int)(events[n].data.u64 & 0xFFFFFFFF)}; + const Socket sock = net_socket_from_native((int)(events[n].data.u64 & 0xFFFFFFFF)); const int status = (events[n].data.u64 >> 32) & 0xFF; const int index = events[n].data.u64 >> 40; @@ -1277,7 +1282,6 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time continue; } - if ((events[n].events & EPOLLIN) == 0) { continue; } @@ -1302,9 +1306,9 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time ev.events = EPOLLIN | EPOLLET | EPOLLRDHUP; - ev.data.u64 = sock_new.sock | ((uint64_t)TCP_SOCKET_INCOMING << 32) | ((uint64_t)index_new << 40); + ev.data.u64 = net_socket_to_native(sock_new) | ((uint64_t)TCP_SOCKET_INCOMING << 32) | ((uint64_t)index_new << 40); - if (epoll_ctl(tcp_server->efd, EPOLL_CTL_ADD, sock_new.sock, &ev) == -1) { + if (epoll_ctl(tcp_server->efd, EPOLL_CTL_ADD, net_socket_to_native(sock_new), &ev) == -1) { LOGGER_DEBUG(tcp_server->logger, "new connection %d was dropped due to epoll error %d", index, net_error()); kill_tcp_secure_connection(&tcp_server->incoming_connection_queue[index_new]); continue; @@ -1320,9 +1324,9 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time if (index_new != -1) { LOGGER_TRACE(tcp_server->logger, "incoming connection %d was accepted as %d", index, index_new); events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP; - events[n].data.u64 = sock.sock | ((uint64_t)TCP_SOCKET_UNCONFIRMED << 32) | ((uint64_t)index_new << 40); + events[n].data.u64 = net_socket_to_native(sock) | ((uint64_t)TCP_SOCKET_UNCONFIRMED << 32) | ((uint64_t)index_new << 40); - if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.sock, &events[n]) == -1) { + if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, net_socket_to_native(sock), &events[n]) == -1) { LOGGER_DEBUG(tcp_server->logger, "incoming connection %d was dropped due to epoll error %d", index, net_error()); kill_tcp_secure_connection(&tcp_server->unconfirmed_connection_queue[index_new]); break; @@ -1338,9 +1342,9 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time if (index_new != -1) { LOGGER_TRACE(tcp_server->logger, "unconfirmed connection %d was confirmed as %d", index, index_new); events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP; - events[n].data.u64 = sock.sock | ((uint64_t)TCP_SOCKET_CONFIRMED << 32) | ((uint64_t)index_new << 40); + events[n].data.u64 = net_socket_to_native(sock) | ((uint64_t)TCP_SOCKET_CONFIRMED << 32) | ((uint64_t)index_new << 40); - if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.sock, &events[n]) == -1) { + if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, net_socket_to_native(sock), &events[n]) == -1) { // remove from confirmed connections LOGGER_DEBUG(tcp_server->logger, "unconfirmed connection %d was dropped due to epoll error %d", index, net_error()); kill_accepted(tcp_server, index_new); @@ -1369,7 +1373,7 @@ static void do_tcp_epoll(TCP_Server *tcp_server, const Mono_Time *mono_time) continue; } } -#endif +#endif /* TCP_SERVER_USE_EPOLL */ void do_tcp_server(TCP_Server *tcp_server, const Mono_Time *mono_time) { @@ -1380,7 +1384,7 @@ void do_tcp_server(TCP_Server *tcp_server, const Mono_Time *mono_time) do_tcp_accept_new(tcp_server); do_tcp_incoming(tcp_server); do_tcp_unconfirmed(tcp_server, mono_time); -#endif +#endif /* TCP_SERVER_USE_EPOLL */ do_tcp_confirmed(tcp_server, mono_time); } @@ -1407,7 +1411,7 @@ void kill_tcp_server(TCP_Server *tcp_server) #ifdef TCP_SERVER_USE_EPOLL close(tcp_server->efd); -#endif +#endif /* TCP_SERVER_USE_EPOLL */ for (uint32_t i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) { wipe_secure_connection(&tcp_server->incoming_connection_queue[i]); diff --git a/toxcore/TCP_server.h b/toxcore/TCP_server.h index 0349f60b..1d3933a4 100644 --- a/toxcore/TCP_server.h +++ b/toxcore/TCP_server.h @@ -9,8 +9,13 @@ #ifndef C_TOXCORE_TOXCORE_TCP_SERVER_H #define C_TOXCORE_TOXCORE_TCP_SERVER_H +#include "attributes.h" #include "crypto_core.h" #include "forwarding.h" +#include "logger.h" +#include "mem.h" +#include "mono_time.h" +#include "network.h" #include "onion.h" #define MAX_INCOMING_CONNECTIONS 256 @@ -47,5 +52,4 @@ void do_tcp_server(TCP_Server *tcp_server, const Mono_Time *mono_time); nullable(1) void kill_tcp_server(TCP_Server *tcp_server); - -#endif +#endif /* C_TOXCORE_TOXCORE_TCP_SERVER_H */ diff --git a/toxcore/announce.c b/toxcore/announce.c index 26645b55..b983cb05 100644 --- a/toxcore/announce.c +++ b/toxcore/announce.c @@ -14,6 +14,7 @@ #include "DHT.h" #include "LAN_discovery.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "forwarding.h" @@ -164,7 +165,6 @@ static const Announce_Entry *get_stored_const(const Announcements *announce, con return nullptr; } - bool announce_on_stored(const Announcements *announce, const uint8_t *data_public_key, announce_on_retrieve_cb *on_retrieve_callback, void *object) { @@ -239,9 +239,7 @@ bool announce_store_data(Announcements *announce, const uint8_t *data_public_key if (length > 0) { assert(data != nullptr); - if (entry->data != nullptr) { - free(entry->data); - } + free(entry->data); uint8_t *entry_data = (uint8_t *)malloc(length); @@ -354,7 +352,7 @@ static int create_reply_plain_data_search_request(Announcements *announce, to_auth, to_auth_length, p); p += TIMED_AUTH_SIZE; - *p = would_accept_store_request(announce, data_public_key); + *p = would_accept_store_request(announce, data_public_key) ? 1 : 0; ++p; Node_format nodes_list[MAX_SENT_NODES]; @@ -387,11 +385,11 @@ static int create_reply_plain_data_search_request(Announcements *announce, non_null() static int create_reply_plain_data_retrieve_request( - const Announcements *announce, - const IP_Port *source, - const uint8_t *data, uint16_t length, - uint8_t *reply, uint16_t reply_max_length, - const uint8_t *to_auth, uint16_t to_auth_length) + const Announcements *announce, + const IP_Port *source, + const uint8_t *data, uint16_t length, + uint8_t *reply, uint16_t reply_max_length, + const uint8_t *to_auth, uint16_t to_auth_length) { if (length != CRYPTO_PUBLIC_KEY_SIZE + 1 + TIMED_AUTH_SIZE) { return -1; @@ -446,7 +444,7 @@ static int create_reply_plain_store_announce_request(Announcements *announce, VLA(uint8_t, plain, plain_len); - const uint8_t* shared_key = shared_key_cache_lookup(announce->shared_keys, data_public_key); + const uint8_t *shared_key = shared_key_cache_lookup(announce->shared_keys, data_public_key); if (shared_key == nullptr) { /* Error looking up/deriving the shared key */ @@ -629,16 +627,15 @@ static void forwarded_request_callback(void *object, const IP_Port *forwarder, } non_null(1, 2, 3) nullable(5) -static int handle_dht_announce_request(void *object, const IP_Port *source, - const uint8_t *data, uint16_t length, void *userdata) +static int handle_dht_announce_request( + void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { - Announcements *announce = (Announcements *) object; + Announcements *announce = (Announcements *)object; uint8_t reply[MAX_FORWARD_DATA_SIZE]; - const int len = create_reply(announce, source, - nullptr, 0, - data, length, reply, sizeof(reply)); + const int len + = create_reply(announce, source, nullptr, 0, packet, length, reply, sizeof(reply)); if (len == -1) { return -1; @@ -703,9 +700,7 @@ void kill_announcements(Announcements *announce) shared_key_cache_free(announce->shared_keys); for (uint32_t i = 0; i < ANNOUNCE_BUCKETS * ANNOUNCE_BUCKET_SIZE; ++i) { - if (announce->entries[i].data != nullptr) { - free(announce->entries[i].data); - } + free(announce->entries[i].data); } free(announce); diff --git a/toxcore/announce.h b/toxcore/announce.h index bbd7a72b..bd05088d 100644 --- a/toxcore/announce.h +++ b/toxcore/announce.h @@ -5,7 +5,14 @@ #ifndef C_TOXCORE_TOXCORE_ANNOUNCE_H #define C_TOXCORE_TOXCORE_ANNOUNCE_H +#include + +#include "attributes.h" +#include "crypto_core.h" #include "forwarding.h" +#include "logger.h" +#include "mem.h" +#include "mono_time.h" #define MAX_ANNOUNCEMENT_SIZE 512 @@ -34,7 +41,6 @@ void announce_set_synch_offset(Announcements *announce, int32_t synch_offset); nullable(1) void kill_announcements(Announcements *announce); - /* The declarations below are not public, they are exposed only for tests. */ /** @private @@ -65,4 +71,4 @@ bool announce_store_data(Announcements *announce, const uint8_t *data_public_key #define ANNOUNCE_BUCKET_PREFIX_LENGTH 5 #define ANNOUNCE_BUCKETS 32 // ANNOUNCE_BUCKETS = 2 ** ANNOUNCE_BUCKET_PREFIX_LENGTH -#endif +#endif /* C_TOXCORE_TOXCORE_ANNOUNCE_H */ diff --git a/toxcore/attributes.h b/toxcore/attributes.h index 3d3aeda0..087efe20 100644 --- a/toxcore/attributes.h +++ b/toxcore/attributes.h @@ -26,6 +26,14 @@ #define nullable(...) +#ifdef SPARSE +#define bitwise __attribute__((bitwise)) +#define force __attribute__((force)) +#else +#define bitwise +#define force +#endif + //!TOKSTYLE+ -#endif // C_TOXCORE_TOXCORE_ATTRIBUTES_H +#endif /* C_TOXCORE_TOXCORE_ATTRIBUTES_H */ diff --git a/toxcore/bin_pack.c b/toxcore/bin_pack.c index 774f03a6..56bdc9ec 100644 --- a/toxcore/bin_pack.c +++ b/toxcore/bin_pack.c @@ -5,10 +5,10 @@ #include "bin_pack.h" #include -#include #include #include "../third_party/cmp/cmp.h" +#include "attributes.h" #include "ccompat.h" #include "logger.h" @@ -27,15 +27,16 @@ static bool null_reader(cmp_ctx_t *ctx, void *data, size_t limit) } non_null() -static bool null_skipper(cmp_ctx_t *ctx, size_t limit) +static bool null_skipper(cmp_ctx_t *ctx, size_t count) { - assert(limit == 0); + assert(count == 0); return false; } non_null() static size_t buf_writer(cmp_ctx_t *ctx, const void *data, size_t count) { + const uint8_t *bytes = (const uint8_t *)data; Bin_Pack *bp = (Bin_Pack *)ctx->buf; assert(bp != nullptr); const uint32_t new_pos = bp->bytes_pos + count; @@ -48,7 +49,7 @@ static size_t buf_writer(cmp_ctx_t *ctx, const void *data, size_t count) // Buffer too small. return 0; } - memcpy(bp->bytes + bp->bytes_pos, data, count); + memcpy(&bp->bytes[bp->bytes_pos], bytes, count); } bp->bytes_pos += count; return count; @@ -63,60 +64,71 @@ static void bin_pack_init(Bin_Pack *bp, uint8_t *buf, uint32_t buf_size) cmp_init(&bp->ctx, bp, null_reader, null_skipper, buf_writer); } -uint32_t bin_pack_obj_size(bin_pack_cb *callback, const Logger *logger, const void *obj) +uint32_t bin_pack_obj_size(bin_pack_cb *callback, const void *obj, const Logger *logger) { Bin_Pack bp; bin_pack_init(&bp, nullptr, 0); - if (!callback(&bp, logger, obj)) { + if (!callback(obj, logger, &bp)) { return UINT32_MAX; } return bp.bytes_pos; } -bool bin_pack_obj(bin_pack_cb *callback, const Logger *logger, const void *obj, uint8_t *buf, uint32_t buf_size) +bool bin_pack_obj(bin_pack_cb *callback, const void *obj, const Logger *logger, uint8_t *buf, uint32_t buf_size) { Bin_Pack bp; bin_pack_init(&bp, buf, buf_size); - return callback(&bp, logger, obj); + return callback(obj, logger, &bp); } -uint32_t bin_pack_obj_array_size(bin_pack_array_cb *callback, const Logger *logger, const void *arr, uint32_t count) +uint32_t bin_pack_obj_array_b_size(bin_pack_array_cb *callback, const void *arr, uint32_t arr_size, const Logger *logger) { Bin_Pack bp; bin_pack_init(&bp, nullptr, 0); - for (uint32_t i = 0; i < count; ++i) { - if (!callback(&bp, logger, arr, i)) { + if (arr == nullptr) { + assert(arr_size == 0); + } + for (uint32_t i = 0; i < arr_size; ++i) { + if (!callback(arr, i, logger, &bp)) { return UINT32_MAX; } } return bp.bytes_pos; } -bool bin_pack_obj_array(bin_pack_array_cb *callback, const Logger *logger, const void *arr, uint32_t count, uint8_t *buf, uint32_t buf_size) +bool bin_pack_obj_array_b(bin_pack_array_cb *callback, const void *arr, uint32_t arr_size, const Logger *logger, uint8_t *buf, uint32_t buf_size) { Bin_Pack bp; bin_pack_init(&bp, buf, buf_size); - for (uint32_t i = 0; i < count; ++i) { - if (!callback(&bp, logger, arr, i)) { + if (arr == nullptr) { + assert(arr_size == 0); + } + for (uint32_t i = 0; i < arr_size; ++i) { + if (!callback(arr, i, logger, &bp)) { return false; } } return true; } -Bin_Pack *bin_pack_new(uint8_t *buf, uint32_t buf_size) +bool bin_pack_obj_array(Bin_Pack *bp, bin_pack_array_cb *callback, const void *arr, uint32_t arr_size, const Logger *logger) { - Bin_Pack *bp = (Bin_Pack *)calloc(1, sizeof(Bin_Pack)); - if (bp == nullptr) { - return nullptr; + if (arr == nullptr) { + assert(arr_size == 0); + return bin_pack_array(bp, 0); } - bin_pack_init(bp, buf, buf_size); - return bp; -} -void bin_pack_free(Bin_Pack *bp) -{ - free(bp); + if (!bin_pack_array(bp, arr_size)) { + return false; + } + + for (uint32_t i = 0; i < arr_size; ++i) { + if (!callback(arr, i, logger, bp)) { + return false; + } + } + + return true; } bool bin_pack_array(Bin_Pack *bp, uint32_t size) @@ -191,4 +203,3 @@ bool bin_pack_bin_b(Bin_Pack *bp, const uint8_t *data, uint32_t length) { return bp->ctx.write(&bp->ctx, data, length) == length; } - diff --git a/toxcore/bin_pack.h b/toxcore/bin_pack.h index 6df21e0e..ce6926a4 100644 --- a/toxcore/bin_pack.h +++ b/toxcore/bin_pack.h @@ -16,6 +16,26 @@ extern "C" { /** * @brief Binary serialisation object. + * + * Naming convention: + * - Functions ending in `_b` (or `_b_size`) are NOT MessagePack, i.e. write + * data in plain big endian binary format. + * - All other functions encode their input in MessagePack format. + * + * Some notes on parameter order: + * + * - We pass the `obj` pointer as `this`-like pointer first to the callbacks. + * - Any extra arguments passed to the callback follow the `obj` (and in case of + * array packing, the `arr` and `arr_size` parameters). + * - The packer is passed last. + * + * This roughly matches a curried lambda function: + * + * @code + * bin_pack_obj([](const void *obj, const Logger *logger, Bin_Pack *bp) { ... }, obj, logger, buf, buf_size); + * // Translates roughly to: + * bin_pack_obj([obj, logger](Bin_Pack *bp) { ... }, buf, buf_size); + * @endcode */ typedef struct Bin_Pack Bin_Pack; @@ -24,7 +44,7 @@ typedef struct Bin_Pack Bin_Pack; * This function would typically cast the `void *` to the actual object pointer type and then call * more appropriately typed packing functions. */ -typedef bool bin_pack_cb(Bin_Pack *bp, const Logger *logger, const void *obj); +typedef bool bin_pack_cb(const void *obj, const Logger *logger, Bin_Pack *bp); /** @brief Function used to pack an array of objects. * @@ -34,99 +54,104 @@ typedef bool bin_pack_cb(Bin_Pack *bp, const Logger *logger, const void *obj); * @param arr is the object array as void pointer. * @param index is the index in the object array that is currently being packed. */ -typedef bool bin_pack_array_cb(Bin_Pack *bp, const Logger *logger, const void *arr, uint32_t index); +typedef bool bin_pack_array_cb(const void *arr, uint32_t index, const Logger *logger, Bin_Pack *bp); /** @brief Determine the serialised size of an object. * * @param callback The function called on the created packer and packed object. - * @param logger Optional logger object to pass to the callback. * @param obj The object to be packed, passed as `obj` to the callback. + * @param logger Optional logger object to pass to the callback. * * @return The packed size of the passed object according to the callback. * @retval UINT32_MAX in case of errors such as buffer overflow. */ non_null(1) nullable(2, 3) -uint32_t bin_pack_obj_size(bin_pack_cb *callback, const Logger *logger, const void *obj); +uint32_t bin_pack_obj_size(bin_pack_cb *callback, const void *obj, const Logger *logger); /** @brief Pack an object into a buffer of a given size. * * This function creates and initialises a `Bin_Pack` packer object, calls the callback with the - * packer object and the to-be-packed object, and then cleans up the packer object. + * packer object and the to-be-packed object, and then cleans up the packer object. Note that + * there is nothing MessagePack-specific about this function, so it can be used for both custom + * binary and MessagePack formats. * * You can use `bin_pack_obj_size` to determine the minimum required size of `buf`. If packing * overflows `uint32_t`, this function returns `false`. * + * Passing NULL for `obj` is supported, but requires that the callback supports nullable inputs. + * * @param callback The function called on the created packer and packed object. - * @param logger Optional logger object to pass to the callback. * @param obj The object to be packed, passed as `obj` to the callback. + * @param logger Optional logger object to pass to the callback. * @param buf A byte array large enough to hold the serialised representation of `obj`. * @param buf_size The size of the byte array. Can be `UINT32_MAX` to disable bounds checking. * * @retval false if an error occurred (e.g. buffer overflow). */ non_null(1, 4) nullable(2, 3) -bool bin_pack_obj(bin_pack_cb *callback, const Logger *logger, const void *obj, uint8_t *buf, uint32_t buf_size); +bool bin_pack_obj(bin_pack_cb *callback, const void *obj, const Logger *logger, uint8_t *buf, uint32_t buf_size); /** @brief Determine the serialised size of an object array. * - * Calls the callback `count` times with increasing `index` argument from 0 to - * `count`. This function is here just so we don't need to write the same - * trivial loop many times and so we don't need an extra struct just to contain - * an array with size so it can be passed to `bin_pack_obj_size`. + * Behaves exactly like `bin_pack_obj_b_array` but doesn't write. * * @param callback The function called on the created packer and each object to * be packed. - * @param logger Optional logger object to pass to the callback. * @param arr The object array to be packed, passed as `arr` to the callback. - * @param count The number of elements in the object array. + * @param arr_size The number of elements in the object array. + * @param logger Optional logger object to pass to the callback. * * @return The packed size of the passed object array according to the callback. * @retval UINT32_MAX in case of errors such as buffer overflow. */ -non_null(1, 3) nullable(2) -uint32_t bin_pack_obj_array_size(bin_pack_array_cb *callback, const Logger *logger, const void *arr, uint32_t count); +non_null(1) nullable(2, 4) +uint32_t bin_pack_obj_array_b_size(bin_pack_array_cb *callback, const void *arr, uint32_t arr_size, const Logger *logger); /** @brief Pack an object array into a buffer of a given size. * - * Calls the callback `count` times with increasing `index` argument from 0 to - * `count`. This function is here just so we don't need to write the same - * trivial loop many times and so we don't need an extra struct just to contain - * an array with size so it can be passed to `bin_pack_obj`. + * Similar to `bin_pack_obj_array` but does not write the array length, so + * if you need that, encoding it is on you. * - * Similar to `bin_pack_obj` but for arrays. Does not write the array length, so - * if you need that, write it manually using `bin_pack_array`. + * Passing NULL for `arr` has no effect, but requires that `arr_size` is 0. * * @param callback The function called on the created packer and packed object * array. - * @param logger Optional logger object to pass to the callback. * @param arr The object array to be packed, passed as `arr` to the callback. - * @param count The number of elements in the object array. + * @param arr_size The number of elements in the object array. + * @param logger Optional logger object to pass to the callback. * @param buf A byte array large enough to hold the serialised representation of `arr`. * @param buf_size The size of the byte array. Can be `UINT32_MAX` to disable bounds checking. * * @retval false if an error occurred (e.g. buffer overflow). */ -non_null(1, 3, 5) nullable(2) -bool bin_pack_obj_array(bin_pack_array_cb *callback, const Logger *logger, const void *arr, uint32_t count, uint8_t *buf, uint32_t buf_size); +non_null(1, 5) nullable(2, 4) +bool bin_pack_obj_array_b(bin_pack_array_cb *callback, const void *arr, uint32_t arr_size, const Logger *logger, uint8_t *buf, uint32_t buf_size); -/** @brief Allocate a new packer object. +/** @brief Encode an object array as MessagePack array into a bin packer. * - * This is the only function that allocates memory in this module. + * Calls the callback `arr_size` times with increasing `index` argument from 0 to + * `arr_size`. This function is here just so we don't need to write the same + * trivial loop many times and so we don't need an extra struct just to contain + * an array with size so it can be passed to `bin_pack_obj`. * - * @param buf A byte array large enough to hold the serialised representation of `obj`. - * @param buf_size The size of the byte array. Can be `UINT32_MAX` to disable bounds checking. + * Similar to `bin_pack_obj` but for arrays. Note that a `Bin_Pack` object is + * required here, so it must be called from within a callback to one of the + * functions above. * - * @retval nullptr on allocation failure. + * Passing NULL for `arr` requires that `arr_size` is 0. This will write a 0-size + * MessagePack array to the packer. + * + * @param bp Bin packer object. + * @param callback The function called on the created packer and packed object + * array. + * @param arr The object array to be packed, passed as `arr` to the callback. + * @param arr_size The number of elements in the object array. + * @param logger Optional logger object to pass to the callback. + * + * @retval false if an error occurred (e.g. buffer overflow). */ -non_null() -Bin_Pack *bin_pack_new(uint8_t *buf, uint32_t buf_size); - -/** @brief Deallocates a packer object. - * - * Does not deallocate the buffer inside. - */ -nullable(1) -void bin_pack_free(Bin_Pack *bp); +non_null(1, 2) nullable(3, 5) +bool bin_pack_obj_array(Bin_Pack *bp, bin_pack_array_cb *callback, const void *arr, uint32_t arr_size, const Logger *logger); /** @brief Start packing a MessagePack array. * @@ -172,7 +197,7 @@ non_null() bool bin_pack_u64_b(Bin_Pack *bp, uint64_t val); non_null() bool bin_pack_bin_b(Bin_Pack *bp, const uint8_t *data, uint32_t length); #ifdef __cplusplus -} // extern "C" +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_BIN_PACK_H +#endif /* C_TOXCORE_TOXCORE_BIN_PACK_H */ diff --git a/toxcore/bin_pack_test.cc b/toxcore/bin_pack_test.cc index 05140146..4bd8a25b 100644 --- a/toxcore/bin_pack_test.cc +++ b/toxcore/bin_pack_test.cc @@ -7,118 +7,142 @@ #include #include "bin_unpack.h" +#include "logger.h" namespace { -struct Bin_Pack_Deleter { - void operator()(Bin_Pack *bp) const { bin_pack_free(bp); } -}; - -using Bin_Pack_Ptr = std::unique_ptr; - -struct Bin_Unpack_Deleter { - void operator()(Bin_Unpack *bu) const { bin_unpack_free(bu); } -}; - -using Bin_Unpack_Ptr = std::unique_ptr; - TEST(BinPack, TooSmallBufferIsNotExceeded) { - std::array buf; - Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size())); - ASSERT_NE(bp, nullptr); - EXPECT_FALSE(bin_pack_u64_b(bp.get(), 1234567812345678LL)); + const uint64_t orig = 1234567812345678LL; + std::array buf; + EXPECT_FALSE(bin_pack_obj( + [](const void *obj, const Logger *logger, Bin_Pack *bp) { + return bin_pack_u64_b(bp, *static_cast(obj)); + }, + &orig, nullptr, buf.data(), buf.size())); } TEST(BinPack, PackedUint64CanBeUnpacked) { + const uint64_t orig = 1234567812345678LL; std::array buf; - Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size())); - ASSERT_NE(bp, nullptr); - ASSERT_TRUE(bin_pack_u64_b(bp.get(), 1234567812345678LL)); + EXPECT_TRUE(bin_pack_obj( + [](const void *obj, const Logger *logger, Bin_Pack *bp) { + return bin_pack_u64_b(bp, *static_cast(obj)); + }, + &orig, nullptr, buf.data(), buf.size())); - Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size())); - ASSERT_NE(bu, nullptr); - uint64_t val; - ASSERT_TRUE(bin_unpack_u64_b(bu.get(), &val)); - EXPECT_EQ(val, 1234567812345678LL); + uint64_t unpacked; + EXPECT_TRUE(bin_unpack_obj( + [](void *obj, Bin_Unpack *bu) { + return bin_unpack_u64_b(bu, static_cast(obj)); + }, + &unpacked, buf.data(), buf.size())); + EXPECT_EQ(unpacked, 1234567812345678LL); } TEST(BinPack, MsgPackedUint8CanBeUnpackedAsUint32) { + const uint8_t orig = 123; std::array buf; - Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size())); - ASSERT_NE(bp, nullptr); - ASSERT_TRUE(bin_pack_u08(bp.get(), 123)); + EXPECT_TRUE(bin_pack_obj( + [](const void *obj, const Logger *logger, Bin_Pack *bp) { + return bin_pack_u08(bp, *static_cast(obj)); + }, + &orig, nullptr, buf.data(), buf.size())); - Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size())); - ASSERT_NE(bu, nullptr); - uint32_t val; - ASSERT_TRUE(bin_unpack_u32(bu.get(), &val)); - EXPECT_EQ(val, 123); + uint32_t unpacked; + EXPECT_TRUE(bin_unpack_obj( + [](void *obj, Bin_Unpack *bu) { return bin_unpack_u32(bu, static_cast(obj)); }, + &unpacked, buf.data(), buf.size())); + EXPECT_EQ(unpacked, 123); } TEST(BinPack, MsgPackedUint32CanBeUnpackedAsUint8IfSmallEnough) { + const uint32_t orig = 123; std::array buf; - Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size())); - ASSERT_NE(bp, nullptr); - ASSERT_TRUE(bin_pack_u32(bp.get(), 123)); + EXPECT_TRUE(bin_pack_obj( + [](const void *obj, const Logger *logger, Bin_Pack *bp) { + return bin_pack_u32(bp, *static_cast(obj)); + }, + &orig, nullptr, buf.data(), buf.size())); - Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size())); - ASSERT_NE(bu, nullptr); - uint8_t val; - ASSERT_TRUE(bin_unpack_u08(bu.get(), &val)); - EXPECT_EQ(val, 123); + uint8_t unpacked; + EXPECT_TRUE(bin_unpack_obj( + [](void *obj, Bin_Unpack *bu) { return bin_unpack_u08(bu, static_cast(obj)); }, + &unpacked, buf.data(), buf.size())); + + EXPECT_EQ(unpacked, 123); } TEST(BinPack, LargeMsgPackedUint32CannotBeUnpackedAsUint8) { + const uint32_t orig = 1234567; std::array buf; - Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size())); - ASSERT_NE(bp, nullptr); - ASSERT_TRUE(bin_pack_u32(bp.get(), 1234567)); + EXPECT_TRUE(bin_pack_obj( + [](const void *obj, const Logger *logger, Bin_Pack *bp) { + return bin_pack_u32(bp, *static_cast(obj)); + }, + &orig, nullptr, buf.data(), buf.size())); - Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size())); - ASSERT_NE(bu, nullptr); - uint8_t val; - EXPECT_FALSE(bin_unpack_u08(bu.get(), &val)); + uint8_t unpacked; + EXPECT_FALSE(bin_unpack_obj( + [](void *obj, Bin_Unpack *bu) { return bin_unpack_u08(bu, static_cast(obj)); }, + &unpacked, buf.data(), buf.size())); } TEST(BinPack, BinCanHoldPackedInts) { - std::array buf; - Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size())); - ASSERT_NE(bp, nullptr); - ASSERT_TRUE(bin_pack_bin_marker(bp.get(), 8)); - ASSERT_TRUE(bin_pack_u64_b(bp.get(), 1234567812345678LL)); - ASSERT_TRUE(bin_pack_u16_b(bp.get(), 54321)); + struct Stuff { + uint64_t u64; + uint16_t u16; + }; + const Stuff orig = {1234567812345678LL, 54321}; + static const uint32_t packed_size = sizeof(uint64_t) + sizeof(uint16_t); - Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size())); - ASSERT_NE(bu, nullptr); - uint32_t size; - EXPECT_TRUE(bin_unpack_bin_size(bu.get(), &size)); - EXPECT_EQ(size, 8); - uint64_t val1; - EXPECT_TRUE(bin_unpack_u64_b(bu.get(), &val1)); - EXPECT_EQ(val1, 1234567812345678LL); - uint16_t val2; - EXPECT_TRUE(bin_unpack_u16_b(bu.get(), &val2)); - EXPECT_EQ(val2, 54321); + std::array buf; + EXPECT_TRUE(bin_pack_obj( + [](const void *obj, const Logger *logger, Bin_Pack *bp) { + const Stuff *self = static_cast(obj); + return bin_pack_bin_marker(bp, packed_size) // + && bin_pack_u64_b(bp, self->u64) // + && bin_pack_u16_b(bp, self->u16); + }, + &orig, nullptr, buf.data(), buf.size())); + + Stuff unpacked; + EXPECT_TRUE(bin_unpack_obj( + [](void *obj, Bin_Unpack *bu) { + Stuff *stuff = static_cast(obj); + uint32_t size; + return bin_unpack_bin_size(bu, &size) // + && size == 10 // + && bin_unpack_u64_b(bu, &stuff->u64) // + && bin_unpack_u16_b(bu, &stuff->u16); + }, + &unpacked, buf.data(), buf.size())); + EXPECT_EQ(unpacked.u64, 1234567812345678LL); + EXPECT_EQ(unpacked.u16, 54321); } TEST(BinPack, BinCanHoldArbitraryData) { std::array buf; - Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size())); - ASSERT_NE(bp, nullptr); - ASSERT_TRUE(bin_pack_bin_marker(bp.get(), 5)); - ASSERT_TRUE(bin_pack_bin_b(bp.get(), reinterpret_cast("hello"), 5)); + EXPECT_TRUE(bin_pack_obj( + [](const void *obj, const Logger *logger, Bin_Pack *bp) { + return bin_pack_bin_marker(bp, 5) // + && bin_pack_bin_b(bp, reinterpret_cast("hello"), 5); + }, + nullptr, nullptr, buf.data(), buf.size())); - Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size())); - ASSERT_NE(bu, nullptr); std::array str; - EXPECT_TRUE(bin_unpack_bin_fixed(bu.get(), str.data(), str.size())); + EXPECT_TRUE(bin_unpack_obj( + [](void *obj, Bin_Unpack *bu) { + uint8_t *data = static_cast(obj); + return bin_unpack_bin_fixed(bu, data, 5); + }, + str.data(), buf.data(), buf.size())); EXPECT_EQ(str, (std::array{'h', 'e', 'l', 'l', 'o'})); } @@ -126,9 +150,13 @@ TEST(BinPack, OversizedArrayFailsUnpack) { std::array buf = {0x91}; - Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size())); uint32_t size; - EXPECT_FALSE(bin_unpack_array(bu.get(), &size)); + EXPECT_FALSE(bin_unpack_obj( + [](void *obj, Bin_Unpack *bu) { + uint32_t *size_ptr = static_cast(obj); + return bin_unpack_array(bu, size_ptr); + }, + &size, buf.data(), buf.size())); } } // namespace diff --git a/toxcore/bin_unpack.c b/toxcore/bin_unpack.c index 07fdfcfe..d6b1c52e 100644 --- a/toxcore/bin_unpack.c +++ b/toxcore/bin_unpack.c @@ -9,6 +9,7 @@ #include #include "../third_party/cmp/cmp.h" +#include "attributes.h" #include "ccompat.h" struct Bin_Unpack { @@ -20,27 +21,28 @@ struct Bin_Unpack { non_null() static bool buf_reader(cmp_ctx_t *ctx, void *data, size_t limit) { + uint8_t *bytes = (uint8_t *)data; Bin_Unpack *reader = (Bin_Unpack *)ctx->buf; assert(reader != nullptr && reader->bytes != nullptr); if (limit > reader->bytes_size) { return false; } - memcpy(data, reader->bytes, limit); + memcpy(bytes, reader->bytes, limit); reader->bytes += limit; reader->bytes_size -= limit; return true; } non_null() -static bool buf_skipper(cmp_ctx_t *ctx, size_t limit) +static bool buf_skipper(cmp_ctx_t *ctx, size_t count) { Bin_Unpack *reader = (Bin_Unpack *)ctx->buf; assert(reader != nullptr && reader->bytes != nullptr); - if (limit > reader->bytes_size) { + if (count > reader->bytes_size) { return false; } - reader->bytes += limit; - reader->bytes_size -= limit; + reader->bytes += count; + reader->bytes_size -= count; return true; } @@ -51,21 +53,19 @@ static size_t null_writer(cmp_ctx_t *ctx, const void *data, size_t count) return 0; } -Bin_Unpack *bin_unpack_new(const uint8_t *buf, uint32_t buf_size) +non_null() +static void bin_unpack_init(Bin_Unpack *bu, const uint8_t *buf, uint32_t buf_size) { - Bin_Unpack *bu = (Bin_Unpack *)calloc(1, sizeof(Bin_Unpack)); - if (bu == nullptr) { - return nullptr; - } bu->bytes = buf; bu->bytes_size = buf_size; cmp_init(&bu->ctx, bu, buf_reader, buf_skipper, null_writer); - return bu; } -void bin_unpack_free(Bin_Unpack *bu) +bool bin_unpack_obj(bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size) { - free(bu); + Bin_Unpack bu; + bin_unpack_init(&bu, buf, buf_size); + return callback(obj, &bu); } bool bin_unpack_array(Bin_Unpack *bu, uint32_t *size) @@ -169,7 +169,7 @@ bool bin_unpack_u16_b(Bin_Unpack *bu, uint16_t *val) uint8_t hi = 0; uint8_t lo = 0; if (!(bin_unpack_u08_b(bu, &hi) - && bin_unpack_u08_b(bu, &lo))) { + && bin_unpack_u08_b(bu, &lo))) { return false; } *val = ((uint16_t)hi << 8) | lo; @@ -181,7 +181,7 @@ bool bin_unpack_u32_b(Bin_Unpack *bu, uint32_t *val) uint16_t hi = 0; uint16_t lo = 0; if (!(bin_unpack_u16_b(bu, &hi) - && bin_unpack_u16_b(bu, &lo))) { + && bin_unpack_u16_b(bu, &lo))) { return false; } *val = ((uint32_t)hi << 16) | lo; @@ -193,7 +193,7 @@ bool bin_unpack_u64_b(Bin_Unpack *bu, uint64_t *val) uint32_t hi = 0; uint32_t lo = 0; if (!(bin_unpack_u32_b(bu, &hi) - && bin_unpack_u32_b(bu, &lo))) { + && bin_unpack_u32_b(bu, &lo))) { return false; } *val = ((uint64_t)hi << 32) | lo; diff --git a/toxcore/bin_unpack.h b/toxcore/bin_unpack.h index 441318a8..0554bd1a 100644 --- a/toxcore/bin_unpack.h +++ b/toxcore/bin_unpack.h @@ -16,25 +16,37 @@ extern "C" { /** * @brief Binary deserialisation object. + * + * User code never creates this object. It is created and destroyed within the below functions, + * and passed to the callback. This enforces an alloc/dealloc bracket, so user code can never + * forget to clean up an unpacker. */ typedef struct Bin_Unpack Bin_Unpack; -/** @brief Allocate a new unpacker object. +/** @brief Function used to unpack an object. * - * @param buf The byte array to unpack values from. + * This function would typically cast the `void *` to the actual object pointer type and then call + * more appropriately typed unpacking functions. + */ +typedef bool bin_unpack_cb(void *obj, Bin_Unpack *bu); + +/** @brief Unpack an object from a buffer of a given size. + * + * This function creates and initialises a `Bin_Unpack` object, calls the callback with the + * unpacker object and the to-be-unpacked object, and then cleans up the unpacker object. + * + * Unlike `bin_pack_obj`, this function does not support NULL anywhere. The input array + * must be non-null, even if it is zero-length. + * + * @param callback The function called on the created unpacker and unpacked object. + * @param obj The object to be packed, passed as `obj` to the callback. + * @param buf A byte array containing the serialised representation of `obj`. * @param buf_size The size of the byte array. * - * @retval nullptr on allocation failure. + * @retval false if an error occurred (e.g. buffer overrun). */ non_null() -Bin_Unpack *bin_unpack_new(const uint8_t *buf, uint32_t buf_size); - -/** @brief Deallocates an unpacker object. - * - * Does not deallocate the buffer inside. - */ -nullable(1) -void bin_unpack_free(Bin_Unpack *bu); +bool bin_unpack_obj(bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size); /** @brief Start unpacking a MessagePack array. * @@ -107,7 +119,7 @@ non_null() bool bin_unpack_u64_b(Bin_Unpack *bu, uint64_t *val); non_null() bool bin_unpack_bin_b(Bin_Unpack *bu, uint8_t *data, uint32_t length); #ifdef __cplusplus -} // extern "C" +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_BIN_UNPACK_H +#endif /* C_TOXCORE_TOXCORE_BIN_UNPACK_H */ diff --git a/toxcore/ccompat.h b/toxcore/ccompat.h index 9ea6739a..47ab9ed2 100644 --- a/toxcore/ccompat.h +++ b/toxcore/ccompat.h @@ -26,7 +26,6 @@ #if !defined(DISABLE_VLA) && !defined(_MSC_VER) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99 VLAs. #define ALLOC_VLA(type, name, size) type name[size] -#define SIZEOF_VLA sizeof #else // Emulation using alloca. @@ -47,9 +46,7 @@ #endif #define ALLOC_VLA(type, name, size) \ - const size_t name##_vla_size = (size) * sizeof(type); \ - type *const name = (type *)alloca(name##_vla_size) -#define SIZEOF_VLA(name) name##_vla_size + type *const name = (type *)alloca((size) * sizeof(type)) #endif @@ -72,16 +69,10 @@ #define STATIC_ASSERT_(cond, msg, line) typedef int static_assert_##line[(cond) ? 1 : -1] #define STATIC_ASSERT(cond, msg, line) STATIC_ASSERT_(cond, msg, line) #define static_assert(cond, msg) STATIC_ASSERT(cond, msg, __LINE__) -#endif // !__GNUC__ -#endif // !static_assert -#endif // !__cplusplus - -#ifdef __GNUC__ -#define GNU_PRINTF(f, a) __attribute__((__format__(__printf__, f, a))) -#else -#define GNU_PRINTF(f, a) -#endif +#endif /* !__GNUC__ */ +#endif /* !static_assert */ +#endif /* !__cplusplus */ //!TOKSTYLE+ -#endif // C_TOXCORE_TOXCORE_CCOMPAT_H +#endif /* C_TOXCORE_TOXCORE_CCOMPAT_H */ diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 1f9fde72..7bb5bb92 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -1,13 +1,8 @@ /* SPDX-License-Identifier: GPL-3.0-or-later - * Copyright © 2016-2018 The TokTok team. + * Copyright © 2016-2024 The TokTok team. * Copyright © 2013 Tox project. */ -/** - * Functions for the core crypto. - * - * NOTE: This code has to be perfect. We don't mess around with encryption. - */ #include "crypto_core.h" #include @@ -16,15 +11,9 @@ #include +#include "attributes.h" #include "ccompat.h" - -#ifndef crypto_box_MACBYTES -#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) -#endif - -// Need dht because of ENC_SECRET_KEY_SIZE and ENC_PUBLIC_KEY_SIZE -#define ENC_PUBLIC_KEY_SIZE CRYPTO_PUBLIC_KEY_SIZE -#define ENC_SECRET_KEY_SIZE CRYPTO_SECRET_KEY_SIZE +#include "util.h" static_assert(CRYPTO_PUBLIC_KEY_SIZE == crypto_box_PUBLICKEYBYTES, "CRYPTO_PUBLIC_KEY_SIZE should be equal to crypto_box_PUBLICKEYBYTES"); @@ -56,43 +45,46 @@ static_assert(CRYPTO_SIGN_PUBLIC_KEY_SIZE == crypto_sign_PUBLICKEYBYTES, static_assert(CRYPTO_SIGN_SECRET_KEY_SIZE == crypto_sign_SECRETKEYBYTES, "CRYPTO_SIGN_SECRET_KEY_SIZE should be equal to crypto_sign_SECRETKEYBYTES"); -bool create_extended_keypair(uint8_t *pk, uint8_t *sk) +bool create_extended_keypair(Extended_Public_Key *pk, Extended_Secret_Key *sk, const Random *rng) { /* create signature key pair */ - crypto_sign_keypair(pk + ENC_PUBLIC_KEY_SIZE, sk + ENC_SECRET_KEY_SIZE); + uint8_t seed[crypto_sign_SEEDBYTES]; + random_bytes(rng, seed, crypto_sign_SEEDBYTES); + crypto_sign_seed_keypair(pk->sig, sk->sig, seed); + crypto_memzero(seed, crypto_sign_SEEDBYTES); /* convert public signature key to public encryption key */ - const int res1 = crypto_sign_ed25519_pk_to_curve25519(pk, pk + ENC_PUBLIC_KEY_SIZE); + const int res1 = crypto_sign_ed25519_pk_to_curve25519(pk->enc, pk->sig); /* convert secret signature key to secret encryption key */ - const int res2 = crypto_sign_ed25519_sk_to_curve25519(sk, sk + ENC_SECRET_KEY_SIZE); + const int res2 = crypto_sign_ed25519_sk_to_curve25519(sk->enc, sk->sig); return res1 == 0 && res2 == 0; } -const uint8_t *get_enc_key(const uint8_t *key) +const uint8_t *get_enc_key(const Extended_Public_Key *key) { - return key; + return key->enc; } -const uint8_t *get_sig_pk(const uint8_t *key) +const uint8_t *get_sig_pk(const Extended_Public_Key *key) { - return key + ENC_PUBLIC_KEY_SIZE; + return key->sig; } -void set_sig_pk(uint8_t *key, const uint8_t *sig_pk) +void set_sig_pk(Extended_Public_Key *key, const uint8_t *sig_pk) { - memcpy(key + ENC_PUBLIC_KEY_SIZE, sig_pk, SIG_PUBLIC_KEY_SIZE); + memcpy(key->sig, sig_pk, SIG_PUBLIC_KEY_SIZE); } -const uint8_t *get_sig_sk(const uint8_t *key) +const uint8_t *get_sig_sk(const Extended_Secret_Key *key) { - return key + ENC_SECRET_KEY_SIZE; + return key->sig; } -const uint8_t *get_chat_id(const uint8_t *key) +const uint8_t *get_chat_id(const Extended_Public_Key *key) { - return key + ENC_PUBLIC_KEY_SIZE; + return key->sig; } #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) @@ -117,15 +109,15 @@ static void crypto_free(uint8_t *ptr, size_t bytes) free(ptr); } -#endif // !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) +#endif /* !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) */ void crypto_memzero(void *data, size_t length) { #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) - memset(data, 0, length); + memzero((uint8_t *)data, length); #else sodium_memzero(data, length); -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ } bool crypto_memlock(void *data, size_t length) @@ -134,12 +126,8 @@ bool crypto_memlock(void *data, size_t length) return false; #else - if (sodium_mlock(data, length) != 0) { - return false; - } - - return true; -#endif + return sodium_mlock(data, length) == 0; +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ } bool crypto_memunlock(void *data, size_t length) @@ -148,12 +136,8 @@ bool crypto_memunlock(void *data, size_t length) return false; #else - if (sodium_munlock(data, length) != 0) { - return false; - } - - return true; -#endif + return sodium_munlock(data, length) == 0; +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ } bool pk_equal(const uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE]) @@ -163,7 +147,7 @@ bool pk_equal(const uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t pk2[CRYPT return memcmp(pk1, pk2, CRYPTO_PUBLIC_KEY_SIZE) == 0; #else return crypto_verify_32(pk1, pk2) == 0; -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ } void pk_copy(uint8_t dest[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t src[CRYPTO_PUBLIC_KEY_SIZE]) @@ -171,24 +155,24 @@ void pk_copy(uint8_t dest[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t src[CRYPTO_PUBL memcpy(dest, src, CRYPTO_PUBLIC_KEY_SIZE); } -bool crypto_sha512_eq(const uint8_t *cksum1, const uint8_t *cksum2) +bool crypto_sha512_eq(const uint8_t cksum1[CRYPTO_SHA512_SIZE], const uint8_t cksum2[CRYPTO_SHA512_SIZE]) { #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) // Hope that this is better for the fuzzer return memcmp(cksum1, cksum2, CRYPTO_SHA512_SIZE) == 0; #else return crypto_verify_64(cksum1, cksum2) == 0; -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ } -bool crypto_sha256_eq(const uint8_t *cksum1, const uint8_t *cksum2) +bool crypto_sha256_eq(const uint8_t cksum1[CRYPTO_SHA256_SIZE], const uint8_t cksum2[CRYPTO_SHA256_SIZE]) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION // Hope that this is better for the fuzzer return memcmp(cksum1, cksum2, CRYPTO_SHA256_SIZE) == 0; #else return crypto_verify_32(cksum1, cksum2) == 0; -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ } uint8_t random_u08(const Random *rng) @@ -224,36 +208,40 @@ uint32_t random_range_u32(const Random *rng, uint32_t upper_bound) return rng->funcs->random_uniform(rng->obj, upper_bound); } -bool crypto_signature_create(uint8_t *signature, const uint8_t *message, uint64_t message_length, - const uint8_t *secret_key) +bool crypto_signature_create(uint8_t signature[CRYPTO_SIGNATURE_SIZE], + const uint8_t *message, uint64_t message_length, + const uint8_t secret_key[SIG_SECRET_KEY_SIZE]) { return crypto_sign_detached(signature, nullptr, message, message_length, secret_key) == 0; } -bool crypto_signature_verify(const uint8_t *signature, const uint8_t *message, uint64_t message_length, - const uint8_t *public_key) +bool crypto_signature_verify(const uint8_t signature[CRYPTO_SIGNATURE_SIZE], + const uint8_t *message, uint64_t message_length, + const uint8_t public_key[SIG_PUBLIC_KEY_SIZE]) { return crypto_sign_verify_detached(signature, message, message_length, public_key) == 0; } -bool public_key_valid(const uint8_t *public_key) +bool public_key_valid(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) { /* Last bit of key is always zero. */ return public_key[31] < 128; } -int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, - uint8_t *shared_key) +int32_t encrypt_precompute(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE], + uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION memcpy(shared_key, public_key, CRYPTO_SHARED_KEY_SIZE); return 0; #else return crypto_box_beforenm(shared_key, public_key, secret_key); -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ } -int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, +int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *plain, size_t length, uint8_t *encrypted) { if (length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { @@ -264,7 +252,7 @@ int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, // Don't encrypt anything. memcpy(encrypted, plain, length); // Zero MAC to avoid uninitialized memory reads. - memset(encrypted + length, 0, crypto_box_MACBYTES); + memzero(encrypted + length, crypto_box_MACBYTES); #else const size_t size_temp_plain = length + crypto_box_ZEROBYTES; @@ -282,9 +270,9 @@ int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, // crypto_box_afternm requires the entire range of the output array be // initialised with something. It doesn't matter what it's initialised with, // so we'll pick 0x00. - memset(temp_encrypted, 0, size_temp_encrypted); + memzero(temp_encrypted, size_temp_encrypted); - memset(temp_plain, 0, crypto_box_ZEROBYTES); + memzero(temp_plain, crypto_box_ZEROBYTES); // Pad the message with 32 0 bytes. memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); @@ -300,12 +288,13 @@ int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, crypto_free(temp_plain, size_temp_plain); crypto_free(temp_encrypted, size_temp_encrypted); -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ assert(length < INT32_MAX - crypto_box_MACBYTES); return (int32_t)(length + crypto_box_MACBYTES); } -int32_t decrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, +int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t length, uint8_t *plain) { if (length <= crypto_box_BOXZEROBYTES || shared_key == nullptr || nonce == nullptr || encrypted == nullptr @@ -333,9 +322,9 @@ int32_t decrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, // crypto_box_open_afternm requires the entire range of the output array be // initialised with something. It doesn't matter what it's initialised with, // so we'll pick 0x00. - memset(temp_plain, 0, size_temp_plain); + memzero(temp_plain, size_temp_plain); - memset(temp_encrypted, 0, crypto_box_BOXZEROBYTES); + memzero(temp_encrypted, crypto_box_BOXZEROBYTES); // Pad the message with 16 0 bytes. memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); @@ -350,13 +339,15 @@ int32_t decrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, crypto_free(temp_plain, size_temp_plain); crypto_free(temp_encrypted, size_temp_encrypted); -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ assert(length > crypto_box_MACBYTES); assert(length < INT32_MAX); return (int32_t)(length - crypto_box_MACBYTES); } -int32_t encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, +int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE], + const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *plain, size_t length, uint8_t *encrypted) { if (public_key == nullptr || secret_key == nullptr) { @@ -370,7 +361,9 @@ int32_t encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const return ret; } -int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, +int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE], + const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t length, uint8_t *plain) { if (public_key == nullptr || secret_key == nullptr) { @@ -384,7 +377,7 @@ int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const return ret; } -void increment_nonce(uint8_t *nonce) +void increment_nonce(uint8_t nonce[CRYPTO_NONCE_SIZE]) { /* TODO(irungentoo): use `increment_nonce_number(nonce, 1)` or * sodium_increment (change to little endian). @@ -403,7 +396,7 @@ void increment_nonce(uint8_t *nonce) } } -void increment_nonce_number(uint8_t *nonce, uint32_t increment) +void increment_nonce_number(uint8_t nonce[CRYPTO_NONCE_SIZE], uint32_t increment) { /* NOTE don't use breaks inside this loop * In particular, make sure, as far as possible, @@ -425,25 +418,28 @@ void increment_nonce_number(uint8_t *nonce, uint32_t increment) } } -void random_nonce(const Random *rng, uint8_t *nonce) +void random_nonce(const Random *rng, uint8_t nonce[CRYPTO_NONCE_SIZE]) { random_bytes(rng, nonce, crypto_box_NONCEBYTES); } -void new_symmetric_key(const Random *rng, uint8_t *key) +void new_symmetric_key(const Random *rng, uint8_t key[CRYPTO_SYMMETRIC_KEY_SIZE]) { random_bytes(rng, key, CRYPTO_SYMMETRIC_KEY_SIZE); } -int32_t crypto_new_keypair(const Random *rng, uint8_t *public_key, uint8_t *secret_key) +int32_t crypto_new_keypair(const Random *rng, + uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], + uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE]) { random_bytes(rng, secret_key, CRYPTO_SECRET_KEY_SIZE); - memset(public_key, 0, CRYPTO_PUBLIC_KEY_SIZE); // Make MSAN happy + memzero(public_key, CRYPTO_PUBLIC_KEY_SIZE); // Make MSAN happy crypto_derive_public_key(public_key, secret_key); return 0; } -void crypto_derive_public_key(uint8_t *public_key, const uint8_t *secret_key) +void crypto_derive_public_key(uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE]) { crypto_scalarmult_curve25519_base(public_key, secret_key); } @@ -453,15 +449,15 @@ void new_hmac_key(const Random *rng, uint8_t key[CRYPTO_HMAC_KEY_SIZE]) random_bytes(rng, key, CRYPTO_HMAC_KEY_SIZE); } -void crypto_hmac(uint8_t auth[CRYPTO_HMAC_SIZE], const uint8_t key[CRYPTO_HMAC_KEY_SIZE], const uint8_t *data, - size_t length) +void crypto_hmac(uint8_t auth[CRYPTO_HMAC_SIZE], const uint8_t key[CRYPTO_HMAC_KEY_SIZE], + const uint8_t *data, size_t length) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION memcpy(auth, key, 16); memcpy(auth + 16, data, length < 16 ? length : 16); #else crypto_auth(auth, data, length, key); -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ } bool crypto_hmac_verify(const uint8_t auth[CRYPTO_HMAC_SIZE], const uint8_t key[CRYPTO_HMAC_KEY_SIZE], @@ -471,27 +467,27 @@ bool crypto_hmac_verify(const uint8_t auth[CRYPTO_HMAC_SIZE], const uint8_t key[ return memcmp(auth, key, 16) == 0 && memcmp(auth + 16, data, length < 16 ? length : 16) == 0; #else return crypto_auth_verify(auth, data, length, key) == 0; -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ } -void crypto_sha256(uint8_t *hash, const uint8_t *data, size_t length) +void crypto_sha256(uint8_t hash[CRYPTO_SHA256_SIZE], const uint8_t *data, size_t length) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - memset(hash, 0, CRYPTO_SHA256_SIZE); + memzero(hash, CRYPTO_SHA256_SIZE); memcpy(hash, data, length < CRYPTO_SHA256_SIZE ? length : CRYPTO_SHA256_SIZE); #else crypto_hash_sha256(hash, data, length); -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ } -void crypto_sha512(uint8_t *hash, const uint8_t *data, size_t length) +void crypto_sha512(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t length) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - memset(hash, 0, CRYPTO_SHA512_SIZE); + memzero(hash, CRYPTO_SHA512_SIZE); memcpy(hash, data, length < CRYPTO_SHA512_SIZE ? length : CRYPTO_SHA512_SIZE); #else crypto_hash_sha512(hash, data, length); -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ } non_null() @@ -506,26 +502,26 @@ static uint32_t sys_random_uniform(void *obj, uint32_t upper_bound) return randombytes_uniform(upper_bound); } -static const Random_Funcs system_random_funcs = { +static const Random_Funcs os_random_funcs = { sys_random_bytes, sys_random_uniform, }; -static const Random system_random_obj = {&system_random_funcs}; +static const Random os_random_obj = {&os_random_funcs}; -const Random *system_random(void) +const Random *os_random(void) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if ((true)) { return nullptr; } -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ // It is safe to call this function more than once and from different // threads -- subsequent calls won't have any effects. if (sodium_init() == -1) { return nullptr; } - return &system_random_obj; + return &os_random_obj; } void random_bytes(const Random *rng, uint8_t *bytes, size_t length) diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index bfcddc31..979791bd 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -1,10 +1,12 @@ /* SPDX-License-Identifier: GPL-3.0-or-later - * Copyright © 2016-2018 The TokTok team. + * Copyright © 2016-2024 The TokTok team. * Copyright © 2013 Tox project. */ /** @file * @brief Functions for the core crypto. + * + * @note This code has to be perfect. We don't mess around with encryption. */ #ifndef C_TOXCORE_TOXCORE_CRYPTO_CORE_H #define C_TOXCORE_TOXCORE_CRYPTO_CORE_H @@ -20,17 +22,17 @@ extern "C" { #endif /** - * The number of bytes in a signature. + * @brief The number of bytes in a signature. */ #define CRYPTO_SIGNATURE_SIZE 64 /** - * The number of bytes in a Tox public key used for signatures. + * @brief The number of bytes in a Tox public key used for signatures. */ #define CRYPTO_SIGN_PUBLIC_KEY_SIZE 32 /** - * The number of bytes in a Tox secret key used for signatures. + * @brief The number of bytes in a Tox secret key used for signatures. */ #define CRYPTO_SIGN_SECRET_KEY_SIZE 64 @@ -75,20 +77,43 @@ extern "C" { */ #define CRYPTO_SHA512_SIZE 64 +/** @brief Fill a byte array with random bytes. + * + * This is the key generator callback and as such must be a cryptographically + * secure pseudo-random number generator (CSPRNG). The security of Tox heavily + * depends on the security of this RNG. + */ typedef void crypto_random_bytes_cb(void *obj, uint8_t *bytes, size_t length); + +/** @brief Generate a random integer between 0 and @p upper_bound. + * + * Should produce a uniform random distribution, but Tox security does not + * depend on this being correct. In principle, it could even be a non-CSPRNG. + */ typedef uint32_t crypto_random_uniform_cb(void *obj, uint32_t upper_bound); +/** @brief Virtual function table for Random. */ typedef struct Random_Funcs { crypto_random_bytes_cb *random_bytes; crypto_random_uniform_cb *random_uniform; } Random_Funcs; +/** @brief Random number generator object. + * + * Can be used by test code and fuzzers to make toxcore behave in specific + * well-defined (non-random) ways. Production code ought to use libsodium's + * CSPRNG and use `os_random` below. + */ typedef struct Random { const Random_Funcs *funcs; void *obj; } Random; -const Random *system_random(void); +/** @brief System random number generator. + * + * Uses libsodium's CSPRNG (on Linux, `/dev/urandom`). + */ +const Random *os_random(void); /** * @brief The number of bytes in an encryption public key used by DHT group chats. @@ -147,25 +172,29 @@ void crypto_memzero(void *data, size_t length); /** * @brief Compute a SHA256 hash (32 bytes). + * + * @param[out] hash The SHA256 hash of @p data will be written to this byte array. */ non_null() -void crypto_sha256(uint8_t *hash, const uint8_t *data, size_t length); +void crypto_sha256(uint8_t hash[CRYPTO_SHA256_SIZE], const uint8_t *data, size_t length); /** * @brief Compute a SHA512 hash (64 bytes). + * + * @param[out] hash The SHA512 hash of @p data will be written to this byte array. */ non_null() -void crypto_sha512(uint8_t *hash, const uint8_t *data, size_t length); +void crypto_sha512(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t length); /** * @brief Compute an HMAC authenticator (32 bytes). * - * @param auth Resulting authenticator. + * @param[out] auth Resulting authenticator. * @param key Secret key, as generated by `new_hmac_key()`. */ non_null() -void crypto_hmac(uint8_t auth[CRYPTO_HMAC_SIZE], const uint8_t key[CRYPTO_HMAC_KEY_SIZE], const uint8_t *data, - size_t length); +void crypto_hmac(uint8_t auth[CRYPTO_HMAC_SIZE], const uint8_t key[CRYPTO_HMAC_KEY_SIZE], + const uint8_t *data, size_t length); /** * @brief Verify an HMAC authenticator. @@ -176,7 +205,7 @@ bool crypto_hmac_verify(const uint8_t auth[CRYPTO_HMAC_SIZE], const uint8_t key[ /** * @brief Compare 2 public keys of length @ref CRYPTO_PUBLIC_KEY_SIZE, not vulnerable to - * timing attacks. + * timing attacks. * * @retval true if both mem locations of length are equal * @retval false if they are not @@ -192,21 +221,21 @@ void pk_copy(uint8_t dest[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t src[CRYPTO_PUBL /** * @brief Compare 2 SHA512 checksums of length CRYPTO_SHA512_SIZE, not vulnerable to - * timing attacks. + * timing attacks. * * @return true if both mem locations of length are equal, false if they are not. */ non_null() -bool crypto_sha512_eq(const uint8_t *cksum1, const uint8_t *cksum2); +bool crypto_sha512_eq(const uint8_t cksum1[CRYPTO_SHA512_SIZE], const uint8_t cksum2[CRYPTO_SHA512_SIZE]); /** * @brief Compare 2 SHA256 checksums of length CRYPTO_SHA256_SIZE, not vulnerable to - * timing attacks. + * timing attacks. * * @return true if both mem locations of length are equal, false if they are not. */ non_null() -bool crypto_sha256_eq(const uint8_t *cksum1, const uint8_t *cksum2); +bool crypto_sha256_eq(const uint8_t cksum1[CRYPTO_SHA256_SIZE], const uint8_t cksum2[CRYPTO_SHA256_SIZE]); /** * @brief Return a random 8 bit integer. @@ -240,10 +269,11 @@ uint64_t random_u64(const Random *rng); non_null() uint32_t random_range_u32(const Random *rng, uint32_t upper_bound); -/** @brief Cryptographically signs a message using the supplied secret key and puts the resulting signature - * in the supplied buffer. +/** + * @brief Cryptographically signs a message using the supplied secret key and puts the resulting signature + * in the supplied buffer. * - * @param signature The buffer for the resulting signature, which must have room for at + * @param[out] signature The buffer for the resulting signature, which must have room for at * least CRYPTO_SIGNATURE_SIZE bytes. * @param message The message being signed. * @param message_length The length in bytes of the message being signed. @@ -253,8 +283,9 @@ uint32_t random_range_u32(const Random *rng, uint32_t upper_bound); * @retval true on success. */ non_null() -bool crypto_signature_create(uint8_t *signature, const uint8_t *message, uint64_t message_length, - const uint8_t *secret_key); +bool crypto_signature_create(uint8_t signature[CRYPTO_SIGNATURE_SIZE], + const uint8_t *message, uint64_t message_length, + const uint8_t secret_key[SIG_SECRET_KEY_SIZE]); /** @brief Verifies that the given signature was produced by a given message and public key. * @@ -267,14 +298,15 @@ bool crypto_signature_create(uint8_t *signature, const uint8_t *message, uint64_ * @retval true on success. */ non_null() -bool crypto_signature_verify(const uint8_t *signature, const uint8_t *message, uint64_t message_length, - const uint8_t *public_key); +bool crypto_signature_verify(const uint8_t signature[CRYPTO_SIGNATURE_SIZE], + const uint8_t *message, uint64_t message_length, + const uint8_t public_key[SIG_PUBLIC_KEY_SIZE]); /** * @brief Fill the given nonce with random bytes. */ non_null() -void random_nonce(const Random *rng, uint8_t *nonce); +void random_nonce(const Random *rng, uint8_t nonce[CRYPTO_NONCE_SIZE]); /** * @brief Fill an array of bytes with random values. @@ -290,25 +322,40 @@ void random_bytes(const Random *rng, uint8_t *bytes, size_t length); * @return false if it isn't, true if it is. */ non_null() -bool public_key_valid(const uint8_t *public_key); +bool public_key_valid(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]); -/** @brief Creates an extended keypair: curve25519 and ed25519 for encryption and signing +typedef struct Extended_Public_Key { + uint8_t enc[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t sig[CRYPTO_SIGN_PUBLIC_KEY_SIZE]; +} Extended_Public_Key; + +typedef struct Extended_Secret_Key { + uint8_t enc[CRYPTO_SECRET_KEY_SIZE]; + uint8_t sig[CRYPTO_SIGN_SECRET_KEY_SIZE]; +} Extended_Secret_Key; + +/** + * @brief Creates an extended keypair: curve25519 and ed25519 for encryption and signing * respectively. The Encryption keys are derived from the signature keys. * - * @param pk The buffer where the public key will be stored. Must have room for EXT_PUBLIC_KEY_SIZE bytes. - * @param sk The buffer where the secret key will be stored. Must have room for EXT_SECRET_KEY_SIZE bytes. + * NOTE: This does *not* use Random, so any code using this will not be fuzzable. + * TODO: Make it use Random. + * + * @param[out] pk The buffer where the public key will be stored. Must have room for EXT_PUBLIC_KEY_SIZE bytes. + * @param[out] sk The buffer where the secret key will be stored. Must have room for EXT_SECRET_KEY_SIZE bytes. + * @param rng The random number generator to use for the key generator seed. * * @retval true on success. */ non_null() -bool create_extended_keypair(uint8_t *pk, uint8_t *sk); +bool create_extended_keypair(Extended_Public_Key *pk, Extended_Secret_Key *sk, const Random *rng); /** Functions for groupchat extended keys */ -non_null() const uint8_t *get_enc_key(const uint8_t *key); -non_null() const uint8_t *get_sig_pk(const uint8_t *key); -non_null() void set_sig_pk(uint8_t *key, const uint8_t *sig_pk); -non_null() const uint8_t *get_sig_sk(const uint8_t *key); -non_null() const uint8_t *get_chat_id(const uint8_t *key); +non_null() const uint8_t *get_enc_key(const Extended_Public_Key *key); +non_null() const uint8_t *get_sig_pk(const Extended_Public_Key *key); +non_null() void set_sig_pk(Extended_Public_Key *key, const uint8_t *sig_pk); +non_null() const uint8_t *get_sig_sk(const Extended_Secret_Key *key); +non_null() const uint8_t *get_chat_id(const Extended_Public_Key *key); /** * @brief Generate a new random keypair. @@ -316,13 +363,16 @@ non_null() const uint8_t *get_chat_id(const uint8_t *key); * Every call to this function is likely to generate a different keypair. */ non_null() -int32_t crypto_new_keypair(const Random *rng, uint8_t *public_key, uint8_t *secret_key); +int32_t crypto_new_keypair(const Random *rng, + uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], + uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE]); /** * @brief Derive the public key from a given secret key. */ non_null() -void crypto_derive_public_key(uint8_t *public_key, const uint8_t *secret_key); +void crypto_derive_public_key(uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE]); /** * @brief Encrypt message to send from secret key to public key. @@ -336,8 +386,10 @@ void crypto_derive_public_key(uint8_t *public_key, const uint8_t *secret_key); * @return length of encrypted data if everything was fine. */ non_null() -int32_t encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, - size_t length, uint8_t *encrypted); +int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE], + const uint8_t nonce[CRYPTO_NONCE_SIZE], + const uint8_t *plain, size_t length, uint8_t *encrypted); /** * @brief Decrypt message from public key to secret key. @@ -351,7 +403,9 @@ int32_t encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const * @return length of plain text data if everything was fine. */ non_null() -int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, +int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE], + const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t length, uint8_t *plain); /** @@ -362,21 +416,24 @@ int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const * encrypt/decrypt. */ non_null() -int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, uint8_t *shared_key); +int32_t encrypt_precompute(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], + const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE], + uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]); /** * @brief Encrypt message with precomputed shared key. * * Encrypts plain of length length to encrypted of length + @ref CRYPTO_MAC_SIZE - * using a shared key @ref CRYPTO_SYMMETRIC_KEY_SIZE big and a @ref CRYPTO_NONCE_SIZE + * using a shared key @ref CRYPTO_SHARED_KEY_SIZE big and a @ref CRYPTO_NONCE_SIZE * byte nonce. * * @retval -1 if there was a problem. * @return length of encrypted data if everything was fine. */ non_null() -int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t length, - uint8_t *encrypted); +int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + const uint8_t nonce[CRYPTO_NONCE_SIZE], + const uint8_t *plain, size_t length, uint8_t *encrypted); /** * @brief Decrypt message with precomputed shared key. @@ -389,15 +446,15 @@ int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, * @return length of plain data if everything was fine. */ non_null() -int32_t decrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t length, - uint8_t *plain); +int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], + const uint8_t nonce[CRYPTO_NONCE_SIZE], + const uint8_t *encrypted, size_t length, uint8_t *plain); /** - * @brief Increment the given nonce by 1 in big endian (rightmost byte incremented - * first). + * @brief Increment the given nonce by 1 in big endian (rightmost byte incremented first). */ non_null() -void increment_nonce(uint8_t *nonce); +void increment_nonce(uint8_t nonce[CRYPTO_NONCE_SIZE]); /** * @brief Increment the given nonce by a given number. @@ -405,13 +462,13 @@ void increment_nonce(uint8_t *nonce); * The number should be in host byte order. */ non_null() -void increment_nonce_number(uint8_t *nonce, uint32_t increment); +void increment_nonce_number(uint8_t nonce[CRYPTO_NONCE_SIZE], uint32_t increment); /** * @brief Fill a key @ref CRYPTO_SYMMETRIC_KEY_SIZE big with random bytes. */ non_null() -void new_symmetric_key(const Random *rng, uint8_t *key); +void new_symmetric_key(const Random *rng, uint8_t key[CRYPTO_SYMMETRIC_KEY_SIZE]); /** * @brief Locks `length` bytes of memory pointed to by `data`. @@ -445,7 +502,7 @@ non_null() void new_hmac_key(const Random *rng, uint8_t key[CRYPTO_HMAC_KEY_SIZE]); #ifdef __cplusplus -} // extern "C" +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_CRYPTO_CORE_H +#endif /* C_TOXCORE_TOXCORE_CRYPTO_CORE_H */ diff --git a/toxcore/crypto_core_pack.c b/toxcore/crypto_core_pack.c new file mode 100644 index 00000000..a173d39d --- /dev/null +++ b/toxcore/crypto_core_pack.c @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2024 The TokTok team. + * Copyright © 2013 Tox project. + */ + +#include "crypto_core_pack.h" + +#include + +#include "bin_pack.h" +#include "bin_unpack.h" +#include "ccompat.h" +#include "crypto_core.h" + +bool pack_extended_public_key(const Extended_Public_Key *key, Bin_Pack *bp) +{ + uint8_t ext_key[EXT_PUBLIC_KEY_SIZE]; + static_assert(sizeof(ext_key) == sizeof(key->enc) + sizeof(key->sig), + "extended secret key size is not the sum of the encryption and sign secret key sizes"); + memcpy(ext_key, key->enc, sizeof(key->enc)); + memcpy(&ext_key[sizeof(key->enc)], key->sig, sizeof(key->sig)); + + return bin_pack_bin(bp, ext_key, sizeof(ext_key)); +} + +bool pack_extended_secret_key(const Extended_Secret_Key *key, Bin_Pack *bp) +{ + uint8_t ext_key[EXT_SECRET_KEY_SIZE]; + static_assert(sizeof(ext_key) == sizeof(key->enc) + sizeof(key->sig), + "extended secret key size is not the sum of the encryption and sign secret key sizes"); + memcpy(ext_key, key->enc, sizeof(key->enc)); + memcpy(&ext_key[sizeof(key->enc)], key->sig, sizeof(key->sig)); + + const bool result = bin_pack_bin(bp, ext_key, sizeof(ext_key)); + crypto_memzero(ext_key, sizeof(ext_key)); + return result; +} + +bool unpack_extended_public_key(Extended_Public_Key *key, Bin_Unpack *bu) +{ + uint8_t ext_key[EXT_PUBLIC_KEY_SIZE]; + + if (!bin_unpack_bin_fixed(bu, ext_key, sizeof(ext_key))) { + return false; + } + + memcpy(key->enc, ext_key, sizeof(key->enc)); + memcpy(key->sig, &ext_key[sizeof(key->enc)], sizeof(key->sig)); + + return true; +} + +bool unpack_extended_secret_key(Extended_Secret_Key *key, Bin_Unpack *bu) +{ + uint8_t ext_key[EXT_SECRET_KEY_SIZE]; + + if (!bin_unpack_bin_fixed(bu, ext_key, sizeof(ext_key))) { + return false; + } + + memcpy(key->enc, ext_key, sizeof(key->enc)); + memcpy(key->sig, &ext_key[sizeof(key->enc)], sizeof(key->sig)); + crypto_memzero(ext_key, sizeof(ext_key)); + + return true; +} diff --git a/toxcore/crypto_core_pack.h b/toxcore/crypto_core_pack.h new file mode 100644 index 00000000..1efefff8 --- /dev/null +++ b/toxcore/crypto_core_pack.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2024 The TokTok team. + * Copyright © 2013 Tox project. + */ + +#ifndef C_TOXCORE_TOXCORE_CRYPTO_CORE_PACK_H +#define C_TOXCORE_TOXCORE_CRYPTO_CORE_PACK_H + +#include +#include +#include + +#include "attributes.h" +#include "bin_pack.h" +#include "bin_unpack.h" +#include "crypto_core.h" + +#ifdef __cplusplus +extern "C" { +#endif + +non_null() bool pack_extended_public_key(const Extended_Public_Key *key, Bin_Pack *bp); +non_null() bool pack_extended_secret_key(const Extended_Secret_Key *key, Bin_Pack *bp); +non_null() bool unpack_extended_public_key(Extended_Public_Key *key, Bin_Unpack *bu); +non_null() bool unpack_extended_secret_key(Extended_Secret_Key *key, Bin_Unpack *bu); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_CRYPTO_CORE_PACK_H */ diff --git a/toxcore/crypto_core_test.cc b/toxcore/crypto_core_test.cc index 19802275..d18ae2da 100644 --- a/toxcore/crypto_core_test.cc +++ b/toxcore/crypto_core_test.cc @@ -14,8 +14,6 @@ namespace { using HmacKey = std::array; using Hmac = std::array; using SecretKey = std::array; -using ExtPublicKey = std::array; -using ExtSecretKey = std::array; using Signature = std::array; using Nonce = std::array; @@ -72,10 +70,10 @@ TEST(CryptoCore, Signatures) { Test_Random rng; - ExtPublicKey pk; - ExtSecretKey sk; + Extended_Public_Key pk; + Extended_Secret_Key sk; - EXPECT_TRUE(create_extended_keypair(pk.data(), sk.data())); + EXPECT_TRUE(create_extended_keypair(&pk, &sk, rng)); std::vector message{0}; message.clear(); @@ -84,9 +82,9 @@ TEST(CryptoCore, Signatures) for (uint8_t i = 0; i < 100; ++i) { Signature signature; EXPECT_TRUE(crypto_signature_create( - signature.data(), message.data(), message.size(), get_sig_sk(sk.data()))); + signature.data(), message.data(), message.size(), get_sig_sk(&sk))); EXPECT_TRUE(crypto_signature_verify( - signature.data(), message.data(), message.size(), get_sig_pk(pk.data()))); + signature.data(), message.data(), message.size(), get_sig_pk(&pk))); message.push_back(random_u08(rng)); } diff --git a/toxcore/crypto_core_test_util.cc b/toxcore/crypto_core_test_util.cc index 4d5f46c5..b48871a5 100644 --- a/toxcore/crypto_core_test_util.cc +++ b/toxcore/crypto_core_test_util.cc @@ -3,6 +3,9 @@ #include #include +#include "crypto_core.h" +#include "test_util.hh" + Random_Funcs const Random_Class::vtable = { Method::invoke<&Random_Class::random_bytes>, Method::invoke<&Random_Class::random_uniform>, diff --git a/toxcore/events/conference_connected.c b/toxcore/events/conference_connected.c index 80834bf4..dbd9e4b5 100644 --- a/toxcore/events/conference_connected.c +++ b/toxcore/events/conference_connected.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -13,14 +14,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Conference_Connected { uint32_t conference_number; }; @@ -65,7 +64,6 @@ static bool tox_event_conference_connected_unpack_into( return bin_unpack_u32(bu, &event->conference_number); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -119,6 +117,7 @@ bool tox_event_conference_connected_unpack( Tox_Event_Conference_Connected **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_conference_connected_new(mem); if (*event == nullptr) { @@ -148,16 +147,15 @@ static Tox_Event_Conference_Connected *tox_event_conference_connected_alloc(void return conference_connected; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_conference_connected(Tox *tox, uint32_t conference_number, - void *user_data) +void tox_events_handle_conference_connected( + Tox *tox, uint32_t conference_number, + void *user_data) { Tox_Event_Conference_Connected *conference_connected = tox_event_conference_connected_alloc(user_data); diff --git a/toxcore/events/conference_invite.c b/toxcore/events/conference_invite.c index 30d9ff99..fb1f794b 100644 --- a/toxcore/events/conference_invite.c +++ b/toxcore/events/conference_invite.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -17,14 +18,12 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Conference_Invite { uint32_t friend_number; Tox_Conference_Type type; @@ -58,7 +57,7 @@ Tox_Conference_Type tox_event_conference_invite_get_type(const Tox_Event_Confere return conference_invite->type; } -non_null() +non_null(1) nullable(2) static bool tox_event_conference_invite_set_cookie(Tox_Event_Conference_Invite *conference_invite, const uint8_t *cookie, uint32_t cookie_length) { @@ -70,6 +69,11 @@ static bool tox_event_conference_invite_set_cookie(Tox_Event_Conference_Invite * conference_invite->cookie_length = 0; } + if (cookie == nullptr) { + assert(cookie_length == 0); + return true; + } + uint8_t *cookie_copy = (uint8_t *)malloc(cookie_length); if (cookie_copy == nullptr) { @@ -128,7 +132,6 @@ static bool tox_event_conference_invite_unpack_into( && bin_unpack_bin(bu, &event->cookie, &event->cookie_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -182,6 +185,7 @@ bool tox_event_conference_invite_unpack( Tox_Event_Conference_Invite **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_conference_invite_new(mem); if (*event == nullptr) { @@ -211,16 +215,15 @@ static Tox_Event_Conference_Invite *tox_event_conference_invite_alloc(void *user return conference_invite; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_conference_invite(Tox *tox, uint32_t friend_number, Tox_Conference_Type type, const uint8_t *cookie, size_t length, - void *user_data) +void tox_events_handle_conference_invite( + Tox *tox, uint32_t friend_number, Tox_Conference_Type type, const uint8_t *cookie, size_t length, + void *user_data) { Tox_Event_Conference_Invite *conference_invite = tox_event_conference_invite_alloc(user_data); diff --git a/toxcore/events/conference_message.c b/toxcore/events/conference_message.c index 818f555d..74e1123e 100644 --- a/toxcore/events/conference_message.c +++ b/toxcore/events/conference_message.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -17,14 +18,12 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Conference_Message { uint32_t conference_number; uint32_t peer_number; @@ -72,7 +71,7 @@ Tox_Message_Type tox_event_conference_message_get_type(const Tox_Event_Conferenc return conference_message->type; } -non_null() +non_null(1) nullable(2) static bool tox_event_conference_message_set_message(Tox_Event_Conference_Message *conference_message, const uint8_t *message, uint32_t message_length) { @@ -84,6 +83,11 @@ static bool tox_event_conference_message_set_message(Tox_Event_Conference_Messag conference_message->message_length = 0; } + if (message == nullptr) { + assert(message_length == 0); + return true; + } + uint8_t *message_copy = (uint8_t *)malloc(message_length); if (message_copy == nullptr) { @@ -144,7 +148,6 @@ static bool tox_event_conference_message_unpack_into( && bin_unpack_bin(bu, &event->message, &event->message_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -198,6 +201,7 @@ bool tox_event_conference_message_unpack( Tox_Event_Conference_Message **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_conference_message_new(mem); if (*event == nullptr) { @@ -227,16 +231,15 @@ static Tox_Event_Conference_Message *tox_event_conference_message_alloc(void *us return conference_message; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_conference_message(Tox *tox, uint32_t conference_number, uint32_t peer_number, Tox_Message_Type type, const uint8_t *message, size_t length, - void *user_data) +void tox_events_handle_conference_message( + Tox *tox, uint32_t conference_number, uint32_t peer_number, Tox_Message_Type type, const uint8_t *message, size_t length, + void *user_data) { Tox_Event_Conference_Message *conference_message = tox_event_conference_message_alloc(user_data); diff --git a/toxcore/events/conference_peer_list_changed.c b/toxcore/events/conference_peer_list_changed.c index 37b97568..050bfb08 100644 --- a/toxcore/events/conference_peer_list_changed.c +++ b/toxcore/events/conference_peer_list_changed.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -13,14 +14,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Conference_Peer_List_Changed { uint32_t conference_number; }; @@ -65,7 +64,6 @@ static bool tox_event_conference_peer_list_changed_unpack_into( return bin_unpack_u32(bu, &event->conference_number); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -119,6 +117,7 @@ bool tox_event_conference_peer_list_changed_unpack( Tox_Event_Conference_Peer_List_Changed **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_conference_peer_list_changed_new(mem); if (*event == nullptr) { @@ -148,16 +147,15 @@ static Tox_Event_Conference_Peer_List_Changed *tox_event_conference_peer_list_ch return conference_peer_list_changed; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_conference_peer_list_changed(Tox *tox, uint32_t conference_number, - void *user_data) +void tox_events_handle_conference_peer_list_changed( + Tox *tox, uint32_t conference_number, + void *user_data) { Tox_Event_Conference_Peer_List_Changed *conference_peer_list_changed = tox_event_conference_peer_list_changed_alloc(user_data); diff --git a/toxcore/events/conference_peer_name.c b/toxcore/events/conference_peer_name.c index 27cba5ac..fc6c2557 100644 --- a/toxcore/events/conference_peer_name.c +++ b/toxcore/events/conference_peer_name.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Conference_Peer_Name { uint32_t conference_number; uint32_t peer_number; @@ -56,7 +55,7 @@ uint32_t tox_event_conference_peer_name_get_peer_number(const Tox_Event_Conferen return conference_peer_name->peer_number; } -non_null() +non_null(1) nullable(2) static bool tox_event_conference_peer_name_set_name(Tox_Event_Conference_Peer_Name *conference_peer_name, const uint8_t *name, uint32_t name_length) { @@ -68,6 +67,11 @@ static bool tox_event_conference_peer_name_set_name(Tox_Event_Conference_Peer_Na conference_peer_name->name_length = 0; } + if (name == nullptr) { + assert(name_length == 0); + return true; + } + uint8_t *name_copy = (uint8_t *)malloc(name_length); if (name_copy == nullptr) { @@ -126,7 +130,6 @@ static bool tox_event_conference_peer_name_unpack_into( && bin_unpack_bin(bu, &event->name, &event->name_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -180,6 +183,7 @@ bool tox_event_conference_peer_name_unpack( Tox_Event_Conference_Peer_Name **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_conference_peer_name_new(mem); if (*event == nullptr) { @@ -209,16 +213,15 @@ static Tox_Event_Conference_Peer_Name *tox_event_conference_peer_name_alloc(void return conference_peer_name; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_conference_peer_name(Tox *tox, uint32_t conference_number, uint32_t peer_number, const uint8_t *name, size_t length, - void *user_data) +void tox_events_handle_conference_peer_name( + Tox *tox, uint32_t conference_number, uint32_t peer_number, const uint8_t *name, size_t length, + void *user_data) { Tox_Event_Conference_Peer_Name *conference_peer_name = tox_event_conference_peer_name_alloc(user_data); diff --git a/toxcore/events/conference_title.c b/toxcore/events/conference_title.c index 1a00e644..d761f512 100644 --- a/toxcore/events/conference_title.c +++ b/toxcore/events/conference_title.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Conference_Title { uint32_t conference_number; uint32_t peer_number; @@ -56,7 +55,7 @@ uint32_t tox_event_conference_title_get_peer_number(const Tox_Event_Conference_T return conference_title->peer_number; } -non_null() +non_null(1) nullable(2) static bool tox_event_conference_title_set_title(Tox_Event_Conference_Title *conference_title, const uint8_t *title, uint32_t title_length) { @@ -68,6 +67,11 @@ static bool tox_event_conference_title_set_title(Tox_Event_Conference_Title *con conference_title->title_length = 0; } + if (title == nullptr) { + assert(title_length == 0); + return true; + } + uint8_t *title_copy = (uint8_t *)malloc(title_length); if (title_copy == nullptr) { @@ -126,7 +130,6 @@ static bool tox_event_conference_title_unpack_into( && bin_unpack_bin(bu, &event->title, &event->title_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -180,6 +183,7 @@ bool tox_event_conference_title_unpack( Tox_Event_Conference_Title **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_conference_title_new(mem); if (*event == nullptr) { @@ -209,16 +213,15 @@ static Tox_Event_Conference_Title *tox_event_conference_title_alloc(void *user_d return conference_title; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_conference_title(Tox *tox, uint32_t conference_number, uint32_t peer_number, const uint8_t *title, size_t length, - void *user_data) +void tox_events_handle_conference_title( + Tox *tox, uint32_t conference_number, uint32_t peer_number, const uint8_t *title, size_t length, + void *user_data) { Tox_Event_Conference_Title *conference_title = tox_event_conference_title_alloc(user_data); diff --git a/toxcore/events/dht_get_nodes_response.c b/toxcore/events/dht_get_nodes_response.c new file mode 100644 index 00000000..6e03b73e --- /dev/null +++ b/toxcore/events/dht_get_nodes_response.c @@ -0,0 +1,223 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022 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_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; + + tox_events_add(events, &event); + 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/events_alloc.c b/toxcore/events/events_alloc.c index 271dfc00..24eebb31 100644 --- a/toxcore/events/events_alloc.c +++ b/toxcore/events/events_alloc.c @@ -63,7 +63,7 @@ bool tox_events_add(Tox_Events *events, const Tox_Event *event) if (events->events_size == events->events_capacity) { const uint32_t new_events_capacity = events->events_capacity * 2 + 1; Tox_Event *new_events = (Tox_Event *)mem_vrealloc( - events->mem, events->events, new_events_capacity, sizeof(Tox_Event)); + events->mem, events->events, new_events_capacity, sizeof(Tox_Event)); if (new_events == nullptr) { return false; diff --git a/toxcore/events/events_alloc.h b/toxcore/events/events_alloc.h index 11ac6c99..a40db970 100644 --- a/toxcore/events/events_alloc.h +++ b/toxcore/events/events_alloc.h @@ -8,7 +8,11 @@ #include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" +#include "../mem.h" +#include "../tox.h" #include "../tox_event.h" +#include "../tox_events.h" +#include "../tox_private.h" #ifdef __cplusplus extern "C" { @@ -34,6 +38,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_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; @@ -68,12 +73,6 @@ tox_group_self_join_cb tox_events_handle_group_self_join; tox_group_join_fail_cb tox_events_handle_group_join_fail; tox_group_moderation_cb tox_events_handle_group_moderation; -non_null(2) nullable(1) -bool tox_events_pack(const Tox_Events *events, Bin_Pack *bp); - -non_null() -bool tox_events_unpack(Tox_Events *events, Bin_Unpack *bu, const Memory *mem); - non_null() Tox_Events_State *tox_events_alloc(void *user_data); @@ -81,7 +80,7 @@ non_null() bool tox_events_add(Tox_Events *events, const Tox_Event *event); #ifdef __cplusplus -} +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_EVENTS_EVENTS_ALLOC_H +#endif /* C_TOXCORE_TOXCORE_EVENTS_EVENTS_ALLOC_H */ diff --git a/toxcore/events/file_chunk_request.c b/toxcore/events/file_chunk_request.c index a83bbd49..4117ef3c 100644 --- a/toxcore/events/file_chunk_request.c +++ b/toxcore/events/file_chunk_request.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -13,14 +14,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_File_Chunk_Request { uint32_t friend_number; uint32_t file_number; @@ -118,7 +117,6 @@ static bool tox_event_file_chunk_request_unpack_into( && bin_unpack_u16(bu, &event->length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -172,6 +170,7 @@ bool tox_event_file_chunk_request_unpack( Tox_Event_File_Chunk_Request **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_file_chunk_request_new(mem); if (*event == nullptr) { @@ -201,16 +200,15 @@ static Tox_Event_File_Chunk_Request *tox_event_file_chunk_request_alloc(void *us return file_chunk_request; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, size_t length, - void *user_data) +void tox_events_handle_file_chunk_request( + Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, size_t length, + void *user_data) { Tox_Event_File_Chunk_Request *file_chunk_request = tox_event_file_chunk_request_alloc(user_data); diff --git a/toxcore/events/file_recv.c b/toxcore/events/file_recv.c index a870857c..45cec44b 100644 --- a/toxcore/events/file_recv.c +++ b/toxcore/events/file_recv.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_File_Recv { uint32_t friend_number; uint32_t file_number; @@ -84,7 +83,7 @@ uint64_t tox_event_file_recv_get_file_size(const Tox_Event_File_Recv *file_recv) return file_recv->file_size; } -non_null() +non_null(1) nullable(2) static bool tox_event_file_recv_set_filename(Tox_Event_File_Recv *file_recv, const uint8_t *filename, uint32_t filename_length) { @@ -96,6 +95,11 @@ static bool tox_event_file_recv_set_filename(Tox_Event_File_Recv *file_recv, file_recv->filename_length = 0; } + if (filename == nullptr) { + assert(filename_length == 0); + return true; + } + uint8_t *filename_copy = (uint8_t *)malloc(filename_length); if (filename_copy == nullptr) { @@ -158,7 +162,6 @@ static bool tox_event_file_recv_unpack_into( && bin_unpack_bin(bu, &event->filename, &event->filename_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -212,6 +215,7 @@ bool tox_event_file_recv_unpack( Tox_Event_File_Recv **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_file_recv_new(mem); if (*event == nullptr) { @@ -241,16 +245,15 @@ static Tox_Event_File_Recv *tox_event_file_recv_alloc(void *user_data) return file_recv; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_file_recv(Tox *tox, uint32_t friend_number, uint32_t file_number, uint32_t kind, uint64_t file_size, const uint8_t *filename, size_t filename_length, - void *user_data) +void tox_events_handle_file_recv( + Tox *tox, uint32_t friend_number, uint32_t file_number, uint32_t kind, uint64_t file_size, const uint8_t *filename, size_t filename_length, + void *user_data) { Tox_Event_File_Recv *file_recv = tox_event_file_recv_alloc(user_data); diff --git a/toxcore/events/file_recv_chunk.c b/toxcore/events/file_recv_chunk.c index 95731259..2edf7c5a 100644 --- a/toxcore/events/file_recv_chunk.c +++ b/toxcore/events/file_recv_chunk.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_File_Recv_Chunk { uint32_t friend_number; uint32_t file_number; @@ -70,7 +69,7 @@ uint64_t tox_event_file_recv_chunk_get_position(const Tox_Event_File_Recv_Chunk return file_recv_chunk->position; } -non_null() +non_null(1) nullable(2) static bool tox_event_file_recv_chunk_set_data(Tox_Event_File_Recv_Chunk *file_recv_chunk, const uint8_t *data, uint32_t data_length) { @@ -82,6 +81,11 @@ static bool tox_event_file_recv_chunk_set_data(Tox_Event_File_Recv_Chunk *file_r file_recv_chunk->data_length = 0; } + if (data == nullptr) { + assert(data_length == 0); + return true; + } + uint8_t *data_copy = (uint8_t *)malloc(data_length); if (data_copy == nullptr) { @@ -142,7 +146,6 @@ static bool tox_event_file_recv_chunk_unpack_into( && bin_unpack_bin(bu, &event->data, &event->data_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -196,6 +199,7 @@ bool tox_event_file_recv_chunk_unpack( Tox_Event_File_Recv_Chunk **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_file_recv_chunk_new(mem); if (*event == nullptr) { @@ -225,16 +229,15 @@ static Tox_Event_File_Recv_Chunk *tox_event_file_recv_chunk_alloc(void *user_dat return file_recv_chunk; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_file_recv_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t *data, size_t length, - void *user_data) +void tox_events_handle_file_recv_chunk( + Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t *data, size_t length, + void *user_data) { Tox_Event_File_Recv_Chunk *file_recv_chunk = tox_event_file_recv_chunk_alloc(user_data); diff --git a/toxcore/events/file_recv_control.c b/toxcore/events/file_recv_control.c index 0fc26ae3..14a34aaf 100644 --- a/toxcore/events/file_recv_control.c +++ b/toxcore/events/file_recv_control.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_File_Recv_Control { uint32_t friend_number; uint32_t file_number; @@ -104,7 +103,6 @@ static bool tox_event_file_recv_control_unpack_into( && tox_file_control_unpack(&event->control, bu); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -158,6 +156,7 @@ bool tox_event_file_recv_control_unpack( Tox_Event_File_Recv_Control **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_file_recv_control_new(mem); if (*event == nullptr) { @@ -187,16 +186,15 @@ static Tox_Event_File_Recv_Control *tox_event_file_recv_control_alloc(void *user return file_recv_control; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_file_recv_control(Tox *tox, uint32_t friend_number, uint32_t file_number, Tox_File_Control control, - void *user_data) +void tox_events_handle_file_recv_control( + Tox *tox, uint32_t friend_number, uint32_t file_number, Tox_File_Control control, + void *user_data) { Tox_Event_File_Recv_Control *file_recv_control = tox_event_file_recv_control_alloc(user_data); diff --git a/toxcore/events/friend_connection_status.c b/toxcore/events/friend_connection_status.c index 4e158e0b..330554b0 100644 --- a/toxcore/events/friend_connection_status.c +++ b/toxcore/events/friend_connection_status.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Friend_Connection_Status { uint32_t friend_number; Tox_Connection connection_status; @@ -88,7 +87,6 @@ static bool tox_event_friend_connection_status_unpack_into( && tox_connection_unpack(&event->connection_status, bu); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -142,6 +140,7 @@ bool tox_event_friend_connection_status_unpack( Tox_Event_Friend_Connection_Status **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_friend_connection_status_new(mem); if (*event == nullptr) { @@ -171,16 +170,15 @@ static Tox_Event_Friend_Connection_Status *tox_event_friend_connection_status_al return friend_connection_status; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_friend_connection_status(Tox *tox, uint32_t friend_number, Tox_Connection connection_status, - void *user_data) +void tox_events_handle_friend_connection_status( + Tox *tox, uint32_t friend_number, Tox_Connection connection_status, + void *user_data) { Tox_Event_Friend_Connection_Status *friend_connection_status = tox_event_friend_connection_status_alloc(user_data); diff --git a/toxcore/events/friend_lossless_packet.c b/toxcore/events/friend_lossless_packet.c index a21af28c..17e8fad9 100644 --- a/toxcore/events/friend_lossless_packet.c +++ b/toxcore/events/friend_lossless_packet.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Friend_Lossless_Packet { uint32_t friend_number; uint8_t *data; @@ -42,7 +41,7 @@ uint32_t tox_event_friend_lossless_packet_get_friend_number(const Tox_Event_Frie return friend_lossless_packet->friend_number; } -non_null() +non_null(1) nullable(2) static bool tox_event_friend_lossless_packet_set_data(Tox_Event_Friend_Lossless_Packet *friend_lossless_packet, const uint8_t *data, uint32_t data_length) { @@ -54,6 +53,11 @@ static bool tox_event_friend_lossless_packet_set_data(Tox_Event_Friend_Lossless_ friend_lossless_packet->data_length = 0; } + if (data == nullptr) { + assert(data_length == 0); + return true; + } + uint8_t *data_copy = (uint8_t *)malloc(data_length); if (data_copy == nullptr) { @@ -110,7 +114,6 @@ static bool tox_event_friend_lossless_packet_unpack_into( && bin_unpack_bin(bu, &event->data, &event->data_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -164,6 +167,7 @@ bool tox_event_friend_lossless_packet_unpack( Tox_Event_Friend_Lossless_Packet **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_friend_lossless_packet_new(mem); if (*event == nullptr) { @@ -193,16 +197,15 @@ static Tox_Event_Friend_Lossless_Packet *tox_event_friend_lossless_packet_alloc( return friend_lossless_packet; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_friend_lossless_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, - void *user_data) +void tox_events_handle_friend_lossless_packet( + Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, + void *user_data) { Tox_Event_Friend_Lossless_Packet *friend_lossless_packet = tox_event_friend_lossless_packet_alloc(user_data); diff --git a/toxcore/events/friend_lossy_packet.c b/toxcore/events/friend_lossy_packet.c index efbf203b..6b2e9ed2 100644 --- a/toxcore/events/friend_lossy_packet.c +++ b/toxcore/events/friend_lossy_packet.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Friend_Lossy_Packet { uint32_t friend_number; uint8_t *data; @@ -42,7 +41,7 @@ uint32_t tox_event_friend_lossy_packet_get_friend_number(const Tox_Event_Friend_ return friend_lossy_packet->friend_number; } -non_null() +non_null(1) nullable(2) static bool tox_event_friend_lossy_packet_set_data(Tox_Event_Friend_Lossy_Packet *friend_lossy_packet, const uint8_t *data, uint32_t data_length) { @@ -54,6 +53,11 @@ static bool tox_event_friend_lossy_packet_set_data(Tox_Event_Friend_Lossy_Packet friend_lossy_packet->data_length = 0; } + if (data == nullptr) { + assert(data_length == 0); + return true; + } + uint8_t *data_copy = (uint8_t *)malloc(data_length); if (data_copy == nullptr) { @@ -110,7 +114,6 @@ static bool tox_event_friend_lossy_packet_unpack_into( && bin_unpack_bin(bu, &event->data, &event->data_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -164,6 +167,7 @@ bool tox_event_friend_lossy_packet_unpack( Tox_Event_Friend_Lossy_Packet **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_friend_lossy_packet_new(mem); if (*event == nullptr) { @@ -193,16 +197,15 @@ static Tox_Event_Friend_Lossy_Packet *tox_event_friend_lossy_packet_alloc(void * return friend_lossy_packet; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_friend_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, - void *user_data) +void tox_events_handle_friend_lossy_packet( + Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, + void *user_data) { Tox_Event_Friend_Lossy_Packet *friend_lossy_packet = tox_event_friend_lossy_packet_alloc(user_data); diff --git a/toxcore/events/friend_message.c b/toxcore/events/friend_message.c index ef917acb..befcc74a 100644 --- a/toxcore/events/friend_message.c +++ b/toxcore/events/friend_message.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -17,14 +18,12 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Friend_Message { uint32_t friend_number; Tox_Message_Type type; @@ -58,7 +57,7 @@ Tox_Message_Type tox_event_friend_message_get_type(const Tox_Event_Friend_Messag return friend_message->type; } -non_null() +non_null(1) nullable(2) static bool tox_event_friend_message_set_message(Tox_Event_Friend_Message *friend_message, const uint8_t *message, uint32_t message_length) { @@ -70,6 +69,11 @@ static bool tox_event_friend_message_set_message(Tox_Event_Friend_Message *frien friend_message->message_length = 0; } + if (message == nullptr) { + assert(message_length == 0); + return true; + } + uint8_t *message_copy = (uint8_t *)malloc(message_length); if (message_copy == nullptr) { @@ -128,7 +132,6 @@ static bool tox_event_friend_message_unpack_into( && bin_unpack_bin(bu, &event->message, &event->message_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -182,6 +185,7 @@ bool tox_event_friend_message_unpack( Tox_Event_Friend_Message **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_friend_message_new(mem); if (*event == nullptr) { @@ -211,16 +215,15 @@ static Tox_Event_Friend_Message *tox_event_friend_message_alloc(void *user_data) return friend_message; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_friend_message(Tox *tox, uint32_t friend_number, Tox_Message_Type type, const uint8_t *message, size_t length, - void *user_data) +void tox_events_handle_friend_message( + Tox *tox, uint32_t friend_number, Tox_Message_Type type, const uint8_t *message, size_t length, + void *user_data) { Tox_Event_Friend_Message *friend_message = tox_event_friend_message_alloc(user_data); diff --git a/toxcore/events/friend_name.c b/toxcore/events/friend_name.c index d371e657..dfa9b396 100644 --- a/toxcore/events/friend_name.c +++ b/toxcore/events/friend_name.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Friend_Name { uint32_t friend_number; uint8_t *name; @@ -42,7 +41,7 @@ uint32_t tox_event_friend_name_get_friend_number(const Tox_Event_Friend_Name *fr return friend_name->friend_number; } -non_null() +non_null(1) nullable(2) static bool tox_event_friend_name_set_name(Tox_Event_Friend_Name *friend_name, const uint8_t *name, uint32_t name_length) { @@ -54,6 +53,11 @@ static bool tox_event_friend_name_set_name(Tox_Event_Friend_Name *friend_name, friend_name->name_length = 0; } + if (name == nullptr) { + assert(name_length == 0); + return true; + } + uint8_t *name_copy = (uint8_t *)malloc(name_length); if (name_copy == nullptr) { @@ -110,7 +114,6 @@ static bool tox_event_friend_name_unpack_into( && bin_unpack_bin(bu, &event->name, &event->name_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -164,6 +167,7 @@ bool tox_event_friend_name_unpack( Tox_Event_Friend_Name **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_friend_name_new(mem); if (*event == nullptr) { @@ -193,16 +197,15 @@ static Tox_Event_Friend_Name *tox_event_friend_name_alloc(void *user_data) return friend_name; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_friend_name(Tox *tox, uint32_t friend_number, const uint8_t *name, size_t length, - void *user_data) +void tox_events_handle_friend_name( + Tox *tox, uint32_t friend_number, const uint8_t *name, size_t length, + void *user_data) { Tox_Event_Friend_Name *friend_name = tox_event_friend_name_alloc(user_data); diff --git a/toxcore/events/friend_read_receipt.c b/toxcore/events/friend_read_receipt.c index f52fc37a..e5f2f9db 100644 --- a/toxcore/events/friend_read_receipt.c +++ b/toxcore/events/friend_read_receipt.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -13,14 +14,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Friend_Read_Receipt { uint32_t friend_number; uint32_t message_id; @@ -86,7 +85,6 @@ static bool tox_event_friend_read_receipt_unpack_into( && bin_unpack_u32(bu, &event->message_id); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -140,6 +138,7 @@ bool tox_event_friend_read_receipt_unpack( Tox_Event_Friend_Read_Receipt **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_friend_read_receipt_new(mem); if (*event == nullptr) { @@ -169,16 +168,15 @@ static Tox_Event_Friend_Read_Receipt *tox_event_friend_read_receipt_alloc(void * return friend_read_receipt; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_friend_read_receipt(Tox *tox, uint32_t friend_number, uint32_t message_id, - void *user_data) +void tox_events_handle_friend_read_receipt( + Tox *tox, uint32_t friend_number, uint32_t message_id, + void *user_data) { Tox_Event_Friend_Read_Receipt *friend_read_receipt = tox_event_friend_read_receipt_alloc(user_data); diff --git a/toxcore/events/friend_request.c b/toxcore/events/friend_request.c index 70f468cb..b492c151 100644 --- a/toxcore/events/friend_request.c +++ b/toxcore/events/friend_request.c @@ -7,6 +7,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox_events.h" #include "../tox_private.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Friend_Request { uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; uint8_t *message; @@ -81,7 +80,9 @@ non_null() static void tox_event_friend_request_construct(Tox_Event_Friend_Request *friend_request) { *friend_request = (Tox_Event_Friend_Request) { - 0 + { + 0 + } }; } non_null() @@ -159,6 +160,7 @@ bool tox_event_friend_request_unpack( Tox_Event_Friend_Request **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_friend_request_new(mem); if (*event == nullptr) { @@ -188,14 +190,12 @@ static Tox_Event_Friend_Request *tox_event_friend_request_alloc(void *user_data) return friend_request; } - /***************************************************** * * :: event handler * *****************************************************/ - void tox_events_handle_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *message, size_t length, void *user_data) { diff --git a/toxcore/events/friend_status.c b/toxcore/events/friend_status.c index 55e60657..3d749972 100644 --- a/toxcore/events/friend_status.c +++ b/toxcore/events/friend_status.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Friend_Status { uint32_t friend_number; Tox_User_Status status; @@ -88,7 +87,6 @@ static bool tox_event_friend_status_unpack_into( && tox_user_status_unpack(&event->status, bu); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -142,6 +140,7 @@ bool tox_event_friend_status_unpack( Tox_Event_Friend_Status **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_friend_status_new(mem); if (*event == nullptr) { @@ -171,16 +170,15 @@ static Tox_Event_Friend_Status *tox_event_friend_status_alloc(void *user_data) return friend_status; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_friend_status(Tox *tox, uint32_t friend_number, Tox_User_Status status, - void *user_data) +void tox_events_handle_friend_status( + Tox *tox, uint32_t friend_number, Tox_User_Status status, + void *user_data) { Tox_Event_Friend_Status *friend_status = tox_event_friend_status_alloc(user_data); diff --git a/toxcore/events/friend_status_message.c b/toxcore/events/friend_status_message.c index 400f7ff8..ad051991 100644 --- a/toxcore/events/friend_status_message.c +++ b/toxcore/events/friend_status_message.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Friend_Status_Message { uint32_t friend_number; uint8_t *message; @@ -42,7 +41,7 @@ uint32_t tox_event_friend_status_message_get_friend_number(const Tox_Event_Frien return friend_status_message->friend_number; } -non_null() +non_null(1) nullable(2) static bool tox_event_friend_status_message_set_message(Tox_Event_Friend_Status_Message *friend_status_message, const uint8_t *message, uint32_t message_length) { @@ -54,6 +53,11 @@ static bool tox_event_friend_status_message_set_message(Tox_Event_Friend_Status_ friend_status_message->message_length = 0; } + if (message == nullptr) { + assert(message_length == 0); + return true; + } + uint8_t *message_copy = (uint8_t *)malloc(message_length); if (message_copy == nullptr) { @@ -110,7 +114,6 @@ static bool tox_event_friend_status_message_unpack_into( && bin_unpack_bin(bu, &event->message, &event->message_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -164,6 +167,7 @@ bool tox_event_friend_status_message_unpack( Tox_Event_Friend_Status_Message **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_friend_status_message_new(mem); if (*event == nullptr) { @@ -193,16 +197,15 @@ static Tox_Event_Friend_Status_Message *tox_event_friend_status_message_alloc(vo return friend_status_message; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_friend_status_message(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length, - void *user_data) +void tox_events_handle_friend_status_message( + Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length, + void *user_data) { Tox_Event_Friend_Status_Message *friend_status_message = tox_event_friend_status_message_alloc(user_data); diff --git a/toxcore/events/friend_typing.c b/toxcore/events/friend_typing.c index 9b099974..692b07fb 100644 --- a/toxcore/events/friend_typing.c +++ b/toxcore/events/friend_typing.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -13,14 +14,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Friend_Typing { uint32_t friend_number; bool typing; @@ -86,7 +85,6 @@ static bool tox_event_friend_typing_unpack_into( && bin_unpack_bool(bu, &event->typing); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -140,6 +138,7 @@ bool tox_event_friend_typing_unpack( Tox_Event_Friend_Typing **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_friend_typing_new(mem); if (*event == nullptr) { @@ -169,16 +168,15 @@ static Tox_Event_Friend_Typing *tox_event_friend_typing_alloc(void *user_data) return friend_typing; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_friend_typing(Tox *tox, uint32_t friend_number, bool typing, - void *user_data) +void tox_events_handle_friend_typing( + Tox *tox, uint32_t friend_number, bool typing, + void *user_data) { Tox_Event_Friend_Typing *friend_typing = tox_event_friend_typing_alloc(user_data); diff --git a/toxcore/events/group_custom_packet.c b/toxcore/events/group_custom_packet.c index acc8a391..a82e2c3a 100644 --- a/toxcore/events/group_custom_packet.c +++ b/toxcore/events/group_custom_packet.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Custom_Packet { uint32_t group_number; uint32_t peer_id; @@ -56,7 +55,7 @@ uint32_t tox_event_group_custom_packet_get_peer_id(const Tox_Event_Group_Custom_ return group_custom_packet->peer_id; } -non_null() +non_null(1) nullable(2) static bool tox_event_group_custom_packet_set_data(Tox_Event_Group_Custom_Packet *group_custom_packet, const uint8_t *data, uint32_t data_length) { @@ -68,6 +67,11 @@ static bool tox_event_group_custom_packet_set_data(Tox_Event_Group_Custom_Packet group_custom_packet->data_length = 0; } + if (data == nullptr) { + assert(data_length == 0); + return true; + } + uint8_t *data_copy = (uint8_t *)malloc(data_length); if (data_copy == nullptr) { @@ -126,7 +130,6 @@ static bool tox_event_group_custom_packet_unpack_into( && bin_unpack_bin(bu, &event->data, &event->data_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -180,6 +183,7 @@ bool tox_event_group_custom_packet_unpack( Tox_Event_Group_Custom_Packet **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_custom_packet_new(mem); if (*event == nullptr) { @@ -209,16 +213,15 @@ static Tox_Event_Group_Custom_Packet *tox_event_group_custom_packet_alloc(void * return group_custom_packet; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_custom_packet(Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *data, size_t length, - void *user_data) +void tox_events_handle_group_custom_packet( + Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *data, size_t length, + void *user_data) { Tox_Event_Group_Custom_Packet *group_custom_packet = tox_event_group_custom_packet_alloc(user_data); diff --git a/toxcore/events/group_custom_private_packet.c b/toxcore/events/group_custom_private_packet.c index 65d95a6f..56282f0f 100644 --- a/toxcore/events/group_custom_private_packet.c +++ b/toxcore/events/group_custom_private_packet.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Custom_Private_Packet { uint32_t group_number; uint32_t peer_id; @@ -56,7 +55,7 @@ uint32_t tox_event_group_custom_private_packet_get_peer_id(const Tox_Event_Group return group_custom_private_packet->peer_id; } -non_null() +non_null(1) nullable(2) static bool tox_event_group_custom_private_packet_set_data(Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet, const uint8_t *data, uint32_t data_length) { @@ -68,6 +67,11 @@ static bool tox_event_group_custom_private_packet_set_data(Tox_Event_Group_Custo group_custom_private_packet->data_length = 0; } + if (data == nullptr) { + assert(data_length == 0); + return true; + } + uint8_t *data_copy = (uint8_t *)malloc(data_length); if (data_copy == nullptr) { @@ -126,7 +130,6 @@ static bool tox_event_group_custom_private_packet_unpack_into( && bin_unpack_bin(bu, &event->data, &event->data_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -180,6 +183,7 @@ bool tox_event_group_custom_private_packet_unpack( Tox_Event_Group_Custom_Private_Packet **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_custom_private_packet_new(mem); if (*event == nullptr) { @@ -209,16 +213,15 @@ static Tox_Event_Group_Custom_Private_Packet *tox_event_group_custom_private_pac return group_custom_private_packet; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_custom_private_packet(Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *data, size_t length, - void *user_data) +void tox_events_handle_group_custom_private_packet( + Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *data, size_t length, + void *user_data) { Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet = tox_event_group_custom_private_packet_alloc(user_data); diff --git a/toxcore/events/group_invite.c b/toxcore/events/group_invite.c index 30e3429a..0691dcd1 100644 --- a/toxcore/events/group_invite.c +++ b/toxcore/events/group_invite.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Invite { uint32_t friend_number; uint8_t *invite_data; @@ -44,7 +43,7 @@ uint32_t tox_event_group_invite_get_friend_number(const Tox_Event_Group_Invite * return group_invite->friend_number; } -non_null() +non_null(1) nullable(2) static bool tox_event_group_invite_set_invite_data(Tox_Event_Group_Invite *group_invite, const uint8_t *invite_data, uint32_t invite_data_length) { @@ -56,6 +55,11 @@ static bool tox_event_group_invite_set_invite_data(Tox_Event_Group_Invite *group group_invite->invite_data_length = 0; } + if (invite_data == nullptr) { + assert(invite_data_length == 0); + return true; + } + uint8_t *invite_data_copy = (uint8_t *)malloc(invite_data_length); if (invite_data_copy == nullptr) { @@ -78,7 +82,7 @@ const uint8_t *tox_event_group_invite_get_invite_data(const Tox_Event_Group_Invi return group_invite->invite_data; } -non_null() +non_null(1) nullable(2) static bool tox_event_group_invite_set_group_name(Tox_Event_Group_Invite *group_invite, const uint8_t *group_name, uint32_t group_name_length) { @@ -90,6 +94,11 @@ static bool tox_event_group_invite_set_group_name(Tox_Event_Group_Invite *group_ group_invite->group_name_length = 0; } + if (group_name == nullptr) { + assert(group_name_length == 0); + return true; + } + uint8_t *group_name_copy = (uint8_t *)malloc(group_name_length); if (group_name_copy == nullptr) { @@ -149,7 +158,6 @@ static bool tox_event_group_invite_unpack_into( && bin_unpack_bin(bu, &event->group_name, &event->group_name_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -203,6 +211,7 @@ bool tox_event_group_invite_unpack( Tox_Event_Group_Invite **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_invite_new(mem); if (*event == nullptr) { @@ -232,16 +241,15 @@ static Tox_Event_Group_Invite *tox_event_group_invite_alloc(void *user_data) return group_invite; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_invite(Tox *tox, uint32_t friend_number, const uint8_t *invite_data, size_t length, const uint8_t *group_name, size_t group_name_length, - void *user_data) +void tox_events_handle_group_invite( + Tox *tox, uint32_t friend_number, const uint8_t *invite_data, size_t length, const uint8_t *group_name, size_t group_name_length, + void *user_data) { Tox_Event_Group_Invite *group_invite = tox_event_group_invite_alloc(user_data); diff --git a/toxcore/events/group_join_fail.c b/toxcore/events/group_join_fail.c index 88565680..b8589685 100644 --- a/toxcore/events/group_join_fail.c +++ b/toxcore/events/group_join_fail.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Join_Fail { uint32_t group_number; Tox_Group_Join_Fail fail_type; @@ -88,7 +87,6 @@ static bool tox_event_group_join_fail_unpack_into( && tox_group_join_fail_unpack(&event->fail_type, bu); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -142,6 +140,7 @@ bool tox_event_group_join_fail_unpack( Tox_Event_Group_Join_Fail **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_join_fail_new(mem); if (*event == nullptr) { @@ -171,16 +170,15 @@ static Tox_Event_Group_Join_Fail *tox_event_group_join_fail_alloc(void *user_dat return group_join_fail; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_join_fail(Tox *tox, uint32_t group_number, Tox_Group_Join_Fail fail_type, - void *user_data) +void tox_events_handle_group_join_fail( + Tox *tox, uint32_t group_number, Tox_Group_Join_Fail fail_type, + void *user_data) { Tox_Event_Group_Join_Fail *group_join_fail = tox_event_group_join_fail_alloc(user_data); diff --git a/toxcore/events/group_message.c b/toxcore/events/group_message.c index 2bdad4ec..a200f845 100644 --- a/toxcore/events/group_message.c +++ b/toxcore/events/group_message.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -17,14 +18,12 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Message { uint32_t group_number; uint32_t peer_id; @@ -73,7 +72,7 @@ Tox_Message_Type tox_event_group_message_get_type(const Tox_Event_Group_Message return group_message->type; } -non_null() +non_null(1) nullable(2) static bool tox_event_group_message_set_message(Tox_Event_Group_Message *group_message, const uint8_t *message, uint32_t message_length) { @@ -85,6 +84,11 @@ static bool tox_event_group_message_set_message(Tox_Event_Group_Message *group_m group_message->message_length = 0; } + if (message == nullptr) { + assert(message_length == 0); + return true; + } + uint8_t *message_copy = (uint8_t *)malloc(message_length); if (message_copy == nullptr) { @@ -160,7 +164,6 @@ static bool tox_event_group_message_unpack_into( && bin_unpack_u32(bu, &event->message_id); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -214,6 +217,7 @@ bool tox_event_group_message_unpack( Tox_Event_Group_Message **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_message_new(mem); if (*event == nullptr) { @@ -243,16 +247,15 @@ static Tox_Event_Group_Message *tox_event_group_message_alloc(void *user_data) return group_message; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_message(Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Message_Type type, const uint8_t *message, size_t length, uint32_t message_id, - void *user_data) +void tox_events_handle_group_message( + Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Message_Type type, const uint8_t *message, size_t length, uint32_t message_id, + void *user_data) { Tox_Event_Group_Message *group_message = tox_event_group_message_alloc(user_data); diff --git a/toxcore/events/group_moderation.c b/toxcore/events/group_moderation.c index 7ac46ffc..ba510d5b 100644 --- a/toxcore/events/group_moderation.c +++ b/toxcore/events/group_moderation.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Moderation { uint32_t group_number; uint32_t source_peer_id; @@ -120,7 +119,6 @@ static bool tox_event_group_moderation_unpack_into( && tox_group_mod_event_unpack(&event->mod_type, bu); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -174,6 +172,7 @@ bool tox_event_group_moderation_unpack( Tox_Event_Group_Moderation **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_moderation_new(mem); if (*event == nullptr) { @@ -203,16 +202,15 @@ static Tox_Event_Group_Moderation *tox_event_group_moderation_alloc(void *user_d return group_moderation; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_moderation(Tox *tox, uint32_t group_number, uint32_t source_peer_id, uint32_t target_peer_id, Tox_Group_Mod_Event mod_type, - void *user_data) +void tox_events_handle_group_moderation( + Tox *tox, uint32_t group_number, uint32_t source_peer_id, uint32_t target_peer_id, Tox_Group_Mod_Event mod_type, + void *user_data) { Tox_Event_Group_Moderation *group_moderation = tox_event_group_moderation_alloc(user_data); diff --git a/toxcore/events/group_password.c b/toxcore/events/group_password.c index cbfedd3c..ad6e86b9 100644 --- a/toxcore/events/group_password.c +++ b/toxcore/events/group_password.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Password { uint32_t group_number; uint8_t *password; @@ -42,7 +41,7 @@ uint32_t tox_event_group_password_get_group_number(const Tox_Event_Group_Passwor return group_password->group_number; } -non_null() +non_null(1) nullable(2) static bool tox_event_group_password_set_password(Tox_Event_Group_Password *group_password, const uint8_t *password, uint32_t password_length) { @@ -54,6 +53,11 @@ static bool tox_event_group_password_set_password(Tox_Event_Group_Password *grou group_password->password_length = 0; } + if (password == nullptr) { + assert(password_length == 0); + return true; + } + uint8_t *password_copy = (uint8_t *)malloc(password_length); if (password_copy == nullptr) { @@ -110,7 +114,6 @@ static bool tox_event_group_password_unpack_into( && bin_unpack_bin(bu, &event->password, &event->password_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -164,6 +167,7 @@ bool tox_event_group_password_unpack( Tox_Event_Group_Password **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_password_new(mem); if (*event == nullptr) { @@ -193,16 +197,15 @@ static Tox_Event_Group_Password *tox_event_group_password_alloc(void *user_data) return group_password; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_password(Tox *tox, uint32_t group_number, const uint8_t *password, size_t length, - void *user_data) +void tox_events_handle_group_password( + Tox *tox, uint32_t group_number, const uint8_t *password, size_t length, + void *user_data) { Tox_Event_Group_Password *group_password = tox_event_group_password_alloc(user_data); diff --git a/toxcore/events/group_peer_exit.c b/toxcore/events/group_peer_exit.c index fd56fd6c..16d1eba7 100644 --- a/toxcore/events/group_peer_exit.c +++ b/toxcore/events/group_peer_exit.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -17,14 +18,12 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Peer_Exit { uint32_t group_number; uint32_t peer_id; @@ -74,7 +73,7 @@ Tox_Group_Exit_Type tox_event_group_peer_exit_get_exit_type(const Tox_Event_Grou return group_peer_exit->exit_type; } -non_null() +non_null(1) nullable(2) static bool tox_event_group_peer_exit_set_name(Tox_Event_Group_Peer_Exit *group_peer_exit, const uint8_t *name, uint32_t name_length) { @@ -86,6 +85,11 @@ static bool tox_event_group_peer_exit_set_name(Tox_Event_Group_Peer_Exit *group_ group_peer_exit->name_length = 0; } + if (name == nullptr) { + assert(name_length == 0); + return true; + } + uint8_t *name_copy = (uint8_t *)malloc(name_length); if (name_copy == nullptr) { @@ -108,7 +112,7 @@ const uint8_t *tox_event_group_peer_exit_get_name(const Tox_Event_Group_Peer_Exi return group_peer_exit->name; } -non_null() +non_null(1) nullable(2) static bool tox_event_group_peer_exit_set_part_message(Tox_Event_Group_Peer_Exit *group_peer_exit, const uint8_t *part_message, uint32_t part_message_length) { @@ -120,6 +124,11 @@ static bool tox_event_group_peer_exit_set_part_message(Tox_Event_Group_Peer_Exit group_peer_exit->part_message_length = 0; } + if (part_message == nullptr) { + assert(part_message_length == 0); + return true; + } + uint8_t *part_message_copy = (uint8_t *)malloc(part_message_length); if (part_message_copy == nullptr) { @@ -183,7 +192,6 @@ static bool tox_event_group_peer_exit_unpack_into( && bin_unpack_bin(bu, &event->part_message, &event->part_message_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -237,6 +245,7 @@ bool tox_event_group_peer_exit_unpack( Tox_Event_Group_Peer_Exit **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_peer_exit_new(mem); if (*event == nullptr) { @@ -266,16 +275,15 @@ static Tox_Event_Group_Peer_Exit *tox_event_group_peer_exit_alloc(void *user_dat return group_peer_exit; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_peer_exit(Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Group_Exit_Type exit_type, const uint8_t *name, size_t name_length, const uint8_t *part_message, size_t part_message_length, - void *user_data) +void tox_events_handle_group_peer_exit( + Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Group_Exit_Type exit_type, const uint8_t *name, size_t name_length, const uint8_t *part_message, size_t part_message_length, + void *user_data) { Tox_Event_Group_Peer_Exit *group_peer_exit = tox_event_group_peer_exit_alloc(user_data); diff --git a/toxcore/events/group_peer_join.c b/toxcore/events/group_peer_join.c index c587c179..af0d006e 100644 --- a/toxcore/events/group_peer_join.c +++ b/toxcore/events/group_peer_join.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -13,14 +14,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Peer_Join { uint32_t group_number; uint32_t peer_id; @@ -86,7 +85,6 @@ static bool tox_event_group_peer_join_unpack_into( && bin_unpack_u32(bu, &event->peer_id); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -140,6 +138,7 @@ bool tox_event_group_peer_join_unpack( Tox_Event_Group_Peer_Join **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_peer_join_new(mem); if (*event == nullptr) { @@ -169,16 +168,15 @@ static Tox_Event_Group_Peer_Join *tox_event_group_peer_join_alloc(void *user_dat return group_peer_join; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_peer_join(Tox *tox, uint32_t group_number, uint32_t peer_id, - void *user_data) +void tox_events_handle_group_peer_join( + Tox *tox, uint32_t group_number, uint32_t peer_id, + void *user_data) { Tox_Event_Group_Peer_Join *group_peer_join = tox_event_group_peer_join_alloc(user_data); diff --git a/toxcore/events/group_peer_limit.c b/toxcore/events/group_peer_limit.c index 9a2daa7e..5e2e2355 100644 --- a/toxcore/events/group_peer_limit.c +++ b/toxcore/events/group_peer_limit.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -13,14 +14,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Peer_Limit { uint32_t group_number; uint32_t peer_limit; @@ -86,7 +85,6 @@ static bool tox_event_group_peer_limit_unpack_into( && bin_unpack_u32(bu, &event->peer_limit); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -140,6 +138,7 @@ bool tox_event_group_peer_limit_unpack( Tox_Event_Group_Peer_Limit **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_peer_limit_new(mem); if (*event == nullptr) { @@ -169,16 +168,15 @@ static Tox_Event_Group_Peer_Limit *tox_event_group_peer_limit_alloc(void *user_d return group_peer_limit; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_peer_limit(Tox *tox, uint32_t group_number, uint32_t peer_limit, - void *user_data) +void tox_events_handle_group_peer_limit( + Tox *tox, uint32_t group_number, uint32_t peer_limit, + void *user_data) { Tox_Event_Group_Peer_Limit *group_peer_limit = tox_event_group_peer_limit_alloc(user_data); diff --git a/toxcore/events/group_peer_name.c b/toxcore/events/group_peer_name.c index 6d6f77db..f8273e94 100644 --- a/toxcore/events/group_peer_name.c +++ b/toxcore/events/group_peer_name.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Peer_Name { uint32_t group_number; uint32_t peer_id; @@ -56,7 +55,7 @@ uint32_t tox_event_group_peer_name_get_peer_id(const Tox_Event_Group_Peer_Name * return group_peer_name->peer_id; } -non_null() +non_null(1) nullable(2) static bool tox_event_group_peer_name_set_name(Tox_Event_Group_Peer_Name *group_peer_name, const uint8_t *name, uint32_t name_length) { @@ -68,6 +67,11 @@ static bool tox_event_group_peer_name_set_name(Tox_Event_Group_Peer_Name *group_ group_peer_name->name_length = 0; } + if (name == nullptr) { + assert(name_length == 0); + return true; + } + uint8_t *name_copy = (uint8_t *)malloc(name_length); if (name_copy == nullptr) { @@ -126,7 +130,6 @@ static bool tox_event_group_peer_name_unpack_into( && bin_unpack_bin(bu, &event->name, &event->name_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -180,6 +183,7 @@ bool tox_event_group_peer_name_unpack( Tox_Event_Group_Peer_Name **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_peer_name_new(mem); if (*event == nullptr) { @@ -209,16 +213,15 @@ static Tox_Event_Group_Peer_Name *tox_event_group_peer_name_alloc(void *user_dat return group_peer_name; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_peer_name(Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *name, size_t length, - void *user_data) +void tox_events_handle_group_peer_name( + Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *name, size_t length, + void *user_data) { Tox_Event_Group_Peer_Name *group_peer_name = tox_event_group_peer_name_alloc(user_data); diff --git a/toxcore/events/group_peer_status.c b/toxcore/events/group_peer_status.c index 2cfe32e0..4165d90e 100644 --- a/toxcore/events/group_peer_status.c +++ b/toxcore/events/group_peer_status.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Peer_Status { uint32_t group_number; uint32_t peer_id; @@ -104,7 +103,6 @@ static bool tox_event_group_peer_status_unpack_into( && tox_user_status_unpack(&event->status, bu); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -158,6 +156,7 @@ bool tox_event_group_peer_status_unpack( Tox_Event_Group_Peer_Status **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_peer_status_new(mem); if (*event == nullptr) { @@ -187,16 +186,15 @@ static Tox_Event_Group_Peer_Status *tox_event_group_peer_status_alloc(void *user return group_peer_status; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_peer_status(Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_User_Status status, - void *user_data) +void tox_events_handle_group_peer_status( + Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_User_Status status, + void *user_data) { Tox_Event_Group_Peer_Status *group_peer_status = tox_event_group_peer_status_alloc(user_data); diff --git a/toxcore/events/group_privacy_state.c b/toxcore/events/group_privacy_state.c index 8623668b..1c683c25 100644 --- a/toxcore/events/group_privacy_state.c +++ b/toxcore/events/group_privacy_state.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Privacy_State { uint32_t group_number; Tox_Group_Privacy_State privacy_state; @@ -88,7 +87,6 @@ static bool tox_event_group_privacy_state_unpack_into( && tox_group_privacy_state_unpack(&event->privacy_state, bu); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -142,6 +140,7 @@ bool tox_event_group_privacy_state_unpack( Tox_Event_Group_Privacy_State **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_privacy_state_new(mem); if (*event == nullptr) { @@ -171,16 +170,15 @@ static Tox_Event_Group_Privacy_State *tox_event_group_privacy_state_alloc(void * return group_privacy_state; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_privacy_state(Tox *tox, uint32_t group_number, Tox_Group_Privacy_State privacy_state, - void *user_data) +void tox_events_handle_group_privacy_state( + Tox *tox, uint32_t group_number, Tox_Group_Privacy_State privacy_state, + void *user_data) { Tox_Event_Group_Privacy_State *group_privacy_state = tox_event_group_privacy_state_alloc(user_data); diff --git a/toxcore/events/group_private_message.c b/toxcore/events/group_private_message.c index acd7a713..a9efdd52 100644 --- a/toxcore/events/group_private_message.c +++ b/toxcore/events/group_private_message.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -17,20 +18,19 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Private_Message { uint32_t group_number; uint32_t peer_id; Tox_Message_Type type; uint8_t *message; uint32_t message_length; + uint32_t message_id; }; non_null() @@ -72,7 +72,7 @@ Tox_Message_Type tox_event_group_private_message_get_type(const Tox_Event_Group_ return group_private_message->type; } -non_null() +non_null(1) nullable(2) static bool tox_event_group_private_message_set_message(Tox_Event_Group_Private_Message *group_private_message, const uint8_t *message, uint32_t message_length) { @@ -84,6 +84,11 @@ static bool tox_event_group_private_message_set_message(Tox_Event_Group_Private_ group_private_message->message_length = 0; } + if (message == nullptr) { + assert(message_length == 0); + return true; + } + uint8_t *message_copy = (uint8_t *)malloc(message_length); if (message_copy == nullptr) { @@ -106,6 +111,19 @@ const uint8_t *tox_event_group_private_message_get_message(const Tox_Event_Group return group_private_message->message; } +non_null() +static void tox_event_group_private_message_set_message_id(Tox_Event_Group_Private_Message *group_private_message, + uint32_t message_id) +{ + assert(group_private_message != nullptr); + group_private_message->message_id = message_id; +} +uint32_t tox_event_group_private_message_get_message_id(const Tox_Event_Group_Private_Message *group_private_message) +{ + assert(group_private_message != nullptr); + return group_private_message->message_id; +} + non_null() static void tox_event_group_private_message_construct(Tox_Event_Group_Private_Message *group_private_message) { @@ -122,11 +140,12 @@ static void tox_event_group_private_message_destruct(Tox_Event_Group_Private_Mes bool tox_event_group_private_message_pack( const Tox_Event_Group_Private_Message *event, Bin_Pack *bp) { - return bin_pack_array(bp, 4) + return bin_pack_array(bp, 5) && bin_pack_u32(bp, event->group_number) && bin_pack_u32(bp, event->peer_id) && tox_message_type_pack(event->type, bp) - && bin_pack_bin(bp, event->message, event->message_length); + && bin_pack_bin(bp, event->message, event->message_length) + && bin_pack_u32(bp, event->message_id); } non_null() @@ -134,17 +153,17 @@ static bool tox_event_group_private_message_unpack_into( Tox_Event_Group_Private_Message *event, Bin_Unpack *bu) { assert(event != nullptr); - if (!bin_unpack_array_fixed(bu, 4, nullptr)) { + if (!bin_unpack_array_fixed(bu, 5, nullptr)) { return false; } return bin_unpack_u32(bu, &event->group_number) && bin_unpack_u32(bu, &event->peer_id) && tox_message_type_unpack(&event->type, bu) - && bin_unpack_bin(bu, &event->message, &event->message_length); + && bin_unpack_bin(bu, &event->message, &event->message_length) + && bin_unpack_u32(bu, &event->message_id); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -198,6 +217,7 @@ bool tox_event_group_private_message_unpack( Tox_Event_Group_Private_Message **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_private_message_new(mem); if (*event == nullptr) { @@ -227,16 +247,15 @@ static Tox_Event_Group_Private_Message *tox_event_group_private_message_alloc(vo return group_private_message; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_private_message(Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Message_Type type, const uint8_t *message, size_t length, - void *user_data) +void tox_events_handle_group_private_message( + Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Message_Type type, const uint8_t *message, size_t length, uint32_t message_id, + void *user_data) { Tox_Event_Group_Private_Message *group_private_message = tox_event_group_private_message_alloc(user_data); @@ -248,4 +267,5 @@ void tox_events_handle_group_private_message(Tox *tox, uint32_t group_number, ui tox_event_group_private_message_set_peer_id(group_private_message, peer_id); tox_event_group_private_message_set_type(group_private_message, type); tox_event_group_private_message_set_message(group_private_message, message, length); + tox_event_group_private_message_set_message_id(group_private_message, message_id); } diff --git a/toxcore/events/group_self_join.c b/toxcore/events/group_self_join.c index 904a3e53..0745e975 100644 --- a/toxcore/events/group_self_join.c +++ b/toxcore/events/group_self_join.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -13,14 +14,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Self_Join { uint32_t group_number; }; @@ -65,7 +64,6 @@ static bool tox_event_group_self_join_unpack_into( return bin_unpack_u32(bu, &event->group_number); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -119,6 +117,7 @@ bool tox_event_group_self_join_unpack( Tox_Event_Group_Self_Join **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_self_join_new(mem); if (*event == nullptr) { @@ -148,16 +147,15 @@ static Tox_Event_Group_Self_Join *tox_event_group_self_join_alloc(void *user_dat return group_self_join; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_self_join(Tox *tox, uint32_t group_number, - void *user_data) +void tox_events_handle_group_self_join( + Tox *tox, uint32_t group_number, + void *user_data) { Tox_Event_Group_Self_Join *group_self_join = tox_event_group_self_join_alloc(user_data); diff --git a/toxcore/events/group_topic.c b/toxcore/events/group_topic.c index 3a62024b..23cdd5d3 100644 --- a/toxcore/events/group_topic.c +++ b/toxcore/events/group_topic.c @@ -8,6 +8,7 @@ #include #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox.h" #include "../tox_events.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Topic { uint32_t group_number; uint32_t peer_id; @@ -56,7 +55,7 @@ uint32_t tox_event_group_topic_get_peer_id(const Tox_Event_Group_Topic *group_to return group_topic->peer_id; } -non_null() +non_null(1) nullable(2) static bool tox_event_group_topic_set_topic(Tox_Event_Group_Topic *group_topic, const uint8_t *topic, uint32_t topic_length) { @@ -68,6 +67,11 @@ static bool tox_event_group_topic_set_topic(Tox_Event_Group_Topic *group_topic, group_topic->topic_length = 0; } + if (topic == nullptr) { + assert(topic_length == 0); + return true; + } + uint8_t *topic_copy = (uint8_t *)malloc(topic_length); if (topic_copy == nullptr) { @@ -126,7 +130,6 @@ static bool tox_event_group_topic_unpack_into( && bin_unpack_bin(bu, &event->topic, &event->topic_length); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -180,6 +183,7 @@ bool tox_event_group_topic_unpack( Tox_Event_Group_Topic **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_topic_new(mem); if (*event == nullptr) { @@ -209,16 +213,15 @@ static Tox_Event_Group_Topic *tox_event_group_topic_alloc(void *user_data) return group_topic; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_topic(Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *topic, size_t length, - void *user_data) +void tox_events_handle_group_topic( + Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *topic, size_t length, + void *user_data) { Tox_Event_Group_Topic *group_topic = tox_event_group_topic_alloc(user_data); diff --git a/toxcore/events/group_topic_lock.c b/toxcore/events/group_topic_lock.c index 82d37a15..36fb4939 100644 --- a/toxcore/events/group_topic_lock.c +++ b/toxcore/events/group_topic_lock.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Topic_Lock { uint32_t group_number; Tox_Group_Topic_Lock topic_lock; @@ -88,7 +87,6 @@ static bool tox_event_group_topic_lock_unpack_into( && tox_group_topic_lock_unpack(&event->topic_lock, bu); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -142,6 +140,7 @@ bool tox_event_group_topic_lock_unpack( Tox_Event_Group_Topic_Lock **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_topic_lock_new(mem); if (*event == nullptr) { @@ -171,16 +170,15 @@ static Tox_Event_Group_Topic_Lock *tox_event_group_topic_lock_alloc(void *user_d return group_topic_lock; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_topic_lock(Tox *tox, uint32_t group_number, Tox_Group_Topic_Lock topic_lock, - void *user_data) +void tox_events_handle_group_topic_lock( + Tox *tox, uint32_t group_number, Tox_Group_Topic_Lock topic_lock, + void *user_data) { Tox_Event_Group_Topic_Lock *group_topic_lock = tox_event_group_topic_lock_alloc(user_data); diff --git a/toxcore/events/group_voice_state.c b/toxcore/events/group_voice_state.c index 7bcfa556..fba03003 100644 --- a/toxcore/events/group_voice_state.c +++ b/toxcore/events/group_voice_state.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Group_Voice_State { uint32_t group_number; Tox_Group_Voice_State voice_state; @@ -88,7 +87,6 @@ static bool tox_event_group_voice_state_unpack_into( && tox_group_voice_state_unpack(&event->voice_state, bu); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -142,6 +140,7 @@ bool tox_event_group_voice_state_unpack( Tox_Event_Group_Voice_State **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_group_voice_state_new(mem); if (*event == nullptr) { @@ -171,16 +170,15 @@ static Tox_Event_Group_Voice_State *tox_event_group_voice_state_alloc(void *user return group_voice_state; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_group_voice_state(Tox *tox, uint32_t group_number, Tox_Group_Voice_State voice_state, - void *user_data) +void tox_events_handle_group_voice_state( + Tox *tox, uint32_t group_number, Tox_Group_Voice_State voice_state, + void *user_data) { Tox_Event_Group_Voice_State *group_voice_state = tox_event_group_voice_state_alloc(user_data); diff --git a/toxcore/events/self_connection_status.c b/toxcore/events/self_connection_status.c index 417a3fe3..8d8bc803 100644 --- a/toxcore/events/self_connection_status.c +++ b/toxcore/events/self_connection_status.c @@ -6,6 +6,7 @@ #include +#include "../attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../ccompat.h" @@ -15,14 +16,12 @@ #include "../tox_pack.h" #include "../tox_unpack.h" - /***************************************************** * * :: struct and accessors * *****************************************************/ - struct Tox_Event_Self_Connection_Status { Tox_Connection connection_status; }; @@ -67,7 +66,6 @@ static bool tox_event_self_connection_status_unpack_into( return tox_connection_unpack(&event->connection_status, bu); } - /***************************************************** * * :: new/free/add/get/size/unpack @@ -121,6 +119,7 @@ bool tox_event_self_connection_status_unpack( Tox_Event_Self_Connection_Status **event, Bin_Unpack *bu, const Memory *mem) { assert(event != nullptr); + assert(*event == nullptr); *event = tox_event_self_connection_status_new(mem); if (*event == nullptr) { @@ -150,16 +149,15 @@ static Tox_Event_Self_Connection_Status *tox_event_self_connection_status_alloc( return self_connection_status; } - /***************************************************** * * :: event handler * *****************************************************/ - -void tox_events_handle_self_connection_status(Tox *tox, Tox_Connection connection_status, - void *user_data) +void tox_events_handle_self_connection_status( + Tox *tox, Tox_Connection connection_status, + void *user_data) { Tox_Event_Self_Connection_Status *self_connection_status = tox_event_self_connection_status_alloc(user_data); diff --git a/toxcore/forwarding.c b/toxcore/forwarding.c index 37a0f841..18ff3203 100644 --- a/toxcore/forwarding.c +++ b/toxcore/forwarding.c @@ -9,6 +9,7 @@ #include #include "DHT.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "logger.h" diff --git a/toxcore/forwarding.h b/toxcore/forwarding.h index a97971e6..bd0ef09e 100644 --- a/toxcore/forwarding.h +++ b/toxcore/forwarding.h @@ -6,6 +6,10 @@ #define C_TOXCORE_TOXCORE_FORWARDING_H #include "DHT.h" +#include "attributes.h" +#include "crypto_core.h" +#include "logger.h" +#include "mono_time.h" #include "network.h" #ifdef __cplusplus @@ -79,7 +83,6 @@ bool forward_reply(const Networking_Core *net, const IP_Port *forwarder, const uint8_t *sendback, uint16_t sendback_length, const uint8_t *data, uint16_t length); - /** * @brief Set callback to handle a forwarded request. * To reply to the packet, callback should use `forward_reply()` to send a reply @@ -119,7 +122,7 @@ nullable(1) void kill_forwarding(Forwarding *forwarding); #ifdef __cplusplus -} // extern "C" +} /* extern "C" */ #endif -#endif +#endif /* C_TOXCORE_TOXCORE_FORWARDING_H */ diff --git a/toxcore/forwarding_fuzz_test.cc b/toxcore/forwarding_fuzz_test.cc index 99d2121f..da772a19 100644 --- a/toxcore/forwarding_fuzz_test.cc +++ b/toxcore/forwarding_fuzz_test.cc @@ -5,8 +5,8 @@ #include #include -#include "../testing/fuzzing/fuzz_support.h" -#include "../testing/fuzzing/fuzz_tox.h" +#include "../testing/fuzzing/fuzz_support.hh" +#include "../testing/fuzzing/fuzz_tox.hh" namespace { diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c index f41563e1..33bfa40d 100644 --- a/toxcore/friend_connection.c +++ b/toxcore/friend_connection.c @@ -14,13 +14,17 @@ #include "DHT.h" #include "LAN_discovery.h" #include "TCP_connection.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "logger.h" #include "mono_time.h" #include "net_crypto.h" #include "network.h" +#include "onion.h" +#include "onion_announce.h" #include "onion_client.h" +#include "util.h" #define PORTS_PER_DISCOVERY 10 @@ -63,7 +67,6 @@ struct Friend_Conn { static const Friend_Conn empty_friend_conn = {0}; - struct Friend_Connections { const Mono_Time *mono_time; const Logger *logger; @@ -102,7 +105,6 @@ const IP_Port *friend_conn_get_dht_ip_port(const Friend_Conn *fc) return &fc->dht_ip_port; } - /** * @retval true if the friendcon_id is valid. * @retval false if the friendcon_id is not valid. @@ -115,7 +117,6 @@ static bool friendconn_id_valid(const Friend_Connections *fr_c, int friendcon_id fr_c->conns[friendcon_id].status != FRIENDCONN_STATUS_NONE; } - /** @brief Set the size of the friend connections list to num. * * @retval false if realloc fails. @@ -245,7 +246,7 @@ static int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, cons if (!net_family_is_unspec(friend_con->dht_ip_port.ip.family)) { ipp_copy.ip = friend_con->dht_ip_port.ip; } else { - friend_con->hosting_tcp_relay = 0; + friend_con->hosting_tcp_relay = false; } } @@ -369,7 +370,7 @@ static void dht_ip_callback(void *object, int32_t number, const IP_Port *ip_port if (friend_con->hosting_tcp_relay) { friend_add_tcp_relay(fr_c, number, ip_port, friend_con->dht_temp_pk); - friend_con->hosting_tcp_relay = 0; + friend_con->hosting_tcp_relay = false; } } @@ -397,10 +398,10 @@ static void change_dht_pk(Friend_Connections *fr_c, int friendcon_id, const uint } non_null() -static int handle_status(void *object, int number, bool status, void *userdata) +static int handle_status(void *object, int id, bool status, void *userdata) { Friend_Connections *const fr_c = (Friend_Connections *)object; - Friend_Conn *const friend_con = get_conn(fr_c, number); + Friend_Conn *const friend_con = get_conn(fr_c, id); if (friend_con == nullptr) { return -1; @@ -423,12 +424,12 @@ static int handle_status(void *object, int number, bool status, void *userdata) friend_con->status = FRIENDCONN_STATUS_CONNECTING; friend_con->crypt_connection_id = -1; - friend_con->hosting_tcp_relay = 0; + friend_con->hosting_tcp_relay = false; } if (status_changed) { if (fr_c->global_status_callback != nullptr) { - fr_c->global_status_callback(fr_c->global_status_callback_object, number, status, userdata); + fr_c->global_status_callback(fr_c->global_status_callback_object, id, status, userdata); } for (unsigned i = 0; i < MAX_FRIEND_CONNECTION_CALLBACKS; ++i) { @@ -472,7 +473,7 @@ static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_pub } non_null() -static int handle_packet(void *object, int number, const uint8_t *data, uint16_t length, void *userdata) +static int handle_packet(void *object, int id, const uint8_t *data, uint16_t length, void *userdata) { Friend_Connections *const fr_c = (Friend_Connections *)object; @@ -480,7 +481,7 @@ static int handle_packet(void *object, int number, const uint8_t *data, uint16_t return -1; } - Friend_Conn *friend_con = get_conn(fr_c, number); + Friend_Conn *friend_con = get_conn(fr_c, id); if (friend_con == nullptr) { return -1; @@ -508,7 +509,7 @@ static int handle_packet(void *object, int number, const uint8_t *data, uint16_t } for (int j = 0; j < n; ++j) { - friend_add_tcp_relay(fr_c, number, &nodes[j].ip_port, nodes[j].public_key); + friend_add_tcp_relay(fr_c, id, &nodes[j].ip_port, nodes[j].public_key); } return 0; @@ -521,7 +522,7 @@ static int handle_packet(void *object, int number, const uint8_t *data, uint16_t friend_con->callbacks[i].callback_id, data, length, userdata); } - friend_con = get_conn(fr_c, number); + friend_con = get_conn(fr_c, id); if (friend_con == nullptr) { return -1; @@ -532,7 +533,7 @@ static int handle_packet(void *object, int number, const uint8_t *data, uint16_t } non_null() -static int handle_lossy_packet(void *object, int number, const uint8_t *data, uint16_t length, void *userdata) +static int handle_lossy_packet(void *object, int id, const uint8_t *data, uint16_t length, void *userdata) { const Friend_Connections *const fr_c = (const Friend_Connections *)object; @@ -540,7 +541,7 @@ static int handle_lossy_packet(void *object, int number, const uint8_t *data, ui return -1; } - const Friend_Conn *friend_con = get_conn(fr_c, number); + const Friend_Conn *friend_con = get_conn(fr_c, id); if (friend_con == nullptr) { return -1; @@ -553,7 +554,7 @@ static int handle_lossy_packet(void *object, int number, const uint8_t *data, ui friend_con->callbacks[i].callback_id, data, length, userdata); } - friend_con = get_conn(fr_c, number); + friend_con = get_conn(fr_c, id); if (friend_con == nullptr) { return -1; @@ -854,7 +855,6 @@ int kill_friend_connection(Friend_Connections *fr_c, int friendcon_id) return wipe_friend_conn(fr_c, friendcon_id); } - /** @brief Set friend request callback. * * This function will be called every time a friend request packet is received. @@ -885,18 +885,19 @@ int send_friend_request_packet(Friend_Connections *fr_c, int friendcon_id, uint3 return -1; } - VLA(uint8_t, packet, 1 + sizeof(nospam_num) + length); + const uint16_t packet_size = 1 + sizeof(nospam_num) + length; + VLA(uint8_t, packet, packet_size); memcpy(packet + 1, &nospam_num, sizeof(nospam_num)); memcpy(packet + 1 + sizeof(nospam_num), data, length); if (friend_con->status == FRIENDCONN_STATUS_CONNECTED) { packet[0] = PACKET_ID_FRIEND_REQUESTS; - return write_cryptpacket(fr_c->net_crypto, friend_con->crypt_connection_id, packet, SIZEOF_VLA(packet), + return write_cryptpacket(fr_c->net_crypto, friend_con->crypt_connection_id, packet, packet_size, false) != -1 ? 1 : 0; } packet[0] = CRYPTO_PACKET_FRIEND_REQ; - const int num = send_onion_data(fr_c->onion_c, friend_con->onion_friendnum, packet, SIZEOF_VLA(packet)); + const int num = send_onion_data(fr_c->onion_c, friend_con->onion_friendnum, packet, packet_size); if (num <= 0) { return -1; @@ -907,8 +908,8 @@ int send_friend_request_packet(Friend_Connections *fr_c, int friendcon_id, uint3 /** Create new friend_connections instance. */ Friend_Connections *new_friend_connections( - const Logger *logger, const Mono_Time *mono_time, const Network *ns, - Onion_Client *onion_c, bool local_discovery_enabled) + const Logger *logger, const Mono_Time *mono_time, const Network *ns, + Onion_Client *onion_c, bool local_discovery_enabled) { if (onion_c == nullptr) { return nullptr; @@ -982,7 +983,7 @@ void do_friend_connections(Friend_Connections *fr_c, void *userdata) if (friend_con->dht_lock_token > 0) { dht_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock_token); friend_con->dht_lock_token = 0; - memset(friend_con->dht_temp_pk, 0, CRYPTO_PUBLIC_KEY_SIZE); + memzero(friend_con->dht_temp_pk, CRYPTO_PUBLIC_KEY_SIZE); } } diff --git a/toxcore/friend_connection.h b/toxcore/friend_connection.h index 93bd5113..bbd44547 100644 --- a/toxcore/friend_connection.h +++ b/toxcore/friend_connection.h @@ -9,9 +9,15 @@ #ifndef C_TOXCORE_TOXCORE_FRIEND_CONNECTION_H #define C_TOXCORE_TOXCORE_FRIEND_CONNECTION_H +#include + #include "DHT.h" #include "LAN_discovery.h" +#include "attributes.h" +#include "logger.h" +#include "mono_time.h" #include "net_crypto.h" +#include "network.h" #include "onion_client.h" #define MAX_FRIEND_CONNECTION_CALLBACKS 2 @@ -39,7 +45,6 @@ /** How often we share our TCP relays with each friend connection */ #define SHARE_RELAYS_INTERVAL (60 * 2) - typedef enum Friendconn_Status { FRIENDCONN_STATUS_NONE, FRIENDCONN_STATUS_CONNECTING, @@ -84,11 +89,11 @@ int get_friendcon_public_keys(uint8_t *real_pk, uint8_t *dht_temp_pk, const Frie non_null() void set_dht_temp_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_temp_pk, void *userdata); -typedef int global_status_cb(void *object, int id, bool status, void *userdata); +typedef int global_status_cb(void *object, int friendcon_id, bool status, void *userdata); -typedef int fc_status_cb(void *object, int id, bool status, void *userdata); -typedef int fc_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); -typedef int fc_lossy_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); +typedef int fc_status_cb(void *object, int friendcon_id, bool status, void *userdata); +typedef int fc_data_cb(void *object, int friendcon_id, const uint8_t *data, uint16_t length, void *userdata); +typedef int fc_lossy_data_cb(void *object, int friendcon_id, const uint8_t *data, uint16_t length, void *userdata); /** Set global status callback for friend connections. */ non_null(1) nullable(2, 3) @@ -144,7 +149,7 @@ int send_friend_request_packet( Friend_Connections *fr_c, int friendcon_id, uint32_t nospam_num, const uint8_t *data, uint16_t length); typedef int fr_request_cb( - void *object, const uint8_t *source_pubkey, const uint8_t *data, uint16_t len, void *userdata); + void *object, const uint8_t *source_pubkey, const uint8_t *data, uint16_t length, void *userdata); /** @brief Set friend request callback. * @@ -156,8 +161,8 @@ void set_friend_request_callback(Friend_Connections *fr_c, fr_request_cb *fr_req /** Create new friend_connections instance. */ non_null() Friend_Connections *new_friend_connections( - const Logger *logger, const Mono_Time *mono_time, const Network *ns, - Onion_Client *onion_c, bool local_discovery_enabled); + const Logger *logger, const Mono_Time *mono_time, const Network *ns, + Onion_Client *onion_c, bool local_discovery_enabled); /** main friend_connections loop. */ non_null() @@ -173,4 +178,4 @@ non_null() Friend_Conn *get_conn(const Friend_Connections *fr_c, int friendcon_i non_null() int friend_conn_get_onion_friendnum(const Friend_Conn *fc); non_null() const IP_Port *friend_conn_get_dht_ip_port(const Friend_Conn *fc); -#endif +#endif /* C_TOXCORE_TOXCORE_FRIEND_CONNECTION_H */ diff --git a/toxcore/friend_requests.c b/toxcore/friend_requests.c index c780f3e3..8b915449 100644 --- a/toxcore/friend_requests.c +++ b/toxcore/friend_requests.c @@ -11,9 +11,13 @@ #include #include +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "friend_connection.h" +#include "network.h" +#include "onion.h" +#include "onion_announce.h" #include "onion_client.h" /** @@ -50,7 +54,6 @@ uint32_t get_nospam(const Friend_Requests *fr) return fr->nospam; } - /** Set the function that will be executed when a friend request for us is received. */ void callback_friendrequest(Friend_Requests *fr, fr_friend_request_cb *function, void *object) { @@ -114,9 +117,8 @@ int remove_request_received(Friend_Requests *fr, const uint8_t *real_pk) return -1; } - non_null() -static int friendreq_handlepacket(void *object, const uint8_t *source_pubkey, const uint8_t *packet, uint16_t length, +static int friendreq_handlepacket(void *object, const uint8_t *source_pubkey, const uint8_t *data, uint16_t length, void *userdata) { Friend_Requests *const fr = (Friend_Requests *)object; @@ -125,7 +127,7 @@ static int friendreq_handlepacket(void *object, const uint8_t *source_pubkey, co return 1; } - ++packet; + ++data; --length; if (fr->handle_friendrequest_isset == 0) { @@ -136,22 +138,22 @@ static int friendreq_handlepacket(void *object, const uint8_t *source_pubkey, co return 1; } - if (memcmp(packet, &fr->nospam, sizeof(fr->nospam)) != 0) { + if (memcmp(data, &fr->nospam, sizeof(fr->nospam)) != 0) { return 1; } if (fr->filter_function != nullptr) { - if (fr->filter_function(source_pubkey, fr->filter_function_userdata) != 0) { + if (fr->filter_function(fr->filter_function_userdata, source_pubkey) != 0) { return 1; } } addto_receivedlist(fr, source_pubkey); - const uint32_t message_len = length - sizeof(fr->nospam); + const uint16_t message_len = length - sizeof(fr->nospam); VLA(uint8_t, message, message_len + 1); - memcpy(message, packet + sizeof(fr->nospam), message_len); - message[SIZEOF_VLA(message) - 1] = 0; /* Be sure the message is null terminated. */ + memcpy(message, data + sizeof(fr->nospam), message_len); + message[message_len] = 0; /* Be sure the message is null terminated. TODO(iphydf): But why? */ fr->handle_friendrequest(fr->handle_friendrequest_object, source_pubkey, message, message_len, userdata); return 0; diff --git a/toxcore/friend_requests.h b/toxcore/friend_requests.h index 26145271..a78a570d 100644 --- a/toxcore/friend_requests.h +++ b/toxcore/friend_requests.h @@ -9,6 +9,9 @@ #ifndef C_TOXCORE_TOXCORE_FRIEND_REQUESTS_H #define C_TOXCORE_TOXCORE_FRIEND_REQUESTS_H +#include + +#include "attributes.h" #include "friend_connection.h" #define MAX_FRIEND_REQUEST_DATA_SIZE (ONION_CLIENT_MAX_DATA_SIZE - (1 + sizeof(uint32_t))) @@ -34,7 +37,7 @@ typedef void fr_friend_request_cb(void *object, const uint8_t *public_key, const non_null() void callback_friendrequest(Friend_Requests *fr, fr_friend_request_cb *function, void *object); -typedef int filter_function_cb(const uint8_t *public_key, void *user_data); +typedef int filter_function_cb(void *object, const uint8_t *public_key); /** @brief Set the function used to check if a friend request should be displayed to the user or not. * It must return 0 if the request is ok (anything else if it is bad). @@ -51,4 +54,4 @@ Friend_Requests *friendreq_new(void); nullable(1) void friendreq_kill(Friend_Requests *fr); -#endif +#endif /* C_TOXCORE_TOXCORE_FRIEND_REQUESTS_H */ diff --git a/toxcore/group.c b/toxcore/group.c index fea80e40..14e61e6f 100644 --- a/toxcore/group.c +++ b/toxcore/group.c @@ -14,6 +14,7 @@ #include "DHT.h" #include "Messenger.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "friend_connection.h" @@ -243,7 +244,6 @@ static bool is_groupnumber_valid(const Group_Chats *g_c, uint32_t groupnumber) && g_c->chats[groupnumber].status != GROUPCHAT_STATUS_NONE; } - /** @brief Set the size of the groupchat list to num. * * @retval false if realloc fails. @@ -429,7 +429,6 @@ static int get_peer_index(const Group_c *g, uint16_t peer_number) return -1; } - non_null() static uint64_t calculate_comp_value(const uint8_t *pk1, const uint8_t *pk2) { @@ -488,7 +487,7 @@ static bool add_to_closest(Group_c *g, const uint8_t *real_pk, const uint8_t *te comp_val = calculate_comp_value(real_pk, g->real_pk); for (unsigned int i = DESIRED_CLOSEST / 2; i < DESIRED_CLOSEST; ++i) { - uint64_t comp = calculate_comp_value(g->closest_peers[i].real_pk, g->real_pk); + const uint64_t comp = calculate_comp_value(g->closest_peers[i].real_pk, g->real_pk); if (comp > comp_val && comp > comp_d) { index = i; @@ -956,11 +955,6 @@ static bool delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void return true; } -static int cmp_u64(uint64_t a, uint64_t b) -{ - return (a > b ? 1 : 0) - (a < b ? 1 : 0); -} - /** Order peers with friends first and with more recently active earlier */ non_null() static int cmp_frozen(const void *a, const void *b) @@ -972,7 +966,7 @@ static int cmp_frozen(const void *a, const void *b) return pa->is_friend ? -1 : 1; } - return cmp_u64(pb->last_active, pa->last_active); + return cmp_uint(pb->last_active, pa->last_active); } /** @brief Delete frozen peers as necessary to ensure at most `g->maxfrozen` remain. @@ -1043,7 +1037,6 @@ static bool freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, return true; } - /** @brief Set the nick for a peer. * * do_gc_callback indicates whether we want to trigger callbacks set by the client @@ -1405,7 +1398,6 @@ static const Group_Peer *peer_in_list(const Group_c *g, uint32_t peernumber, boo return &list[peernumber]; } - /** * @brief Copy the public key of (frozen, if frozen is true) peernumber who is in * groupnumber to pk. @@ -1622,12 +1614,13 @@ static bool send_packet_group_peer(const Friend_Connections *fr_c, int friendcon } group_num = net_htons(group_num); - VLA(uint8_t, packet, 1 + sizeof(uint16_t) + length); + const uint32_t packet_size = 1 + sizeof(uint16_t) + length; + VLA(uint8_t, packet, packet_size); packet[0] = packet_id; memcpy(packet + 1, &group_num, sizeof(uint16_t)); memcpy(packet + 1 + sizeof(uint16_t), data, length); - return write_cryptpacket(friendconn_net_crypto(fr_c), friend_connection_crypt_connection_id(fr_c, friendcon_id), packet, - SIZEOF_VLA(packet), false) != -1; + return write_cryptpacket(friendconn_net_crypto(fr_c), friend_connection_crypt_connection_id(fr_c, friendcon_id), + packet, packet_size, false) != -1; } /** @brief Send a group lossy packet to friendcon_id. @@ -1644,12 +1637,13 @@ static bool send_lossy_group_peer(const Friend_Connections *fr_c, int friendcon_ } group_num = net_htons(group_num); - VLA(uint8_t, packet, 1 + sizeof(uint16_t) + length); + const uint32_t packet_size = 1 + sizeof(uint16_t) + length; + VLA(uint8_t, packet, packet_size); packet[0] = packet_id; memcpy(packet + 1, &group_num, sizeof(uint16_t)); memcpy(packet + 1 + sizeof(uint16_t), data, length); return send_lossy_cryptpacket(friendconn_net_crypto(fr_c), friend_connection_crypt_connection_id(fr_c, friendcon_id), - packet, SIZEOF_VLA(packet)) != -1; + packet, packet_size) != -1; } /** @brief invite friendnumber to groupnumber. @@ -1782,7 +1776,8 @@ static bool send_invite_response(Group_Chats *g_c, int groupnumber, uint32_t fri const bool member = g->status == GROUPCHAT_STATUS_CONNECTED; - VLA(uint8_t, response, member ? INVITE_MEMBER_PACKET_SIZE : INVITE_ACCEPT_PACKET_SIZE); + const uint32_t response_size = member ? INVITE_MEMBER_PACKET_SIZE : INVITE_ACCEPT_PACKET_SIZE; + VLA(uint8_t, response, response_size); response[0] = member ? INVITE_MEMBER_ID : INVITE_ACCEPT_ID; net_pack_u16(response + 1, groupnumber); memcpy(response + 1 + sizeof(uint16_t), data, length); @@ -1791,7 +1786,7 @@ static bool send_invite_response(Group_Chats *g_c, int groupnumber, uint32_t fri net_pack_u16(response + 1 + sizeof(uint16_t) + length, g->peer_number); } - if (!send_conference_invite_packet(g_c->m, friendnumber, response, SIZEOF_VLA(response))) { + if (!send_conference_invite_packet(g_c->m, friendnumber, response, response_size)) { return false; } @@ -2013,7 +2008,6 @@ static bool group_leave(const Group_Chats *g_c, uint32_t groupnumber, bool perma } } - /** @brief set the group's title, limited to MAX_NAME_LENGTH. * @retval 0 on success * @retval -1 if groupnumber is invalid. @@ -2115,8 +2109,8 @@ static bool get_peer_number(const Group_c *g, const uint8_t *real_pk, uint16_t * } non_null(1, 3) nullable(5) -static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, - void *userdata) +static void handle_friend_invite_packet(Messenger *m, uint32_t friend_number, const uint8_t *cookie, uint16_t length, + void *user_data) { Group_Chats *g_c = m->conferences_object; @@ -2124,20 +2118,20 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con return; } - switch (data[0]) { + switch (cookie[0]) { case INVITE_ID: { if (length != INVITE_PACKET_SIZE) { return; } - const int groupnumber = get_group_num(g_c, data[1 + sizeof(uint16_t)], data + 1 + sizeof(uint16_t) + 1); + const int groupnumber = get_group_num(g_c, cookie[1 + sizeof(uint16_t)], cookie + 1 + sizeof(uint16_t) + 1); - const uint8_t *invite_data = data + 1; + const uint8_t *invite_data = cookie + 1; const uint16_t invite_length = length - 1; if (groupnumber == -1) { if (g_c->invite_callback != nullptr) { - g_c->invite_callback(m, friendnumber, invite_data[sizeof(uint16_t)], invite_data, invite_length, userdata); + g_c->invite_callback(m, friend_number, invite_data[sizeof(uint16_t)], invite_data, invite_length, user_data); } return; @@ -2145,7 +2139,7 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con const Group_c *g = get_group_c(g_c, groupnumber); if (g != nullptr && g->status == GROUPCHAT_STATUS_CONNECTED) { - send_invite_response(g_c, groupnumber, friendnumber, invite_data, invite_length); + send_invite_response(g_c, groupnumber, friend_number, invite_data, invite_length); } } @@ -2154,7 +2148,7 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con case INVITE_ACCEPT_ID: case INVITE_MEMBER_ID: { - const bool member = data[0] == INVITE_MEMBER_ID; + const bool member = cookie[0] == INVITE_MEMBER_ID; if (length != (member ? INVITE_MEMBER_PACKET_SIZE : INVITE_ACCEPT_PACKET_SIZE)) { return; @@ -2162,8 +2156,8 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con uint16_t other_groupnum; uint16_t groupnum; - net_unpack_u16(data + 1, &other_groupnum); - net_unpack_u16(data + 1 + sizeof(uint16_t), &groupnum); + net_unpack_u16(cookie + 1, &other_groupnum); + net_unpack_u16(cookie + 1 + sizeof(uint16_t), &groupnum); Group_c *g = get_group_c(g_c, groupnum); @@ -2171,18 +2165,18 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con return; } - if (data[1 + sizeof(uint16_t) * 2] != g->type) { + if (cookie[1 + sizeof(uint16_t) * 2] != g->type) { return; } - if (!group_id_eq(data + 1 + sizeof(uint16_t) * 2 + 1, g->id)) { + if (!group_id_eq(cookie + 1 + sizeof(uint16_t) * 2 + 1, g->id)) { return; } uint16_t peer_number; if (member) { - net_unpack_u16(data + 1 + sizeof(uint16_t) * 2 + 1 + GROUP_ID_LENGTH, &peer_number); + net_unpack_u16(cookie + 1 + sizeof(uint16_t) * 2 + 1 + GROUP_ID_LENGTH, &peer_number); } else { /* TODO(irungentoo): what if two people enter the group at the * same time and are given the same peer_number by different @@ -2201,7 +2195,7 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con } } - const int friendcon_id = getfriendcon_id(m, friendnumber); + const int friendcon_id = getfriendcon_id(m, friend_number); if (friendcon_id == -1) { // TODO(iphydf): Log something? @@ -2212,7 +2206,7 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con uint8_t temp_pk[CRYPTO_PUBLIC_KEY_SIZE]; get_friendcon_public_keys(real_pk, temp_pk, g_c->fr_c, friendcon_id); - addpeer(g_c, groupnum, real_pk, temp_pk, peer_number, userdata, true, true); + addpeer(g_c, groupnum, real_pk, temp_pk, peer_number, user_data, true, true); const int connection_index = add_conn_to_groupchat(g_c, friendcon_id, g, GROUPCHAT_CONNECTION_REASON_INTRODUCING, true); @@ -2386,7 +2380,6 @@ static int handle_packet_rejoin(Group_Chats *g_c, int friendcon_id, const uint8_ return 0; } - // we could send title with invite, but then if it changes between sending and accepting inv, joinee won't see it /** @@ -2400,7 +2393,6 @@ static bool send_peer_introduced(const Group_Chats *g_c, int friendcon_id, uint1 return send_packet_group_peer(g_c->fr_c, friendcon_id, PACKET_ID_DIRECT_CONFERENCE, group_num, packet, sizeof(packet)); } - /** * @retval true on success. * @retval false on failure @@ -2457,11 +2449,12 @@ static unsigned int send_peers(const Group_Chats *g_c, const Group_c *g, int fri } if (g->title_len > 0) { - VLA(uint8_t, title_packet, 1 + g->title_len); + const uint32_t title_packet_size = 1 + g->title_len; + VLA(uint8_t, title_packet, title_packet_size); title_packet[0] = PEER_TITLE_ID; memcpy(title_packet + 1, g->title, g->title_len); - send_packet_group_peer(g_c->fr_c, friendcon_id, PACKET_ID_DIRECT_CONFERENCE, group_num, title_packet, - SIZEOF_VLA(title_packet)); + send_packet_group_peer(g_c->fr_c, friendcon_id, PACKET_ID_DIRECT_CONFERENCE, group_num, + title_packet, title_packet_size); } return sent; @@ -2554,13 +2547,11 @@ static void handle_direct_packet(Group_Chats *g_c, uint32_t groupnumber, const u break; } - case PEER_RESPONSE_ID: { handle_send_peers(g_c, groupnumber, data + 1, length - 1, userdata); break; } - case PEER_TITLE_ID: { if (!g->title_fresh) { settitle(g_c, groupnumber, -1, data + 1, length - 1, userdata); @@ -2696,7 +2687,8 @@ static int send_message_group(const Group_Chats *g_c, uint32_t groupnumber, uint return -3; } - VLA(uint8_t, packet, sizeof(uint16_t) + sizeof(uint32_t) + 1 + len); + const uint16_t packet_size = sizeof(uint16_t) + sizeof(uint32_t) + 1 + len; + VLA(uint8_t, packet, packet_size); const uint16_t peer_num = net_htons(g->peer_number); memcpy(packet, &peer_num, sizeof(peer_num)); @@ -2715,7 +2707,7 @@ static int send_message_group(const Group_Chats *g_c, uint32_t groupnumber, uint memcpy(packet + sizeof(uint16_t) + sizeof(uint32_t) + 1, data, len); } - const unsigned int ret = send_message_all_connections(g_c, g, packet, SIZEOF_VLA(packet), -1); + const unsigned int ret = send_message_all_connections(g_c, g, packet, packet_size, -1); if (ret == 0) { return -4; @@ -2768,14 +2760,15 @@ int send_group_lossy_packet(const Group_Chats *g_c, uint32_t groupnumber, const return -1; } - VLA(uint8_t, packet, sizeof(uint16_t) * 2 + length); + const uint16_t packet_size = sizeof(uint16_t) * 2 + length; + VLA(uint8_t, packet, packet_size); const uint16_t peer_number = net_htons(g->peer_number); memcpy(packet, &peer_number, sizeof(uint16_t)); const uint16_t message_num = net_htons(g->lossy_message_number); memcpy(packet + sizeof(uint16_t), &message_num, sizeof(uint16_t)); memcpy(packet + sizeof(uint16_t) * 2, data, length); - if (send_lossy_all_connections(g_c, g, packet, SIZEOF_VLA(packet), -1) == 0) { + if (send_lossy_all_connections(g_c, g, packet, packet_size, -1) == 0) { return -1; } @@ -3758,7 +3751,6 @@ bool conferences_load_state_section(Group_Chats *g_c, const uint8_t *data, uint3 return true; } - /** Create new groupchat instance. */ Group_Chats *new_groupchats(const Mono_Time *mono_time, Messenger *m) { diff --git a/toxcore/group.h b/toxcore/group.h index e6f6c447..5ce03275 100644 --- a/toxcore/group.h +++ b/toxcore/group.h @@ -9,7 +9,14 @@ #ifndef C_TOXCORE_TOXCORE_GROUP_H #define C_TOXCORE_TOXCORE_GROUP_H +#include +#include + #include "Messenger.h" +#include "attributes.h" +#include "crypto_core.h" +#include "mono_time.h" +#include "state.h" typedef enum Groupchat_Type { GROUPCHAT_TYPE_TEXT, @@ -72,7 +79,6 @@ void g_callback_group_connected(Group_Chats *g_c, g_conference_connected_cb *fun non_null() void g_callback_group_message(Group_Chats *g_c, g_conference_message_cb *function); - /** Set callback function for title changes. */ non_null() void g_callback_group_title(Group_Chats *g_c, title_cb *function); @@ -217,7 +223,6 @@ int group_action_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8_ non_null() int group_title_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t *title, uint8_t title_len); - /** @brief return the group's title size. * @retval -1 of groupnumber is invalid. * @retval -2 if title is too long or empty. @@ -395,4 +400,4 @@ void do_groupchats(Group_Chats *g_c, void *userdata); nullable(1) void kill_groupchats(Group_Chats *g_c); -#endif +#endif /* C_TOXCORE_TOXCORE_GROUP_H */ diff --git a/toxcore/group_announce.c b/toxcore/group_announce.c index 0aa704ae..ee083198 100644 --- a/toxcore/group_announce.c +++ b/toxcore/group_announce.c @@ -9,7 +9,9 @@ #include #include "DHT.h" +#include "attributes.h" #include "ccompat.h" +#include "crypto_core.h" #include "logger.h" #include "mono_time.h" #include "network.h" @@ -76,7 +78,7 @@ int gca_get_announces(const GC_Announces_List *gc_announces_list, GC_Announce *g for (size_t i = 0; i < announces->index && i < GCA_MAX_SAVED_ANNOUNCES_PER_GC && added_count < max_nodes; ++i) { const size_t index = i % GCA_MAX_SAVED_ANNOUNCES_PER_GC; - if (memcmp(except_public_key, &announces->peer_announces[index].base_announce.peer_public_key, + if (memcmp(except_public_key, announces->peer_announces[index].base_announce.peer_public_key, ENC_PUBLIC_KEY_SIZE) == 0) { continue; } @@ -84,7 +86,7 @@ int gca_get_announces(const GC_Announces_List *gc_announces_list, GC_Announce *g bool already_added = false; for (size_t j = 0; j < added_count; ++j) { - if (memcmp(&gc_announces[j].peer_public_key, &announces->peer_announces[index].base_announce.peer_public_key, + if (memcmp(gc_announces[j].peer_public_key, announces->peer_announces[index].base_announce.peer_public_key, ENC_PUBLIC_KEY_SIZE) == 0) { already_added = true; break; @@ -341,8 +343,8 @@ int gca_unpack_announces_list(const Logger *log, const uint8_t *data, uint16_t l non_null() static GC_Announces *gca_new_announces( - GC_Announces_List *gc_announces_list, - const GC_Public_Announce *public_announce) + GC_Announces_List *gc_announces_list, + const GC_Public_Announce *public_announce) { GC_Announces *announces = (GC_Announces *)calloc(1, sizeof(GC_Announces)); diff --git a/toxcore/group_announce.h b/toxcore/group_announce.h index 19ca2985..72f2cfc1 100644 --- a/toxcore/group_announce.h +++ b/toxcore/group_announce.h @@ -10,8 +10,14 @@ #define C_TOXCORE_TOXCORE_GROUP_ANNOUNCE_H #include +#include #include "DHT.h" +#include "attributes.h" +#include "crypto_core.h" +#include "logger.h" +#include "mono_time.h" +#include "network.h" #ifdef __cplusplus extern "C" { @@ -77,7 +83,6 @@ struct GC_Announces_List { uint64_t last_timeout_check; }; - /** @brief Returns a new group announces list. * * The caller is responsible for freeing the memory with `kill_gca`. @@ -212,7 +217,7 @@ non_null() bool gca_is_valid_announce(const GC_Announce *announce); #ifdef __cplusplus -} // extern "C" +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_GROUP_ANNOUNCE_H +#endif /* C_TOXCORE_TOXCORE_GROUP_ANNOUNCE_H */ diff --git a/toxcore/group_announce_fuzz_test.cc b/toxcore/group_announce_fuzz_test.cc index eba5e877..eb0dfb62 100644 --- a/toxcore/group_announce_fuzz_test.cc +++ b/toxcore/group_announce_fuzz_test.cc @@ -5,7 +5,7 @@ #include #include -#include "../testing/fuzzing/fuzz_support.h" +#include "../testing/fuzzing/fuzz_support.hh" #include "mem_test_util.hh" namespace { diff --git a/toxcore/group_announce_test.cc b/toxcore/group_announce_test.cc index 89452672..2918dc76 100644 --- a/toxcore/group_announce_test.cc +++ b/toxcore/group_announce_test.cc @@ -2,8 +2,12 @@ #include +#include "DHT.h" +#include "crypto_core.h" +#include "logger.h" #include "mem_test_util.hh" #include "mono_time.h" +#include "network.h" namespace { diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index 6ea64ba6..03077d08 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c @@ -18,6 +18,7 @@ #include "DHT.h" #include "Messenger.h" #include "TCP_connection.h" +#include "attributes.h" #include "bin_pack.h" #include "bin_unpack.h" #include "ccompat.h" @@ -176,6 +177,35 @@ non_null() static bool saved_peer_is_valid(const GC_SavedPeerInfo *saved_peer); static const GC_Chat empty_gc_chat = {nullptr}; +#define GC_INVALID_PEER_ID_VALUE ((force GC_Peer_Id_Value)-1) + +static GC_Peer_Id gc_invalid_peer_id(void) +{ + const GC_Peer_Id invalid = {GC_INVALID_PEER_ID_VALUE}; + return invalid; +} + +static bool gc_peer_id_is_valid(GC_Peer_Id peer_id) +{ + return peer_id.value != GC_INVALID_PEER_ID_VALUE; +} + +GC_Peer_Id gc_peer_id_from_int(uint32_t value) +{ + const GC_Peer_Id peer_id = {(force GC_Peer_Id_Value)value}; + return peer_id; +} + +uint32_t gc_peer_id_to_int(GC_Peer_Id peer_id) +{ + return (force uint32_t)peer_id.value; +} + +static GC_Peer_Id gc_unknown_peer_id(void) +{ + return gc_peer_id_from_int(0); +} + non_null() static void kill_group_friend_connection(const GC_Session *c, const GC_Chat *chat) { @@ -328,7 +358,7 @@ static void self_gc_set_status(const GC_Chat *chat, Group_Peer_Status status) LOGGER_WARNING(chat->log, "Attempting to set user status with invalid status: %u", (uint8_t)status); } -uint32_t gc_get_self_peer_id(const GC_Chat *chat) +GC_Peer_Id gc_get_self_peer_id(const GC_Chat *chat) { const GC_Peer *peer = get_gc_peer(chat, 0); assert(peer != nullptr); @@ -356,7 +386,7 @@ static bool self_gc_is_founder(const GC_Chat *chat) void gc_get_self_public_key(const GC_Chat *chat, uint8_t *public_key) { if (public_key != nullptr) { - memcpy(public_key, chat->self_public_key, ENC_PUBLIC_KEY_SIZE); + memcpy(public_key, chat->self_public_key.enc, ENC_PUBLIC_KEY_SIZE); } } @@ -365,12 +395,12 @@ void gc_get_self_public_key(const GC_Chat *chat, uint8_t *public_key) * If `ext_public_key` is null this function has no effect. */ non_null() -static void self_gc_set_ext_public_key(const GC_Chat *chat, const uint8_t *ext_public_key) +static void self_gc_set_ext_public_key(const GC_Chat *chat, const Extended_Public_Key *ext_public_key) { if (ext_public_key != nullptr) { GC_Connection *gconn = get_gc_connection(chat, 0); assert(gconn != nullptr); - memcpy(gconn->addr.public_key, ext_public_key, EXT_PUBLIC_KEY_SIZE); + gconn->addr.public_key = *ext_public_key; } } @@ -549,7 +579,7 @@ static GC_Chat *get_chat_by_id(const GC_Session *c, const uint8_t *id) continue; } - if (memcmp(id, chat->self_public_key, ENC_PUBLIC_KEY_SIZE) == 0) { + if (memcmp(id, chat->self_public_key.enc, ENC_PUBLIC_KEY_SIZE) == 0) { return chat; } @@ -611,7 +641,7 @@ int get_peer_number_of_enc_pk(const GC_Chat *chat, const uint8_t *public_enc_key continue; } - if (memcmp(gconn->addr.public_key, public_enc_key, ENC_PUBLIC_KEY_SIZE) == 0) { + if (memcmp(gconn->addr.public_key.enc, public_enc_key, ENC_PUBLIC_KEY_SIZE) == 0) { return i; } } @@ -632,7 +662,7 @@ static int get_peer_number_of_sig_pk(const GC_Chat *chat, const uint8_t *public_ assert(gconn != nullptr); - if (memcmp(get_sig_pk(gconn->addr.public_key), public_sig_key, SIG_PUBLIC_KEY_SIZE) == 0) { + if (memcmp(get_sig_pk(&gconn->addr.public_key), public_sig_key, SIG_PUBLIC_KEY_SIZE) == 0) { return i; } } @@ -648,7 +678,7 @@ static bool gc_get_enc_pk_from_sig_pk(const GC_Chat *chat, uint8_t *public_key, assert(gconn != nullptr); - const uint8_t *full_pk = gconn->addr.public_key; + const Extended_Public_Key *full_pk = &gconn->addr.public_key; if (memcmp(public_sig_key, get_sig_pk(full_pk), SIG_PUBLIC_KEY_SIZE) == 0) { memcpy(public_key, get_enc_key(full_pk), ENC_PUBLIC_KEY_SIZE); @@ -688,10 +718,10 @@ static GC_Connection *random_gc_connection(const GC_Chat *chat) * Returns -1 if peer_id is invalid. */ non_null() -static int get_peer_number_of_peer_id(const GC_Chat *chat, uint32_t peer_id) +static int get_peer_number_of_peer_id(const GC_Chat *chat, GC_Peer_Id peer_id) { for (uint32_t i = 0; i < chat->numpeers; ++i) { - if (chat->group[i].peer_id == peer_id) { + if (chat->group[i].peer_id.value == peer_id.value) { return i; } } @@ -706,15 +736,16 @@ static int get_peer_number_of_peer_id(const GC_Chat *chat, uint32_t peer_id) * considered arbitrary values. */ non_null() -static uint32_t get_new_peer_id(const GC_Chat *chat) +static GC_Peer_Id get_new_peer_id(const GC_Chat *chat) { for (uint32_t i = 0; i < UINT32_MAX - 1; ++i) { - if (get_peer_number_of_peer_id(chat, i) == -1) { - return i; + const GC_Peer_Id peer_id = gc_peer_id_from_int(i); + if (get_peer_number_of_peer_id(chat, peer_id) == -1) { + return peer_id; } } - return UINT32_MAX; + return gc_invalid_peer_id(); } /** @brief Sets the password for the group (locally only). @@ -730,7 +761,7 @@ static bool set_gc_password_local(GC_Chat *chat, const uint8_t *passwd, uint16_t if (passwd == nullptr || length == 0) { chat->shared_state.password_length = 0; - memset(chat->shared_state.password, 0, MAX_GC_PASSWORD_SIZE); + memzero(chat->shared_state.password, MAX_GC_PASSWORD_SIZE); } else { chat->shared_state.password_length = length; crypto_memlock(chat->shared_state.password, sizeof(chat->shared_state.password)); @@ -758,12 +789,12 @@ static void set_gc_shared_state_version(GC_Chat *chat, uint32_t version) * Return true on success. */ non_null() -static bool expand_chat_id(uint8_t *dest, const uint8_t *chat_id) +static bool expand_chat_id(Extended_Public_Key *dest, const uint8_t *chat_id) { assert(dest != nullptr); - const int ret = crypto_sign_ed25519_pk_to_curve25519(dest, chat_id); - memcpy(dest + ENC_PUBLIC_KEY_SIZE, chat_id, SIG_PUBLIC_KEY_SIZE); + const int ret = crypto_sign_ed25519_pk_to_curve25519(dest->enc, chat_id); + memcpy(dest->sig, chat_id, SIG_PUBLIC_KEY_SIZE); return ret != -1; } @@ -779,7 +810,7 @@ static void copy_gc_saved_peer(const Random *rng, const GC_Connection *gconn, GC } addr->ip_port = gconn->addr.ip_port; - memcpy(addr->public_key, gconn->addr.public_key, ENC_PUBLIC_KEY_SIZE); + memcpy(addr->public_key, gconn->addr.public_key.enc, ENC_PUBLIC_KEY_SIZE); } /** Return true if `saved_peer` has either a valid IP_Port or a valid TCP relay. */ @@ -863,7 +894,7 @@ static int saved_peers_get_new_index(const GC_Chat *chat, const uint8_t *public_ non_null() static void add_gc_saved_peers(GC_Chat *chat, const GC_Connection *gconn) { - const int idx = saved_peers_get_new_index(chat, gconn->addr.public_key); + const int idx = saved_peers_get_new_index(chat, gconn->addr.public_key.enc); if (idx == -1) { return; @@ -898,7 +929,7 @@ static void refresh_gc_saved_peers(GC_Chat *chat) continue; } - if (saved_peer_index(chat, gconn->addr.public_key) == -1) { + if (saved_peer_index(chat, gconn->addr.public_key.enc) == -1) { GC_SavedPeerInfo *saved_peer = &chat->saved_peers[idx]; copy_gc_saved_peer(chat->rng, gconn, saved_peer); return; @@ -930,7 +961,7 @@ non_null() static bool broadcast_gc_mod_list(const GC_Chat *chat); non_null() static bool broadcast_gc_shared_state(const GC_Chat *chat); non_null() static bool update_gc_sanctions_list(GC_Chat *chat, const uint8_t *public_sig_key); non_null() static bool update_gc_topic(GC_Chat *chat, const uint8_t *public_sig_key); -non_null() static bool send_gc_set_observer(const GC_Chat *chat, const uint8_t *target_ext_pk, +non_null() static bool send_gc_set_observer(const GC_Chat *chat, const Extended_Public_Key *target_ext_pk, const uint8_t *sanction_data, uint16_t length, bool add_obs); /** Returns true if peer designated by `peer_number` is in the sanctions list as an observer. */ @@ -943,7 +974,7 @@ static bool peer_is_observer(const GC_Chat *chat, uint32_t peer_number) return false; } - return sanctions_list_is_observer(&chat->moderation, get_enc_key(gconn->addr.public_key)); + return sanctions_list_is_observer(&chat->moderation, get_enc_key(&gconn->addr.public_key)); } /** Returns true if peer designated by `peer_number` is the group founder. */ @@ -957,7 +988,7 @@ static bool peer_is_founder(const GC_Chat *chat, uint32_t peer_number) return false; } - return memcmp(chat->shared_state.founder_public_key, gconn->addr.public_key, ENC_PUBLIC_KEY_SIZE) == 0; + return memcmp(chat->shared_state.founder_public_key.enc, gconn->addr.public_key.enc, ENC_PUBLIC_KEY_SIZE) == 0; } /** Returns true if peer designated by `peer_number` is in the moderator list or is the founder. */ @@ -974,7 +1005,7 @@ static bool peer_is_moderator(const GC_Chat *chat, uint32_t peer_number) return false; } - return mod_list_verify_sig_pk(&chat->moderation, get_sig_pk(gconn->addr.public_key)); + return mod_list_verify_sig_pk(&chat->moderation, get_sig_pk(&gconn->addr.public_key)); } /** @brief Iterates through the peerlist and updates group roles according to the @@ -1003,7 +1034,7 @@ static void update_gc_peer_roles(GC_Chat *chat) continue; } - const uint8_t first_byte = gconn->addr.public_key[0]; + const uint8_t first_byte = gconn->addr.public_key.enc[0]; const bool is_founder = peer_is_founder(chat, i); if (is_founder) { @@ -1085,43 +1116,16 @@ static bool prune_gc_mod_list(GC_Chat *chat) && update_gc_topic(chat, public_sig_key); } -/** @brief Removes the first found offline sanctioned peer from the sanctions list and sends the - * event to the rest of the group. - * - * @retval false on failure or if no presently sanctioned peer is offline. - */ non_null() -static bool prune_gc_sanctions_list(GC_Chat *chat) +static bool prune_gc_sanctions_list_inner( + GC_Chat *chat, const Mod_Sanction *sanction, + const Extended_Public_Key *target_ext_pk) { - if (chat->moderation.num_sanctions == 0) { - return true; - } - - const Mod_Sanction *sanction = nullptr; - uint8_t target_ext_pk[ENC_PUBLIC_KEY_SIZE + SIG_PUBLIC_KEY_SIZE]; - - for (uint16_t i = 0; i < chat->moderation.num_sanctions; ++i) { - const int peer_number = get_peer_number_of_enc_pk(chat, chat->moderation.sanctions[i].target_public_enc_key, true); - - if (peer_number == -1) { - sanction = &chat->moderation.sanctions[i]; - memcpy(target_ext_pk, sanction->target_public_enc_key, ENC_PUBLIC_KEY_SIZE); - memcpy(target_ext_pk + ENC_PUBLIC_KEY_SIZE, sanction->setter_public_sig_key, SIG_PUBLIC_KEY_SIZE); - break; - } - } - - if (sanction == nullptr) { - return false; - } - if (!sanctions_list_remove_observer(&chat->moderation, sanction->target_public_enc_key, nullptr)) { LOGGER_WARNING(chat->log, "Failed to remove entry from observer list"); return false; } - sanction = nullptr; - uint8_t data[MOD_SANCTIONS_CREDS_SIZE]; const uint16_t length = sanctions_creds_pack(&chat->moderation.sanctions_creds, data); @@ -1138,6 +1142,33 @@ static bool prune_gc_sanctions_list(GC_Chat *chat) return true; } +/** @brief Removes the first found offline sanctioned peer from the sanctions list and sends the + * event to the rest of the group. + * + * @retval false on failure or if no presently sanctioned peer is offline. + */ +non_null() +static bool prune_gc_sanctions_list(GC_Chat *chat) +{ + if (chat->moderation.num_sanctions == 0) { + return true; + } + + for (uint16_t i = 0; i < chat->moderation.num_sanctions; ++i) { + const int peer_number = get_peer_number_of_enc_pk(chat, chat->moderation.sanctions[i].target_public_enc_key, true); + + if (peer_number == -1) { + const Mod_Sanction *sanction = &chat->moderation.sanctions[i]; + Extended_Public_Key target_ext_pk; + memcpy(target_ext_pk.enc, sanction->target_public_enc_key, ENC_PUBLIC_KEY_SIZE); + memcpy(target_ext_pk.sig, sanction->setter_public_sig_key, SIG_PUBLIC_KEY_SIZE); + return prune_gc_sanctions_list_inner(chat, sanction, &target_ext_pk); + } + } + + return false; +} + /** @brief Size of peer data that we pack for transfer (nick length must be accounted for separately). * packed data consists of: nick length, nick, and status. */ @@ -1214,8 +1245,10 @@ static uint16_t pack_gc_shared_state(uint8_t *data, uint16_t length, const GC_Sh net_pack_u32(data + packed_len, shared_state->version); packed_len += sizeof(uint32_t); - memcpy(data + packed_len, shared_state->founder_public_key, EXT_PUBLIC_KEY_SIZE); - packed_len += EXT_PUBLIC_KEY_SIZE; + memcpy(data + packed_len, shared_state->founder_public_key.enc, ENC_PUBLIC_KEY_SIZE); + packed_len += ENC_PUBLIC_KEY_SIZE; + memcpy(data + packed_len, shared_state->founder_public_key.sig, SIG_PUBLIC_KEY_SIZE); + packed_len += SIG_PUBLIC_KEY_SIZE; net_pack_u16(data + packed_len, shared_state->maxpeers); packed_len += sizeof(uint16_t); net_pack_u16(data + packed_len, shared_state->group_name_len); @@ -1257,8 +1290,10 @@ static uint16_t unpack_gc_shared_state(GC_SharedState *shared_state, const uint8 net_unpack_u32(data + len_processed, &shared_state->version); len_processed += sizeof(uint32_t); - memcpy(shared_state->founder_public_key, data + len_processed, EXT_PUBLIC_KEY_SIZE); - len_processed += EXT_PUBLIC_KEY_SIZE; + memcpy(shared_state->founder_public_key.enc, data + len_processed, ENC_PUBLIC_KEY_SIZE); + len_processed += ENC_PUBLIC_KEY_SIZE; + memcpy(shared_state->founder_public_key.sig, data + len_processed, SIG_PUBLIC_KEY_SIZE); + len_processed += SIG_PUBLIC_KEY_SIZE; net_unpack_u16(data + len_processed, &shared_state->maxpeers); len_processed += sizeof(uint16_t); net_unpack_u16(data + len_processed, &shared_state->group_name_len); @@ -1416,7 +1451,7 @@ static bool sign_gc_shared_state(GC_Chat *chat) } const int ret = crypto_sign_detached(chat->shared_state_sig, nullptr, shared_state, packed_len, - get_sig_sk(chat->chat_secret_key)); + get_sig_sk(&chat->chat_secret_key)); if (ret != 0) { set_gc_shared_state_version(chat, chat->shared_state.version - 1); @@ -1526,7 +1561,7 @@ int group_packet_wrap( assert(padding_len < packet_size); - memset(plain, 0, padding_len); + memzero(plain, padding_len); uint16_t enc_header_len = sizeof(uint8_t); plain[padding_len] = gp_packet_type; @@ -1599,7 +1634,7 @@ static bool send_lossy_group_packet(const GC_Chat *chat, const GC_Connection *gc } const int len = group_packet_wrap( - chat->log, chat->rng, chat->self_public_key, gconn->session_shared_key, packet, + chat->log, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet, packet_size, data, length, 0, packet_type, NET_PACKET_GC_LOSSY); if (len < 0) { @@ -1699,7 +1734,7 @@ static bool unpack_gc_sync_announce(GC_Chat *chat, const uint8_t *data, const ui return false; } - if (memcmp(announce.peer_public_key, chat->self_public_key, ENC_PUBLIC_KEY_SIZE) == 0) { + if (memcmp(announce.peer_public_key, chat->self_public_key.enc, ENC_PUBLIC_KEY_SIZE) == 0) { LOGGER_WARNING(chat->log, "Attempted to unpack our own announce"); return true; } @@ -1768,7 +1803,7 @@ static bool unpack_gc_sync_announce(GC_Chat *chat, const uint8_t *data, const ui * Return -1 if the group is full or the peer failed to unpack. * Return -2 if `peer_number` does not designate a valid peer. */ -non_null(1, 2, 4) nullable(6) +non_null(1, 2) nullable(4, 6) static int handle_gc_sync_response(const GC_Session *c, GC_Chat *chat, uint32_t peer_number, const uint8_t *data, uint16_t length, void *userdata) { @@ -1809,7 +1844,6 @@ non_null() static bool send_peer_mod_list(const GC_Chat *chat, GC_Connection *gc non_null() static bool send_peer_sanctions_list(const GC_Chat *chat, GC_Connection *gconn); non_null() static bool send_peer_topic(const GC_Chat *chat, GC_Connection *gconn); - /** @brief Creates a sync announce for peer designated by `gconn` and puts it in `announce`, which * must be zeroed by the caller. * @@ -2023,7 +2057,6 @@ static int handle_gc_sync_request(GC_Chat *chat, uint32_t peer_number, const uin non_null() static void copy_self(const GC_Chat *chat, GC_Peer *peer); non_null() static bool send_gc_peer_info_request(const GC_Chat *chat, GC_Connection *gconn); - /** @brief Shares our TCP relays with peer and adds shared relays to our connection with them. * * Returns true on success or if we're not connected to any TCP relays. @@ -2212,7 +2245,7 @@ static bool send_gc_invite_response_reject(const GC_Chat *chat, const GC_Connect * Return -3 if we fail to send an invite response. * Return -4 if peer_number does not designate a valid peer. */ -non_null() +non_null(1) nullable(3) static int handle_gc_invite_request(GC_Chat *chat, uint32_t peer_number, const uint8_t *data, uint16_t length) { if (chat->shared_state.version == 0) { // we aren't synced yet; ignore request @@ -2492,8 +2525,7 @@ static int handle_gc_ping(GC_Chat *chat, GC_Connection *gconn, const uint8_t *da do_gc_peer_state_sync(chat, gconn, data, length); if (length > GC_PING_PACKET_MIN_DATA_SIZE) { - IP_Port ip_port; - memset(&ip_port, 0, sizeof(IP_Port)); + IP_Port ip_port = {{{0}}}; if (unpack_ip_port(&ip_port, data + GC_PING_PACKET_MIN_DATA_SIZE, length - GC_PING_PACKET_MIN_DATA_SIZE, false) > 0) { @@ -2555,7 +2587,7 @@ static int handle_gc_status(const GC_Session *c, const GC_Chat *chat, GC_Peer *p return 0; } -uint8_t gc_get_status(const GC_Chat *chat, uint32_t peer_id) +uint8_t gc_get_status(const GC_Chat *chat, GC_Peer_Id peer_id) { const int peer_number = get_peer_number_of_peer_id(chat, peer_id); @@ -2568,7 +2600,7 @@ uint8_t gc_get_status(const GC_Chat *chat, uint32_t peer_id) return peer->status; } -uint8_t gc_get_role(const GC_Chat *chat, uint32_t peer_id) +uint8_t gc_get_role(const GC_Chat *chat, GC_Peer_Id peer_id) { const int peer_number = get_peer_number_of_peer_id(chat, peer_id); @@ -2584,7 +2616,7 @@ uint8_t gc_get_role(const GC_Chat *chat, uint32_t peer_id) void gc_get_chat_id(const GC_Chat *chat, uint8_t *dest) { if (dest != nullptr) { - memcpy(dest, get_chat_id(chat->chat_public_key), CHAT_ID_SIZE); + memcpy(dest, get_chat_id(&chat->chat_public_key), CHAT_ID_SIZE); } } @@ -2840,7 +2872,7 @@ static void do_privacy_state_change(const GC_Session *c, GC_Chat *chat, void *us } } else { kill_group_friend_connection(c, chat); - cleanup_gca(c->announces_list, get_chat_id(chat->chat_public_key)); + cleanup_gca(c->announces_list, get_chat_id(&chat->chat_public_key)); chat->join_type = HJ_PRIVATE; } @@ -2964,7 +2996,7 @@ static int handle_gc_shared_state(const GC_Session *c, GC_Chat *chat, GC_Connect const uint16_t ss_length = length - SIGNATURE_SIZE; if (crypto_sign_verify_detached(signature, ss_data, GC_PACKED_SHARED_STATE_SIZE, - get_sig_pk(chat->chat_public_key)) == -1) { + get_sig_pk(&chat->chat_public_key)) == -1) { LOGGER_DEBUG(chat->log, "Failed to validate shared state signature"); return handle_gc_shared_state_error(chat, gconn); } @@ -2978,7 +3010,7 @@ static int handle_gc_shared_state(const GC_Session *c, GC_Chat *chat, GC_Connect return 0; } - GC_SharedState old_shared_state = chat->shared_state; + const GC_SharedState old_shared_state = chat->shared_state; GC_SharedState new_shared_state; if (unpack_gc_shared_state(&new_shared_state, ss_data, ss_length) == 0) { @@ -2993,7 +3025,7 @@ static int handle_gc_shared_state(const GC_Session *c, GC_Chat *chat, GC_Connect if (chat->shared_state.version == 0) { // init founder public sig key in moderation object memcpy(chat->moderation.founder_public_sig_key, - get_sig_pk(new_shared_state.founder_public_key), SIG_PUBLIC_KEY_SIZE); + get_sig_pk(&new_shared_state.founder_public_key), SIG_PUBLIC_KEY_SIZE); } chat->shared_state = new_shared_state; @@ -3071,7 +3103,7 @@ static int handle_gc_mod_list(const GC_Session *c, GC_Chat *chat, const uint8_t update_gc_peer_roles(chat); if (chat->connection_state == CS_CONNECTED && c->moderation != nullptr) { - c->moderation(c->messenger, chat->group_number, (uint32_t) -1, (uint32_t) -1, MV_MOD, userdata); + c->moderation(c->messenger, chat->group_number, gc_invalid_peer_id(), gc_invalid_peer_id(), MV_MOD, userdata); } return 0; @@ -3192,7 +3224,7 @@ static int handle_gc_sanctions_list(const GC_Session *c, GC_Chat *chat, const ui if (chat->connection_state == CS_CONNECTED) { if (c->moderation != nullptr) { - c->moderation(c->messenger, chat->group_number, (uint32_t) -1, (uint32_t) -1, MV_OBSERVER, userdata); + c->moderation(c->messenger, chat->group_number, gc_invalid_peer_id(), gc_invalid_peer_id(), MV_OBSERVER, userdata); } } @@ -3453,7 +3485,7 @@ int gc_set_self_nick(const Messenger *m, int group_number, const uint8_t *nick, return 0; } -bool gc_get_peer_nick(const GC_Chat *chat, uint32_t peer_id, uint8_t *name) +bool gc_get_peer_nick(const GC_Chat *chat, GC_Peer_Id peer_id, uint8_t *name) { const int peer_number = get_peer_number_of_peer_id(chat, peer_id); @@ -3470,7 +3502,7 @@ bool gc_get_peer_nick(const GC_Chat *chat, uint32_t peer_id, uint8_t *name) return true; } -int gc_get_peer_nick_size(const GC_Chat *chat, uint32_t peer_id) +int gc_get_peer_nick_size(const GC_Chat *chat, GC_Peer_Id peer_id) { const int peer_number = get_peer_number_of_peer_id(chat, peer_id); @@ -3529,12 +3561,12 @@ static int get_gc_peer_public_key(const GC_Chat *chat, uint32_t peer_number, uin return -2; } - memcpy(public_key, gconn->addr.public_key, ENC_PUBLIC_KEY_SIZE); + memcpy(public_key, gconn->addr.public_key.enc, ENC_PUBLIC_KEY_SIZE); return 0; } -int gc_get_peer_public_key_by_peer_id(const GC_Chat *chat, uint32_t peer_id, uint8_t *public_key) +int gc_get_peer_public_key_by_peer_id(const GC_Chat *chat, GC_Peer_Id peer_id, uint8_t *public_key) { const int peer_number = get_peer_number_of_peer_id(chat, peer_id); @@ -3548,7 +3580,7 @@ int gc_get_peer_public_key_by_peer_id(const GC_Chat *chat, uint32_t peer_id, uin return -2; } - memcpy(public_key, gconn->addr.public_key, ENC_PUBLIC_KEY_SIZE); + memcpy(public_key, gconn->addr.public_key.enc, ENC_PUBLIC_KEY_SIZE); return 0; } @@ -3569,7 +3601,7 @@ static void get_gc_ip_ntoa(const IP_Port *ip_port, Ip_Ntoa *ip_str) } } -int gc_get_peer_ip_address_size(const GC_Chat *chat, uint32_t peer_id) +int gc_get_peer_ip_address_size(const GC_Chat *chat, GC_Peer_Id peer_id) { const int peer_number = get_peer_number_of_peer_id(chat, peer_id); const GC_Connection *gconn = get_gc_connection(chat, peer_number); @@ -3586,7 +3618,7 @@ int gc_get_peer_ip_address_size(const GC_Chat *chat, uint32_t peer_id) return ip_str.length; } -int gc_get_peer_ip_address(const GC_Chat *chat, uint32_t peer_id, uint8_t *ip_addr) +int gc_get_peer_ip_address(const GC_Chat *chat, GC_Peer_Id peer_id, uint8_t *ip_addr) { const int peer_number = get_peer_number_of_peer_id(chat, peer_id); const GC_Connection *gconn = get_gc_connection(chat, peer_number); @@ -3610,7 +3642,7 @@ int gc_get_peer_ip_address(const GC_Chat *chat, uint32_t peer_id, uint8_t *ip_ad return 0; } -unsigned int gc_get_peer_connection_status(const GC_Chat *chat, uint32_t peer_id) +unsigned int gc_get_peer_connection_status(const GC_Chat *chat, GC_Peer_Id peer_id) { const int peer_number = get_peer_number_of_peer_id(chat, peer_id); @@ -3792,10 +3824,10 @@ int gc_set_topic(GC_Chat *chat, const uint8_t *topic, uint16_t length) assert(topic != nullptr); memcpy(chat->topic_info.topic, topic, length); } else { - memset(chat->topic_info.topic, 0, sizeof(chat->topic_info.topic)); + memzero(chat->topic_info.topic, sizeof(chat->topic_info.topic)); } - memcpy(chat->topic_info.public_sig_key, get_sig_pk(chat->self_public_key), SIG_PUBLIC_KEY_SIZE); + memcpy(chat->topic_info.public_sig_key, get_sig_pk(&chat->self_public_key), SIG_PUBLIC_KEY_SIZE); chat->topic_info.checksum = get_gc_topic_checksum(&chat->topic_info); @@ -3815,7 +3847,7 @@ int gc_set_topic(GC_Chat *chat, const uint8_t *topic, uint16_t length) } if (crypto_sign_detached(chat->topic_sig, nullptr, packed_topic, packet_buf_size, - get_sig_sk(chat->self_secret_key)) == -1) { + get_sig_sk(&chat->self_secret_key)) == -1) { goto ON_ERROR; } @@ -3862,6 +3894,7 @@ static bool update_gc_topic(GC_Chat *chat, const uint8_t *public_sig_key) return true; } + LOGGER_TRACE(chat->log, "founder is re-signing topic"); return gc_set_topic(chat, chat->topic_info.topic, chat->topic_info.length) == 0; } @@ -3971,7 +4004,7 @@ static int handle_gc_topic(const GC_Session *c, GC_Chat *chat, const GC_Peer *pe if (!skip_callback && chat->connection_state == CS_CONNECTED && c->topic_change != nullptr) { const int setter_peer_number = get_peer_number_of_sig_pk(chat, topic_info.public_sig_key); - const uint32_t peer_id = setter_peer_number >= 0 ? chat->group[setter_peer_number].peer_id : 0; + const GC_Peer_Id peer_id = setter_peer_number >= 0 ? chat->group[setter_peer_number].peer_id : gc_unknown_peer_id(); c->topic_change(c->messenger, chat->group_number, peer_id, topic_info.topic, topic_info.length, userdata); } @@ -4030,6 +4063,11 @@ static int handle_gc_key_exchange(const GC_Chat *chat, GC_Connection *gconn, con memcpy(response + 1, new_session_pk, ENC_PUBLIC_KEY_SIZE); if (!send_lossless_group_packet(chat, gconn, response, sizeof(response), GP_KEY_ROTATION)) { + // Don't really care about zeroing the secret key here, because we failed, but + // we're doing it anyway for symmetry with the memzero+munlock below, where we + // really do care about it. + crypto_memzero(new_session_sk, sizeof(new_session_sk)); + crypto_memunlock(new_session_sk, sizeof(new_session_sk)); return -3; } @@ -4039,6 +4077,7 @@ static int handle_gc_key_exchange(const GC_Chat *chat, GC_Connection *gconn, con gcc_make_session_shared_key(gconn, sender_public_session_key); + crypto_memzero(new_session_sk, sizeof(new_session_sk)); crypto_memunlock(new_session_sk, sizeof(new_session_sk)); gconn->last_key_rotation = mono_time_get(chat->mono_time); @@ -4227,7 +4266,7 @@ static bool send_gc_set_mod(const GC_Chat *chat, const GC_Connection *gconn, boo net_pack_bool(&data[0], add_mod); - memcpy(data + 1, get_sig_pk(gconn->addr.public_key), SIG_PUBLIC_KEY_SIZE); + memcpy(data + 1, get_sig_pk(&gconn->addr.public_key), SIG_PUBLIC_KEY_SIZE); if (!send_gc_broadcast_message(chat, data, length, GM_SET_MOD)) { free(data); @@ -4259,16 +4298,16 @@ static bool founder_gc_set_moderator(GC_Chat *chat, const GC_Connection *gconn, } } - if (!mod_list_add_entry(&chat->moderation, get_sig_pk(gconn->addr.public_key))) { + if (!mod_list_add_entry(&chat->moderation, get_sig_pk(&gconn->addr.public_key))) { return false; } } else { - if (!mod_list_remove_entry(&chat->moderation, get_sig_pk(gconn->addr.public_key))) { + if (!mod_list_remove_entry(&chat->moderation, get_sig_pk(&gconn->addr.public_key))) { return false; } - if (!update_gc_sanctions_list(chat, get_sig_pk(gconn->addr.public_key)) - || !update_gc_topic(chat, get_sig_pk(gconn->addr.public_key))) { + if (!update_gc_sanctions_list(chat, get_sig_pk(&gconn->addr.public_key)) + || !update_gc_topic(chat, get_sig_pk(&gconn->addr.public_key))) { return false; } } @@ -4397,7 +4436,6 @@ static int handle_gc_set_observer(const GC_Session *c, GC_Chat *chat, uint32_t p return -2; } - if (ret == 1) { return 0; } @@ -4419,10 +4457,10 @@ static int handle_gc_set_observer(const GC_Session *c, GC_Chat *chat, uint32_t p * Returns true on success. */ non_null() -static bool send_gc_set_observer(const GC_Chat *chat, const uint8_t *target_ext_pk, const uint8_t *sanction_data, - uint16_t length, bool add_obs) +static bool send_gc_set_observer(const GC_Chat *chat, const Extended_Public_Key *target_ext_pk, + const uint8_t *sanction_data, uint16_t length, bool add_obs) { - const uint16_t packet_len = 1 + EXT_PUBLIC_KEY_SIZE + length; + const uint16_t packet_len = 1 + ENC_PUBLIC_KEY_SIZE + SIG_PUBLIC_KEY_SIZE + length; uint8_t *packet = (uint8_t *)malloc(packet_len); if (packet == nullptr) { @@ -4431,8 +4469,9 @@ static bool send_gc_set_observer(const GC_Chat *chat, const uint8_t *target_ext_ net_pack_bool(&packet[0], add_obs); - memcpy(packet + 1, target_ext_pk, EXT_PUBLIC_KEY_SIZE); - memcpy(packet + 1 + EXT_PUBLIC_KEY_SIZE, sanction_data, length); + memcpy(packet + 1, target_ext_pk->enc, ENC_PUBLIC_KEY_SIZE); + memcpy(packet + 1 + ENC_PUBLIC_KEY_SIZE, target_ext_pk->sig, SIG_PUBLIC_KEY_SIZE); + memcpy(packet + 1 + ENC_PUBLIC_KEY_SIZE + SIG_PUBLIC_KEY_SIZE, sanction_data, length); if (!send_gc_broadcast_message(chat, packet, packet_len, GM_SET_OBSERVER)) { free(packet); @@ -4484,7 +4523,7 @@ static bool mod_gc_set_observer(GC_Chat *chat, uint32_t peer_number, bool add_ob Mod_Sanction sanction; - if (!sanctions_list_make_entry(&chat->moderation, gconn->addr.public_key, &sanction, SA_OBSERVER)) { + if (!sanctions_list_make_entry(&chat->moderation, gconn->addr.public_key.enc, &sanction, SA_OBSERVER)) { LOGGER_WARNING(chat->log, "sanctions_list_make_entry failed in mod_gc_set_observer"); return false; } @@ -4498,7 +4537,7 @@ static bool mod_gc_set_observer(GC_Chat *chat, uint32_t peer_number, bool add_ob length += packed_len; } else { - if (!sanctions_list_remove_observer(&chat->moderation, gconn->addr.public_key, nullptr)) { + if (!sanctions_list_remove_observer(&chat->moderation, gconn->addr.public_key.enc, nullptr)) { LOGGER_WARNING(chat->log, "failed to remove sanction"); return false; } @@ -4519,7 +4558,7 @@ static bool mod_gc_set_observer(GC_Chat *chat, uint32_t peer_number, bool add_ob update_gc_peer_roles(chat); - return send_gc_set_observer(chat, gconn->addr.public_key, sanction_data, length, add_obs); + return send_gc_set_observer(chat, &gconn->addr.public_key, sanction_data, length, add_obs); } /** @brief Sets the role of `peer_number` to `new_role`. If necessary this function will first @@ -4586,7 +4625,7 @@ static bool apply_new_gc_role(GC_Chat *chat, uint32_t peer_number, Group_Role cu return true; } -int gc_set_peer_role(const Messenger *m, int group_number, uint32_t peer_id, Group_Role new_role) +int gc_set_peer_role(const Messenger *m, int group_number, GC_Peer_Id peer_id, Group_Role new_role) { const GC_Session *c = m->group_handler; GC_Chat *chat = gc_get_group(c, group_number); @@ -4782,7 +4821,7 @@ int gc_founder_set_privacy_state(const Messenger *m, int group_number, Group_Pri } if (new_privacy_state == GI_PRIVATE) { - cleanup_gca(c->announces_list, get_chat_id(chat->chat_public_key)); + cleanup_gca(c->announces_list, get_chat_id(&chat->chat_public_key)); kill_group_friend_connection(c, chat); chat->join_type = HJ_PRIVATE; } else { @@ -4872,11 +4911,12 @@ int gc_send_message(const GC_Chat *chat, const uint8_t *message, uint16_t length return -5; } + free(message_raw); + if (message_id != nullptr) { *message_id = pseudo_msg_id; } - free(message_raw); return 0; } @@ -4915,8 +4955,8 @@ static int handle_gc_message(const GC_Session *c, const GC_Chat *chat, const GC_ return 0; } -int gc_send_private_message(const GC_Chat *chat, uint32_t peer_id, uint8_t type, const uint8_t *message, - uint16_t length) +int gc_send_private_message(const GC_Chat *chat, GC_Peer_Id peer_id, uint8_t type, const uint8_t *message, + uint16_t length, uint32_t *message_id) { if (length > MAX_GC_MESSAGE_SIZE) { return -1; @@ -4942,23 +4982,28 @@ int gc_send_private_message(const GC_Chat *chat, uint32_t peer_id, uint8_t type, return -5; } - uint8_t *message_with_type = (uint8_t *)malloc(length + 1); + const uint16_t raw_length = 1 + length + GC_MESSAGE_PSEUDO_ID_SIZE; + uint8_t *message_with_type = (uint8_t *)malloc(raw_length); if (message_with_type == nullptr) { return -6; } message_with_type[0] = type; - memcpy(message_with_type + 1, message, length); - uint8_t *packet = (uint8_t *)malloc(length + 1 + GC_BROADCAST_ENC_HEADER_SIZE); + const uint32_t pseudo_msg_id = random_u32(chat->rng); + net_pack_u32(message_with_type + 1, pseudo_msg_id); + + memcpy(message_with_type + 1 + GC_MESSAGE_PSEUDO_ID_SIZE, message, length); + + uint8_t *packet = (uint8_t *)malloc(raw_length + GC_BROADCAST_ENC_HEADER_SIZE); if (packet == nullptr) { free(message_with_type); return -6; } - const uint16_t packet_len = make_gc_broadcast_header(message_with_type, length + 1, packet, GM_PRIVATE_MESSAGE); + const uint16_t packet_len = make_gc_broadcast_header(message_with_type, raw_length, packet, GM_PRIVATE_MESSAGE); free(message_with_type); @@ -4969,6 +5014,10 @@ int gc_send_private_message(const GC_Chat *chat, uint32_t peer_id, uint8_t type, free(packet); + if (message_id != nullptr) { + *message_id = pseudo_msg_id; + } + return 0; } @@ -4981,7 +5030,7 @@ non_null(1, 2, 3, 4) nullable(6) static int handle_gc_private_message(const GC_Session *c, const GC_Chat *chat, const GC_Peer *peer, const uint8_t *data, uint16_t length, void *userdata) { - if (data == nullptr || length > MAX_GC_MESSAGE_SIZE || length <= 1) { + if (data == nullptr || length > MAX_GC_MESSAGE_SIZE || length <= 1 + GC_MESSAGE_PSEUDO_ID_SIZE) { return -1; } @@ -4996,8 +5045,13 @@ static int handle_gc_private_message(const GC_Session *c, const GC_Chat *chat, c return 0; } + uint32_t message_id; + net_unpack_u32(data + 1, &message_id); + if (c->private_message != nullptr) { - c->private_message(c->messenger, chat->group_number, peer->peer_id, message_type, data + 1, length - 1, userdata); + c->private_message(c->messenger, chat->group_number, peer->peer_id, message_type, + data + 1 + GC_MESSAGE_PSEUDO_ID_SIZE, length - 1 - GC_MESSAGE_PSEUDO_ID_SIZE, + message_id, userdata); } return 0; @@ -5006,20 +5060,10 @@ static int handle_gc_private_message(const GC_Session *c, const GC_Chat *chat, c /** @brief Returns false if a custom packet is too large. */ static bool custom_gc_packet_length_is_valid(uint16_t length, bool lossless) { - if (lossless) { - if (length > MAX_GC_CUSTOM_LOSSLESS_PACKET_SIZE) { - return false; - } - } else { - if (length > MAX_GC_CUSTOM_LOSSY_PACKET_SIZE) { - return false; - } - } - - return true; + return length <= (lossless ? MAX_GC_CUSTOM_LOSSLESS_PACKET_SIZE : MAX_GC_CUSTOM_LOSSY_PACKET_SIZE); } -int gc_send_custom_private_packet(const GC_Chat *chat, bool lossless, uint32_t peer_id, const uint8_t *message, +int gc_send_custom_private_packet(const GC_Chat *chat, bool lossless, GC_Peer_Id peer_id, const uint8_t *message, uint16_t length) { if (!custom_gc_packet_length_is_valid(length, lossless)) { @@ -5038,10 +5082,6 @@ int gc_send_custom_private_packet(const GC_Chat *chat, bool lossless, uint32_t p return -3; } - if (gc_get_self_role(chat) >= GR_OBSERVER) { - return -4; - } - bool ret; if (lossless) { @@ -5050,11 +5090,9 @@ int gc_send_custom_private_packet(const GC_Chat *chat, bool lossless, uint32_t p ret = send_lossy_group_packet(chat, gconn, message, length, GP_CUSTOM_PRIVATE_PACKET); } - return ret ? 0 : -5; + return ret ? 0 : -4; } - - /** @brief Handles a custom private packet. * * @retval 0 if packet is handled correctly. @@ -5072,10 +5110,6 @@ static int handle_gc_custom_private_packet(const GC_Session *c, const GC_Chat *c return -1; } - if (peer->ignore || peer->role >= GR_OBSERVER) { - return 0; - } - if (c->custom_private_packet != nullptr) { c->custom_private_packet(c->messenger, chat->group_number, peer->peer_id, data, length, userdata); } @@ -5093,10 +5127,6 @@ int gc_send_custom_packet(const GC_Chat *chat, bool lossless, const uint8_t *dat return -2; } - if (gc_get_self_role(chat) >= GR_OBSERVER) { - return -3; - } - bool success; if (lossless) { @@ -5105,7 +5135,7 @@ int gc_send_custom_packet(const GC_Chat *chat, bool lossless, const uint8_t *dat success = send_gc_lossy_packet_all_peers(chat, data, length, GP_CUSTOM_PACKET); } - return success ? 0 : -4; + return success ? 0 : -3; } /** @brief Handles a custom packet. @@ -5125,10 +5155,6 @@ static int handle_gc_custom_packet(const GC_Session *c, const GC_Chat *chat, con return -1; } - if (peer->ignore || peer->role >= GR_OBSERVER) { - return 0; - } - if (c->custom_packet != nullptr) { c->custom_packet(c->messenger, chat->group_number, peer->peer_id, data, length, userdata); } @@ -5205,12 +5231,12 @@ non_null() static bool send_gc_kick_peer(const GC_Chat *chat, const GC_Connection *gconn) { uint8_t packet[ENC_PUBLIC_KEY_SIZE]; - memcpy(packet, gconn->addr.public_key, ENC_PUBLIC_KEY_SIZE); + memcpy(packet, gconn->addr.public_key.enc, ENC_PUBLIC_KEY_SIZE); return send_gc_broadcast_message(chat, packet, ENC_PUBLIC_KEY_SIZE, GM_KICK_PEER); } -int gc_kick_peer(const Messenger *m, int group_number, uint32_t peer_id) +int gc_kick_peer(const Messenger *m, int group_number, GC_Peer_Id peer_id) { const GC_Session *c = m->group_handler; GC_Chat *chat = gc_get_group(c, group_number); @@ -5362,7 +5388,7 @@ static int handle_gc_hs_response_ack(const GC_Chat *chat, GC_Connection *gconn) return 0; } -int gc_set_ignore(const GC_Chat *chat, uint32_t peer_id, bool ignore) +int gc_set_ignore(const GC_Chat *chat, GC_Peer_Id peer_id, bool ignore) { const int peer_number = get_peer_number_of_peer_id(chat, peer_id); @@ -5564,12 +5590,12 @@ static int make_gc_handshake_packet(const GC_Chat *chat, const GC_Connection *gc uint8_t request_type, uint8_t join_type, uint8_t *packet, size_t packet_size, const Node_format *node) { - if (packet_size != GC_MIN_ENCRYPTED_HS_PAYLOAD_SIZE + sizeof(Node_format)) { - LOGGER_FATAL(chat->log, "invalid packet size: %zu", packet_size); + if (chat == nullptr || gconn == nullptr || node == nullptr) { return -1; } - if (chat == nullptr || gconn == nullptr || node == nullptr) { + if (packet_size != GC_MIN_ENCRYPTED_HS_PAYLOAD_SIZE + sizeof(Node_format)) { + LOGGER_FATAL(chat->log, "invalid packet size: %zu", packet_size); return -1; } @@ -5580,7 +5606,7 @@ static int make_gc_handshake_packet(const GC_Chat *chat, const GC_Connection *gc data[0] = handshake_type; memcpy(data + length, gconn->session_public_key, ENC_PUBLIC_KEY_SIZE); length += ENC_PUBLIC_KEY_SIZE; - memcpy(data + length, get_sig_pk(chat->self_public_key), SIG_PUBLIC_KEY_SIZE); + memcpy(data + length, get_sig_pk(&chat->self_public_key), SIG_PUBLIC_KEY_SIZE); length += SIG_PUBLIC_KEY_SIZE; memcpy(data + length, &request_type, sizeof(uint8_t)); length += sizeof(uint8_t); @@ -5596,8 +5622,8 @@ static int make_gc_handshake_packet(const GC_Chat *chat, const GC_Connection *gc } const int enc_len = wrap_group_handshake_packet( - chat->log, chat->rng, chat->self_public_key, chat->self_secret_key, - gconn->addr.public_key, packet, (uint16_t)packet_size, data, length); + chat->log, chat->rng, chat->self_public_key.enc, chat->self_secret_key.enc, + gconn->addr.public_key.enc, packet, (uint16_t)packet_size, data, length); if (enc_len != GC_MIN_ENCRYPTED_HS_PAYLOAD_SIZE + nodes_size) { LOGGER_WARNING(chat->log, "Failed to wrap handshake packet: %d", enc_len); @@ -5621,8 +5647,7 @@ static bool send_gc_handshake_packet(const GC_Chat *chat, GC_Connection *gconn, return false; } - Node_format node; - memset(&node, 0, sizeof(node)); + Node_format node = {{0}}; if (!gcc_copy_tcp_relay(chat->rng, &node, gconn)) { LOGGER_TRACE(chat->log, "Failed to copy TCP relay during handshake (%u TCP relays)", gconn->tcp_relays_count); @@ -5677,8 +5702,7 @@ static bool send_gc_oob_handshake_request(const GC_Chat *chat, const GC_Connecti return false; } - Node_format node; - memset(&node, 0, sizeof(node)); + Node_format node = {{0}}; if (!gcc_copy_tcp_relay(chat->rng, &node, gconn)) { LOGGER_WARNING(chat->log, "Failed to copy TCP relay"); @@ -5694,7 +5718,7 @@ static bool send_gc_oob_handshake_request(const GC_Chat *chat, const GC_Connecti return false; } - return tcp_send_oob_packet_using_relay(chat->tcp_conn, gconn->oob_relay_pk, gconn->addr.public_key, + return tcp_send_oob_packet_using_relay(chat->tcp_conn, gconn->oob_relay_pk, gconn->addr.public_key.enc, packet, (uint16_t)length) == 0; } @@ -5732,7 +5756,7 @@ static int handle_gc_handshake_response(const GC_Chat *chat, const uint8_t *send gcc_make_session_shared_key(gconn, sender_session_pk); - set_sig_pk(gconn->addr.public_key, data + ENC_PUBLIC_KEY_SIZE); + set_sig_pk(&gconn->addr.public_key, data + ENC_PUBLIC_KEY_SIZE); gcc_set_recv_message_id(gconn, 2); // handshake response is always second packet @@ -5891,7 +5915,7 @@ static int handle_gc_handshake_request(GC_Chat *chat, const IP_Port *ipp, const gcc_make_session_shared_key(gconn, sender_session_pk); - set_sig_pk(gconn->addr.public_key, public_sig_key); + set_sig_pk(&gconn->addr.public_key, public_sig_key); if (join_type == HJ_PUBLIC && !is_public_chat(chat)) { gcc_mark_for_deletion(gconn, chat->tcp_conn, GC_EXIT_TYPE_DISCONNECTED, nullptr, 0); @@ -5927,7 +5951,7 @@ static int handle_gc_handshake_packet(GC_Chat *chat, const uint8_t *sender_pk, c return -1; } - const int plain_len = unwrap_group_handshake_packet(chat->log, chat->self_secret_key, sender_pk, data, + const int plain_len = unwrap_group_handshake_packet(chat->log, chat->self_secret_key.enc, sender_pk, data, data_buf_size, packet, length); if (plain_len < GC_MIN_HS_PACKET_PAYLOAD_SIZE) { @@ -6356,7 +6380,7 @@ static bool group_can_handle_packets(const GC_Chat *chat) */ #define MIN_TCP_PACKET_SIZE (1 + ENC_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE) non_null(1, 3) nullable(5) -static int handle_gc_tcp_packet(void *object, int id, const uint8_t *packet, uint16_t length, void *userdata) +static int handle_gc_tcp_packet(void *object, int crypt_connection_id, const uint8_t *packet, uint16_t length, void *userdata) { const Messenger *m = (Messenger *)object; @@ -6492,7 +6516,7 @@ static int handle_gc_tcp_oob_packet(void *object, const uint8_t *public_key, uns #define MIN_UDP_PACKET_SIZE (1 + ENC_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE) non_null(1, 2, 3) nullable(5) -static int handle_gc_udp_packet(void *object, const IP_Port *ipp, const uint8_t *packet, uint16_t length, +static int handle_gc_udp_packet(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { const Messenger *m = (Messenger *)object; @@ -6557,7 +6581,7 @@ static int handle_gc_udp_packet(void *object, const IP_Port *ipp, const uint8_t payload_len = payload_len - ENC_PUBLIC_KEY_SIZE; payload = payload + ENC_PUBLIC_KEY_SIZE; - ret = handle_gc_handshake_packet(chat, sender_pk, ipp, payload, payload_len, true, userdata) != -1; + ret = handle_gc_handshake_packet(chat, sender_pk, source, payload, payload_len, true, userdata) != -1; break; } @@ -6688,7 +6712,7 @@ static bool peer_delete(const GC_Session *c, GC_Chat *chat, uint32_t peer_number // We need to save some peer info for the callback before deleting it const bool peer_confirmed = peer->gconn.confirmed; - const uint32_t peer_id = peer->peer_id; + 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; @@ -6766,9 +6790,9 @@ int peer_add(GC_Chat *chat, const IP_Port *ipp, const uint8_t *public_key) return -2; } - const uint32_t peer_id = get_new_peer_id(chat); + const GC_Peer_Id peer_id = get_new_peer_id(chat); - if (peer_id == UINT32_MAX) { + if (!gc_peer_id_is_valid(peer_id)) { LOGGER_WARNING(chat->log, "Failed to add peer: all peer ID's are taken?"); return -1; } @@ -6835,9 +6859,9 @@ int peer_add(GC_Chat *chat, const IP_Port *ipp, const uint8_t *public_key) create_gc_session_keypair(chat->log, chat->rng, gconn->session_public_key, gconn->session_secret_key); if (peer_number > 0) { - memcpy(gconn->addr.public_key, public_key, ENC_PUBLIC_KEY_SIZE); // we get the sig key in the handshake + memcpy(gconn->addr.public_key.enc, public_key, ENC_PUBLIC_KEY_SIZE); // we get the sig key in the handshake } else { - memcpy(gconn->addr.public_key, chat->self_public_key, EXT_PUBLIC_KEY_SIZE); + gconn->addr.public_key = chat->self_public_key; } const uint64_t tm = mono_time_get(chat->mono_time); @@ -6849,9 +6873,9 @@ int peer_add(GC_Chat *chat, const IP_Port *ipp, const uint8_t *public_key) gconn->tcp_connection_num = tcp_connection_num; gconn->last_sent_ip_time = tm; gconn->last_sent_ping_time = tm - (GC_PING_TIMEOUT / 2) + (peer_number % (GC_PING_TIMEOUT / 2)); - gconn->self_is_closer = id_closest(get_chat_id(chat->chat_public_key), - get_enc_key(chat->self_public_key), - get_enc_key(gconn->addr.public_key)) == 1; + gconn->self_is_closer = id_closest(get_chat_id(&chat->chat_public_key), + get_enc_key(&chat->self_public_key), + get_enc_key(&gconn->addr.public_key)) == 1; return peer_number; } @@ -6995,23 +7019,30 @@ non_null(1, 2) nullable(3) static void do_peer_delete(const GC_Session *c, GC_Chat *chat, void *userdata) { for (uint32_t i = 1; i < chat->numpeers; ++i) { - const GC_Connection *gconn = get_gc_connection(chat, i); + GC_Connection *gconn = get_gc_connection(chat, i); assert(gconn != nullptr); - if (gconn->pending_delete) { - const GC_Exit_Info *exit_info = &gconn->exit_info; + if (!gconn->pending_delete) { + continue; + } - if (exit_info->exit_type == GC_EXIT_TYPE_TIMEOUT && gconn->confirmed) { - add_gc_peer_timeout_list(chat, gconn); - } + if (!gconn->delete_this_iteration) { + gconn->delete_this_iteration = true; + continue; + } - if (!peer_delete(c, chat, i, userdata)) { - LOGGER_ERROR(chat->log, "Failed to delete peer %u", i); - } + const GC_Exit_Info *exit_info = &gconn->exit_info; - if (i >= chat->numpeers) { - break; - } + if (exit_info->exit_type == GC_EXIT_TYPE_TIMEOUT && gconn->confirmed) { + add_gc_peer_timeout_list(chat, gconn); + } + + if (!peer_delete(c, chat, i, userdata)) { + LOGGER_ERROR(chat->log, "Failed to delete peer %u", i); + } + + if (i >= chat->numpeers) { + break; } } } @@ -7276,6 +7307,10 @@ void do_gc(GC_Session *c, void *userdata) do_new_connection_cooldown(chat); do_peer_delete(c, chat, userdata); + + if (chat->flag_exit) { // should always come last as it modifies the chats array + group_delete(c, chat); + } } } @@ -7323,7 +7358,7 @@ static int get_new_group_index(GC_Session *c) c->chats[new_index] = empty_gc_chat; - for (size_t i = 0; i < sizeof(c->chats[new_index].saved_invites)/sizeof(*c->chats[new_index].saved_invites); ++i) { + for (size_t i = 0; i < sizeof(c->chats[new_index].saved_invites) / sizeof(*c->chats[new_index].saved_invites); ++i) { c->chats[new_index].saved_invites[i] = -1; } @@ -7363,7 +7398,7 @@ static bool init_gc_tcp_connection(const GC_Session *c, GC_Chat *chat) { const Messenger *m = c->messenger; - chat->tcp_conn = new_tcp_connections(chat->log, chat->mem, chat->rng, m->ns, chat->mono_time, chat->self_secret_key, + chat->tcp_conn = new_tcp_connections(chat->log, chat->mem, chat->rng, m->ns, chat->mono_time, chat->self_secret_key.enc, &m->options.proxy_info); if (chat->tcp_conn == nullptr) { @@ -7396,7 +7431,7 @@ non_null() static bool init_gc_shared_state_founder(GC_Chat *chat, Group_Privacy_State privacy_state, const uint8_t *group_name, uint16_t name_length) { - memcpy(chat->shared_state.founder_public_key, chat->self_public_key, EXT_PUBLIC_KEY_SIZE); + chat->shared_state.founder_public_key = chat->self_public_key; memcpy(chat->shared_state.group_name, group_name, name_length); chat->shared_state.group_name_len = name_length; chat->shared_state.privacy_state = privacy_state; @@ -7413,9 +7448,9 @@ non_null() static void init_gc_moderation(GC_Chat *chat) { memcpy(chat->moderation.founder_public_sig_key, - get_sig_pk(chat->shared_state.founder_public_key), SIG_PUBLIC_KEY_SIZE); - memcpy(chat->moderation.self_public_sig_key, get_sig_pk(chat->self_public_key), SIG_PUBLIC_KEY_SIZE); - memcpy(chat->moderation.self_secret_sig_key, get_sig_pk(chat->self_secret_key), SIG_SECRET_KEY_SIZE); + get_sig_pk(&chat->shared_state.founder_public_key), SIG_PUBLIC_KEY_SIZE); + memcpy(chat->moderation.self_public_sig_key, get_sig_pk(&chat->self_public_key), SIG_PUBLIC_KEY_SIZE); + memcpy(chat->moderation.self_secret_sig_key, get_sig_sk(&chat->self_secret_key), SIG_SECRET_KEY_SIZE); chat->moderation.shared_state_version = chat->shared_state.version; chat->moderation.log = chat->log; chat->moderation.mem = chat->mem; @@ -7473,7 +7508,7 @@ static int create_new_group(GC_Session *c, const uint8_t *nick, size_t nick_leng return -1; } - if (peer_add(chat, nullptr, chat->self_public_key) != 0) { /* you are always peer_number/index 0 */ + if (peer_add(chat, nullptr, chat->self_public_key.enc) != 0) { /* you are always peer_number/index 0 */ group_delete(c, chat); return -1; } @@ -7486,7 +7521,7 @@ static int create_new_group(GC_Session *c, const uint8_t *nick, size_t nick_leng self_gc_set_status(chat, GS_NONE); self_gc_set_role(chat, founder ? GR_FOUNDER : GR_USER); self_gc_set_confirmed(chat, true); - self_gc_set_ext_public_key(chat, chat->self_public_key); + self_gc_set_ext_public_key(chat, &chat->self_public_key); return group_number; } @@ -7625,8 +7660,8 @@ int gc_group_load(GC_Session *c, Bin_Unpack *bu) return group_number; } -int gc_group_add(GC_Session *c, Group_Privacy_State privacy_state, const uint8_t *group_name, - uint16_t group_name_length, +int gc_group_add(GC_Session *c, Group_Privacy_State privacy_state, + const uint8_t *group_name, uint16_t group_name_length, const uint8_t *nick, size_t nick_length) { if (group_name_length > MAX_GC_GROUP_NAME_SIZE) { @@ -7657,9 +7692,9 @@ int gc_group_add(GC_Session *c, Group_Privacy_State privacy_state, const uint8_t return -3; } - crypto_memlock(chat->chat_secret_key, sizeof(chat->chat_secret_key)); + crypto_memlock(&chat->chat_secret_key, sizeof(chat->chat_secret_key)); - create_extended_keypair(chat->chat_public_key, chat->chat_secret_key); + create_extended_keypair(&chat->chat_public_key, &chat->chat_secret_key, chat->rng); if (!init_gc_shared_state_founder(chat, privacy_state, group_name, group_name_length)) { group_delete(c, chat); @@ -7724,7 +7759,7 @@ int gc_group_join(GC_Session *c, const uint8_t *chat_id, const uint8_t *nick, si return -1; } - if (!expand_chat_id(chat->chat_public_key, chat_id)) { + if (!expand_chat_id(&chat->chat_public_key, chat_id)) { group_delete(c, chat); return -1; } @@ -7834,13 +7869,12 @@ int gc_invite_friend(const GC_Session *c, GC_Chat *chat, int32_t friend_number, packet[0] = GP_FRIEND_INVITE; packet[1] = GROUP_INVITE; - memcpy(packet + 2, get_chat_id(chat->chat_public_key), CHAT_ID_SIZE); + memcpy(packet + 2, get_chat_id(&chat->chat_public_key), CHAT_ID_SIZE); uint16_t length = 2 + CHAT_ID_SIZE; - memcpy(packet + length, chat->self_public_key, ENC_PUBLIC_KEY_SIZE); + memcpy(packet + length, chat->self_public_key.enc, ENC_PUBLIC_KEY_SIZE); length += ENC_PUBLIC_KEY_SIZE; - memcpy(packet + length, chat->shared_state.group_name, group_name_length); length += group_name_length; @@ -7881,10 +7915,10 @@ static int send_gc_invite_accepted_packet(const Messenger *m, const GC_Chat *cha packet[0] = GP_FRIEND_INVITE; packet[1] = GROUP_INVITE_ACCEPTED; - memcpy(packet + 2, get_chat_id(chat->chat_public_key), CHAT_ID_SIZE); + memcpy(packet + 2, get_chat_id(&chat->chat_public_key), CHAT_ID_SIZE); uint16_t length = 2 + CHAT_ID_SIZE; - memcpy(packet + length, chat->self_public_key, ENC_PUBLIC_KEY_SIZE); + memcpy(packet + length, chat->self_public_key.enc, ENC_PUBLIC_KEY_SIZE); length += ENC_PUBLIC_KEY_SIZE; if (!send_group_invite_packet(m, friend_number, packet, length)) { @@ -8104,7 +8138,7 @@ bool handle_gc_invite_accepted_packet(const GC_Session *c, int friend_number, co uint8_t out_data[GC_JOIN_DATA_LENGTH + (GCC_MAX_TCP_SHARED_RELAYS * PACKED_NODE_SIZE_IP6)]; memcpy(out_data, chat_id, CHAT_ID_SIZE); - memcpy(out_data + CHAT_ID_SIZE, chat->self_public_key, ENC_PUBLIC_KEY_SIZE); + memcpy(out_data + CHAT_ID_SIZE, chat->self_public_key.enc, ENC_PUBLIC_KEY_SIZE); if (num_tcp_relays > 0) { const uint32_t tcp_relays_added = add_gc_tcp_relays(chat, gconn, tcp_relays, num_tcp_relays); @@ -8161,7 +8195,7 @@ int gc_accept_invite(GC_Session *c, int32_t friend_number, const uint8_t *data, return -2; } - if (!expand_chat_id(chat->chat_public_key, chat_id)) { + if (!expand_chat_id(&chat->chat_public_key, chat_id)) { group_delete(c, chat); return -2; } @@ -8233,8 +8267,8 @@ static void group_cleanup(const GC_Session *c, GC_Chat *chat) chat->group = nullptr; } - crypto_memunlock(chat->self_secret_key, sizeof(chat->self_secret_key)); - crypto_memunlock(chat->chat_secret_key, sizeof(chat->chat_secret_key)); + crypto_memunlock(&chat->self_secret_key, sizeof(chat->self_secret_key)); + crypto_memunlock(&chat->chat_secret_key, sizeof(chat->chat_secret_key)); crypto_memunlock(chat->shared_state.password, sizeof(chat->shared_state.password)); } @@ -8265,14 +8299,21 @@ static void group_delete(GC_Session *c, GC_Chat *chat) c->chats_index = i; if (!realloc_groupchats(c, c->chats_index)) { - LOGGER_ERROR(chat->log, "Failed to reallocate groupchats array"); + LOGGER_ERROR(c->messenger->log, "Failed to reallocate groupchats array"); } } } int gc_group_exit(GC_Session *c, GC_Chat *chat, const uint8_t *message, uint16_t length) { - const int ret = group_can_handle_packets(chat) ? send_gc_self_exit(chat, message, length) : 0; + chat->flag_exit = true; + return group_can_handle_packets(chat) ? send_gc_self_exit(chat, message, length) : 0; +} + +non_null() +static int kill_group(GC_Session *c, GC_Chat *chat) +{ + const int ret = gc_group_exit(c, chat, nullptr, 0); group_delete(c, chat); return ret; } @@ -8290,11 +8331,9 @@ void kill_dht_groupchats(GC_Session *c) continue; } - if (group_can_handle_packets(chat)) { - send_gc_self_exit(chat, nullptr, 0); + if (kill_group(c, chat) != 0) { + LOGGER_WARNING(c->messenger->log, "Failed to send group exit packet"); } - - group_cleanup(c, chat); } networking_registerhandler(c->messenger->net, NET_PACKET_GC_LOSSY, nullptr, nullptr); @@ -8358,7 +8397,7 @@ GC_Chat *gc_get_group_by_public_key(const GC_Session *c, const uint8_t *public_k continue; } - if (memcmp(public_key, get_chat_id(chat->chat_public_key), CHAT_ID_SIZE) == 0) { + if (memcmp(public_key, get_chat_id(&chat->chat_public_key), CHAT_ID_SIZE) == 0) { return chat; } } @@ -8376,7 +8415,7 @@ static bool group_exists(const GC_Session *c, const uint8_t *chat_id) continue; } - if (memcmp(get_chat_id(chat->chat_public_key), chat_id, CHAT_ID_SIZE) == 0) { + if (memcmp(get_chat_id(&chat->chat_public_key), chat_id, CHAT_ID_SIZE) == 0) { return true; } } @@ -8402,10 +8441,10 @@ static void create_gc_session_keypair(const Logger *log, const Random *rng, uint non_null() static bool create_new_chat_ext_keypair(GC_Chat *chat) { - crypto_memlock(chat->self_secret_key, sizeof(chat->self_secret_key)); + crypto_memlock(&chat->self_secret_key, sizeof(chat->self_secret_key)); - if (!create_extended_keypair(chat->self_public_key, chat->self_secret_key)) { - crypto_memunlock(chat->self_secret_key, sizeof(chat->self_secret_key)); + if (!create_extended_keypair(&chat->self_public_key, &chat->self_secret_key, chat->rng)) { + crypto_memunlock(&chat->self_secret_key, sizeof(chat->self_secret_key)); return false; } diff --git a/toxcore/group_chats.h b/toxcore/group_chats.h index 57ebe60b..d22ce400 100644 --- a/toxcore/group_chats.h +++ b/toxcore/group_chats.h @@ -14,12 +14,15 @@ #include #include "TCP_connection.h" +#include "attributes.h" #include "bin_pack.h" #include "bin_unpack.h" +#include "crypto_core.h" #include "group_announce.h" #include "group_common.h" #include "group_connection.h" #include "logger.h" +#include "network.h" #define GC_PING_TIMEOUT 12 #define GC_SEND_IP_PORT_INTERVAL (GC_PING_TIMEOUT * 5) @@ -178,9 +181,9 @@ int gc_send_message(const GC_Chat *chat, const uint8_t *message, uint16_t length * Returns -5 if the sender has the observer role. * Returns -6 if the packet fails to send. */ -non_null() -int gc_send_private_message(const GC_Chat *chat, uint32_t peer_id, uint8_t type, const uint8_t *message, - uint16_t length); +non_null(1, 4) nullable(6) +int gc_send_private_message(const GC_Chat *chat, GC_Peer_Id peer_id, uint8_t type, const uint8_t *message, + uint16_t length, uint32_t *message_id); /** @brief Sends a custom packet to the group. If lossless is true, the packet will be lossless. * @@ -189,8 +192,7 @@ int gc_send_private_message(const GC_Chat *chat, uint32_t peer_id, uint8_t type, * Returns 0 on success. * Returns -1 if the message is too long. * Returns -2 if the message pointer is NULL or length is zero. - * Returns -3 if the sender has the observer role. - * Returns -4 if the packet did not successfully send to any peer. + * Returns -3 if the packet did not successfully send to any peer. */ non_null() int gc_send_custom_packet(const GC_Chat *chat, bool lossless, const uint8_t *data, uint16_t length); @@ -203,11 +205,10 @@ int gc_send_custom_packet(const GC_Chat *chat, bool lossless, const uint8_t *dat * @retval -1 if the message is too long. * @retval -2 if the message pointer is NULL or length is zero. * @retval -3 if the supplied peer_id does not designate a valid peer. - * @retval -4 if the sender has the observer role. - * @retval -5 if the packet fails to send. + * @retval -4 if the packet fails to send. */ non_null() -int gc_send_custom_private_packet(const GC_Chat *chat, bool lossless, uint32_t peer_id, const uint8_t *message, +int gc_send_custom_private_packet(const GC_Chat *chat, bool lossless, GC_Peer_Id peer_id, const uint8_t *message, uint16_t length); /** @brief Sets ignore for peer_id. @@ -217,7 +218,7 @@ int gc_send_custom_private_packet(const GC_Chat *chat, bool lossless, uint32_t p * Returns -2 if the caller attempted to ignore himself. */ non_null() -int gc_set_ignore(const GC_Chat *chat, uint32_t peer_id, bool ignore); +int gc_set_ignore(const GC_Chat *chat, GC_Peer_Id peer_id, bool ignore); /** @brief Sets the group topic and broadcasts it to the group. * @@ -342,7 +343,7 @@ uint8_t gc_get_self_status(const GC_Chat *chat); /** @brief Returns your own peer id. */ non_null() -uint32_t gc_get_self_peer_id(const GC_Chat *chat); +GC_Peer_Id gc_get_self_peer_id(const GC_Chat *chat); /** @brief Copies self public key to `public_key`. * @@ -365,7 +366,7 @@ void gc_get_self_public_key(const GC_Chat *chat, uint8_t *public_key); * Returns false if peer_id is invalid. */ non_null(1) nullable(3) -bool gc_get_peer_nick(const GC_Chat *chat, uint32_t peer_id, uint8_t *name); +bool gc_get_peer_nick(const GC_Chat *chat, GC_Peer_Id peer_id, uint8_t *name); /** @brief Returns the length of the nick for the peer designated by `peer_id`. * Returns -1 if peer_id is invalid. @@ -374,7 +375,7 @@ bool gc_get_peer_nick(const GC_Chat *chat, uint32_t peer_id, uint8_t *name); * nick_change callback. */ non_null() -int gc_get_peer_nick_size(const GC_Chat *chat, uint32_t peer_id); +int gc_get_peer_nick_size(const GC_Chat *chat, GC_Peer_Id peer_id); /** @brief Copies peer_id's public key to `public_key`. * @@ -389,13 +390,13 @@ int gc_get_peer_nick_size(const GC_Chat *chat, uint32_t peer_id); * Returns -2 if `public_key` is null. */ non_null(1) nullable(3) -int gc_get_peer_public_key_by_peer_id(const GC_Chat *chat, uint32_t peer_id, uint8_t *public_key); +int gc_get_peer_public_key_by_peer_id(const GC_Chat *chat, GC_Peer_Id peer_id, uint8_t *public_key); /** @brief Returns the length of the IP address for the peer designated by `peer_id`. * Returns -1 if peer_id is invalid. */ non_null() -int gc_get_peer_ip_address_size(const GC_Chat *chat, uint32_t peer_id); +int gc_get_peer_ip_address_size(const GC_Chat *chat, GC_Peer_Id peer_id); /** @brief Copies peer_id's IP address to `ip_addr`. * @@ -412,7 +413,7 @@ int gc_get_peer_ip_address_size(const GC_Chat *chat, uint32_t peer_id); * Returns -2 if `ip_addr` is null. */ non_null(1) nullable(3) -int gc_get_peer_ip_address(const GC_Chat *chat, uint32_t peer_id, uint8_t *ip_addr); +int gc_get_peer_ip_address(const GC_Chat *chat, GC_Peer_Id peer_id, uint8_t *ip_addr); /** @brief Gets the connection status for peer associated with `peer_id`. * @@ -426,7 +427,7 @@ int gc_get_peer_ip_address(const GC_Chat *chat, uint32_t peer_id, uint8_t *ip_ad * Note: Return values must correspond to Tox_Connection enum in API. */ non_null() -unsigned int gc_get_peer_connection_status(const GC_Chat *chat, uint32_t peer_id); +unsigned int gc_get_peer_connection_status(const GC_Chat *chat, GC_Peer_Id peer_id); /** @brief Sets the caller's status to `status`. * @@ -444,7 +445,7 @@ int gc_set_self_status(const Messenger *m, int group_number, Group_Peer_Status s * callback. */ non_null() -uint8_t gc_get_status(const GC_Chat *chat, uint32_t peer_id); +uint8_t gc_get_status(const GC_Chat *chat, GC_Peer_Id peer_id); /** @brief Returns the group role of peer designated by `peer_id`. * Returns UINT8_MAX on failure. @@ -452,7 +453,7 @@ uint8_t gc_get_status(const GC_Chat *chat, uint32_t peer_id); * The role returned is equal to the last role received through the moderation callback. */ non_null() -uint8_t gc_get_role(const GC_Chat *chat, uint32_t peer_id); +uint8_t gc_get_role(const GC_Chat *chat, GC_Peer_Id peer_id); /** @brief Sets the role of peer_id. role must be one of: GR_MODERATOR, GR_USER, GR_OBSERVER * @@ -465,7 +466,7 @@ uint8_t gc_get_role(const GC_Chat *chat, uint32_t peer_id); * Returns -6 if the caller attempted to kick himself. */ non_null() -int gc_set_peer_role(const Messenger *m, int group_number, uint32_t peer_id, Group_Role new_role); +int gc_set_peer_role(const Messenger *m, int group_number, GC_Peer_Id peer_id, Group_Role new_role); /** @brief Sets the group password and distributes the new shared state to the group. * @@ -560,7 +561,7 @@ int gc_founder_set_max_peers(GC_Chat *chat, uint16_t max_peers); * Returns -6 if the caller attempted to kick himself. */ non_null() -int gc_kick_peer(const Messenger *m, int group_number, uint32_t peer_id); +int gc_kick_peer(const Messenger *m, int group_number, GC_Peer_Id peer_id); /** @brief Copies the chat_id to dest. If dest is null this function has no effect. * @@ -569,7 +570,6 @@ int gc_kick_peer(const Messenger *m, int group_number, uint32_t peer_id); non_null(1) nullable(2) void gc_get_chat_id(const GC_Chat *chat, uint8_t *dest); - /** Group callbacks */ non_null(1) nullable(2) void gc_callback_message(const Messenger *m, gc_message_cb *function); non_null(1) nullable(2) void gc_callback_private_message(const Messenger *m, gc_private_message_cb *function); @@ -806,4 +806,4 @@ GC_Chat *gc_get_group_by_public_key(const GC_Session *c, const uint8_t *public_k non_null() int gc_add_peers_from_announces(GC_Chat *chat, const GC_Announce *announces, uint8_t gc_announces_count); -#endif // C_TOXCORE_TOXCORE_GROUP_CHATS_H +#endif /* C_TOXCORE_TOXCORE_GROUP_CHATS_H */ diff --git a/toxcore/group_common.h b/toxcore/group_common.h index 49c21369..daa8fe17 100644 --- a/toxcore/group_common.h +++ b/toxcore/group_common.h @@ -14,7 +14,13 @@ #include "DHT.h" #include "TCP_connection.h" +#include "attributes.h" +#include "crypto_core.h" #include "group_moderation.h" +#include "logger.h" +#include "mem.h" +#include "mono_time.h" +#include "network.h" #define MAX_GC_PART_MESSAGE_SIZE 128 #define MAX_GC_NICK_SIZE 128 @@ -73,7 +79,7 @@ typedef struct GC_Exit_Info { } GC_Exit_Info; typedef struct GC_PeerAddress { - uint8_t public_key[EXT_PUBLIC_KEY_SIZE]; + Extended_Public_Key public_key; IP_Port ip_port; } GC_PeerAddress; @@ -133,6 +139,7 @@ typedef struct GC_Connection { bool pending_key_rotation_request; bool pending_delete; /* true if this peer has been marked for deletion */ + bool delete_this_iteration; /* true if this peer should be deleted this do_gc() iteration*/ GC_Exit_Info exit_info; } GC_Connection; @@ -210,6 +217,15 @@ typedef struct GC_TimedOutPeer { uint64_t last_reconn_try; // the last time we tried to establish a new connection } GC_TimedOutPeer; +typedef bitwise uint32_t GC_Peer_Id_Value; + +typedef struct GC_Peer_Id { + GC_Peer_Id_Value value; +} GC_Peer_Id; + +GC_Peer_Id gc_peer_id_from_int(uint32_t value); +uint32_t gc_peer_id_to_int(GC_Peer_Id peer_id); + typedef struct GC_Peer { /* Below state is sent to other peers in peer info exchange */ uint8_t nick[MAX_GC_NICK_SIZE]; @@ -218,7 +234,7 @@ typedef struct GC_Peer { /* Below state is local only */ Group_Role role; - uint32_t peer_id; // permanent ID (used for the public API) + GC_Peer_Id peer_id; // permanent ID (used for the public API) bool ignore; GC_Connection gconn; @@ -226,7 +242,7 @@ typedef struct GC_Peer { typedef struct GC_SharedState { uint32_t version; - uint8_t founder_public_key[EXT_PUBLIC_KEY_SIZE]; + Extended_Public_Key founder_public_key; uint16_t maxpeers; uint16_t group_name_len; uint8_t group_name[MAX_GC_GROUP_NAME_SIZE]; @@ -281,11 +297,11 @@ typedef struct GC_Chat { uint32_t numpeers; int group_number; - uint8_t chat_public_key[EXT_PUBLIC_KEY_SIZE]; // the chat_id is the sig portion - uint8_t chat_secret_key[EXT_SECRET_KEY_SIZE]; // only used by the founder + Extended_Public_Key chat_public_key; // the chat_id is the sig portion + Extended_Secret_Key chat_secret_key; // only used by the founder - uint8_t self_public_key[EXT_PUBLIC_KEY_SIZE]; - uint8_t self_secret_key[EXT_SECRET_KEY_SIZE]; + Extended_Public_Key self_public_key; + Extended_Secret_Key self_secret_key; uint64_t time_connected; uint64_t last_ping_interval; @@ -320,6 +336,8 @@ typedef struct GC_Chat { uint8_t m_group_public_key[CRYPTO_PUBLIC_KEY_SIZE]; // public key for group's messenger friend connection int friend_connection_id; // identifier for group's messenger friend connection + + bool flag_exit; // true if the group will be deleted after the next do_gc() iteration } GC_Chat; #ifndef MESSENGER_DEFINED @@ -327,34 +345,34 @@ typedef struct GC_Chat { typedef struct Messenger Messenger; #endif /* MESSENGER_DEFINED */ -typedef void gc_message_cb(const Messenger *m, uint32_t group_number, uint32_t peer_id, unsigned int type, - const uint8_t *data, size_t length, uint32_t message_id, void *user_data); -typedef void gc_private_message_cb(const Messenger *m, uint32_t group_number, uint32_t peer_id, unsigned int type, - const uint8_t *data, size_t length, void *user_data); -typedef void gc_custom_packet_cb(const Messenger *m, uint32_t group_number, uint32_t peer_id, const uint8_t *data, +typedef void gc_message_cb(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, unsigned int type, + const uint8_t *message, size_t length, uint32_t message_id, void *user_data); +typedef void gc_private_message_cb(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, unsigned int type, + const uint8_t *message, size_t length, uint32_t message_id, void *user_data); +typedef void gc_custom_packet_cb(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, const uint8_t *data, size_t length, void *user_data); -typedef void gc_custom_private_packet_cb(const Messenger *m, uint32_t group_number, uint32_t peer_id, - const uint8_t *data, - size_t length, void *user_data); -typedef void gc_moderation_cb(const Messenger *m, uint32_t group_number, uint32_t peer_id, uint32_t target_peer, - unsigned int mod_event, void *user_data); -typedef void gc_nick_change_cb(const Messenger *m, uint32_t group_number, uint32_t peer_id, const uint8_t *data, +typedef void gc_custom_private_packet_cb(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, + const uint8_t *data, size_t length, void *user_data); +typedef void gc_moderation_cb(const Messenger *m, uint32_t group_number, GC_Peer_Id source_peer_number, + GC_Peer_Id target_peer_number, unsigned int mod_type, void *user_data); +typedef void gc_nick_change_cb(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, const uint8_t *name, size_t length, void *user_data); -typedef void gc_status_change_cb(const Messenger *m, uint32_t group_number, uint32_t peer_id, unsigned int status, +typedef void gc_status_change_cb(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, unsigned int status, void *user_data); -typedef void gc_topic_change_cb(const Messenger *m, uint32_t group_number, uint32_t peer_id, const uint8_t *data, +typedef void gc_topic_change_cb(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, const uint8_t *topic, size_t length, void *user_data); typedef void gc_topic_lock_cb(const Messenger *m, uint32_t group_number, unsigned int topic_lock, void *user_data); typedef void gc_voice_state_cb(const Messenger *m, uint32_t group_number, unsigned int voice_state, void *user_data); -typedef void gc_peer_limit_cb(const Messenger *m, uint32_t group_number, uint32_t max_peers, void *user_data); -typedef void gc_privacy_state_cb(const Messenger *m, uint32_t group_number, unsigned int state, void *user_data); -typedef void gc_password_cb(const Messenger *m, uint32_t group_number, const uint8_t *data, size_t length, +typedef void gc_peer_limit_cb(const Messenger *m, uint32_t group_number, uint32_t peer_limit, void *user_data); +typedef void gc_privacy_state_cb(const Messenger *m, uint32_t group_number, unsigned int privacy_state, void *user_data); +typedef void gc_password_cb(const Messenger *m, uint32_t group_number, const uint8_t *password, size_t length, void *user_data); -typedef void gc_peer_join_cb(const Messenger *m, uint32_t group_number, uint32_t peer_id, void *user_data); -typedef void gc_peer_exit_cb(const Messenger *m, uint32_t group_number, uint32_t peer_id, unsigned int exit_type, - const uint8_t *nick, size_t nick_len, const uint8_t *data, size_t length, void *user_data); +typedef void gc_peer_join_cb(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, void *user_data); +typedef void gc_peer_exit_cb(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, unsigned int exit_type, + const uint8_t *name, size_t name_length, const uint8_t *part_message, size_t length, + void *user_data); typedef void gc_self_join_cb(const Messenger *m, uint32_t group_number, void *user_data); -typedef void gc_rejected_cb(const Messenger *m, uint32_t group_number, unsigned int type, void *user_data); +typedef void gc_rejected_cb(const Messenger *m, uint32_t group_number, unsigned int fail_type, void *user_data); typedef struct GC_Session { Messenger *messenger; @@ -410,4 +428,4 @@ int unpack_gc_saved_peers(GC_Chat *chat, const uint8_t *data, uint16_t length); non_null(1, 2) nullable(4) int pack_gc_saved_peers(const GC_Chat *chat, uint8_t *data, uint16_t length, uint16_t *processed); -#endif // C_TOXCORE_TOXCORE_GROUP_COMMON_H +#endif /* C_TOXCORE_TOXCORE_GROUP_COMMON_H */ diff --git a/toxcore/group_connection.c b/toxcore/group_connection.c index 9abf73e6..1c2d1ec3 100644 --- a/toxcore/group_connection.c +++ b/toxcore/group_connection.c @@ -16,6 +16,7 @@ #include "DHT.h" #include "TCP_connection.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "group_chats.h" @@ -40,9 +41,7 @@ static bool array_entry_is_empty(const GC_Message_Array_Entry *array_entry) non_null() static void clear_array_entry(GC_Message_Array_Entry *const array_entry) { - if (array_entry->data != nullptr) { - free(array_entry->data); - } + free(array_entry->data); *array_entry = (GC_Message_Array_Entry) { nullptr @@ -93,7 +92,7 @@ void gcc_set_recv_message_id(GC_Connection *gconn, uint64_t id) */ non_null(1, 2, 3) nullable(4) static bool create_array_entry(const Logger *log, const Mono_Time *mono_time, GC_Message_Array_Entry *array_entry, - const uint8_t *data, uint16_t length, uint8_t packet_type, uint64_t message_id) + const uint8_t *data, uint16_t length, uint8_t packet_type, uint64_t message_id) { if (!array_entry_is_empty(array_entry)) { LOGGER_WARNING(log, "Failed to create array entry; entry is not empty."); @@ -182,7 +181,6 @@ int gcc_send_lossless_packet(const GC_Chat *chat, GC_Connection *gconn, const ui return 0; } - bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gconn, const uint8_t *data, uint16_t length, uint8_t packet_type) { @@ -441,7 +439,7 @@ int gcc_handle_packet_fragment(const GC_Session *c, GC_Chat *chat, uint32_t peer } uint8_t sender_pk[ENC_PUBLIC_KEY_SIZE]; - memcpy(sender_pk, get_enc_key(gconn->addr.public_key), ENC_PUBLIC_KEY_SIZE); + memcpy(sender_pk, get_enc_key(&gconn->addr.public_key), ENC_PUBLIC_KEY_SIZE); uint8_t *payload = nullptr; const uint16_t processed_len = reassemble_packet(chat->log, gconn, &payload, message_id); @@ -515,7 +513,7 @@ static bool process_recv_array_entry(const GC_Session *c, GC_Chat *chat, GC_Conn GC_Message_Array_Entry *const array_entry, void *userdata) { uint8_t sender_pk[ENC_PUBLIC_KEY_SIZE]; - memcpy(sender_pk, get_enc_key(gconn->addr.public_key), ENC_PUBLIC_KEY_SIZE); + memcpy(sender_pk, get_enc_key(&gconn->addr.public_key), ENC_PUBLIC_KEY_SIZE); const bool ret = handle_gc_lossless_helper(c, chat, peer_number, array_entry->data, array_entry->data_length, array_entry->packet_type, userdata); @@ -631,7 +629,7 @@ int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connectio } const int enc_len = group_packet_wrap( - chat->log, chat->rng, chat->self_public_key, gconn->session_shared_key, packet, + chat->log, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet, packet_size, data, length, message_id, packet_type, NET_PACKET_GC_LOSSLESS); if (enc_len < 0) { diff --git a/toxcore/group_connection.h b/toxcore/group_connection.h index fa7a3c94..4a9ccad0 100644 --- a/toxcore/group_connection.h +++ b/toxcore/group_connection.h @@ -10,7 +10,14 @@ #ifndef C_TOXCORE_TOXCORE_GROUP_CONNECTION_H #define C_TOXCORE_TOXCORE_GROUP_CONNECTION_H +#include "DHT.h" +#include "TCP_connection.h" +#include "attributes.h" +#include "crypto_core.h" #include "group_common.h" +#include "logger.h" +#include "mono_time.h" +#include "network.h" /* Max number of TCP relays we share with a peer on handshake */ #define GCC_MAX_TCP_SHARED_RELAYS 3 @@ -166,7 +173,6 @@ non_null() bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gconn, const uint8_t *data, uint16_t length, uint8_t packet_type); - /** @brief Encrypts `data` of `length` bytes, designated by `message_id`, using the shared key * associated with `gconn` and sends lossless packet over the wire. * @@ -178,7 +184,7 @@ bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gcon */ non_null(1, 2) nullable(3) int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *data, - uint16_t length, uint64_t message_id, uint8_t packet_type); + uint16_t length, uint64_t message_id, uint8_t packet_type); /** @brief Called when a peer leaves the group. */ non_null() @@ -188,4 +194,4 @@ void gcc_peer_cleanup(GC_Connection *gconn); non_null() void gcc_cleanup(const GC_Chat *chat); -#endif // C_TOXCORE_TOXCORE_GROUP_CONNECTION_H +#endif /* C_TOXCORE_TOXCORE_GROUP_CONNECTION_H */ diff --git a/toxcore/group_moderation.c b/toxcore/group_moderation.c index 0da113ec..3cb69e94 100644 --- a/toxcore/group_moderation.c +++ b/toxcore/group_moderation.c @@ -16,6 +16,7 @@ #include #include "DHT.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "logger.h" @@ -93,7 +94,7 @@ void mod_list_get_data_hash(uint8_t *hash, const uint8_t *packed_mod_list, uint1 bool mod_list_make_hash(const Moderation *moderation, uint8_t *hash) { if (moderation->num_mods == 0) { - memset(hash, 0, MOD_MODERATION_HASH_SIZE); + memzero(hash, MOD_MODERATION_HASH_SIZE); return true; } @@ -235,15 +236,15 @@ uint16_t sanctions_creds_pack(const Mod_Sanction_Creds *creds, uint8_t *data) { uint16_t packed_len = 0; - net_pack_u32(data + packed_len, creds->version); + net_pack_u32(&data[packed_len], creds->version); packed_len += sizeof(uint32_t); - memcpy(data + packed_len, creds->hash, MOD_SANCTION_HASH_SIZE); + memcpy(&data[packed_len], creds->hash, MOD_SANCTION_HASH_SIZE); packed_len += MOD_SANCTION_HASH_SIZE; - net_pack_u16(data + packed_len, creds->checksum); + net_pack_u16(&data[packed_len], creds->checksum); packed_len += sizeof(uint16_t); - memcpy(data + packed_len, creds->sig_pk, SIG_PUBLIC_KEY_SIZE); + memcpy(&data[packed_len], creds->sig_pk, SIG_PUBLIC_KEY_SIZE); packed_len += SIG_PUBLIC_KEY_SIZE; - memcpy(data + packed_len, creds->sig, SIGNATURE_SIZE); + memcpy(&data[packed_len], creds->sig, SIGNATURE_SIZE); packed_len += SIGNATURE_SIZE; return packed_len; @@ -267,11 +268,11 @@ int sanctions_list_pack(uint8_t *data, uint16_t length, const Mod_Sanction *sanc return -1; } - memcpy(data + packed_len, &sanctions[i].type, sizeof(uint8_t)); + memcpy(&data[packed_len], &sanctions[i].type, sizeof(uint8_t)); packed_len += sizeof(uint8_t); - memcpy(data + packed_len, sanctions[i].setter_public_sig_key, SIG_PUBLIC_KEY_SIZE); + memcpy(&data[packed_len], sanctions[i].setter_public_sig_key, SIG_PUBLIC_KEY_SIZE); packed_len += SIG_PUBLIC_KEY_SIZE; - net_pack_u64(data + packed_len, sanctions[i].time_set); + net_pack_u64(&data[packed_len], sanctions[i].time_set); packed_len += TIME_STAMP_SIZE; const uint8_t sanctions_type = sanctions[i].type; @@ -281,7 +282,7 @@ int sanctions_list_pack(uint8_t *data, uint16_t length, const Mod_Sanction *sanc return -1; } - memcpy(data + packed_len, sanctions[i].target_public_enc_key, ENC_PUBLIC_KEY_SIZE); + memcpy(&data[packed_len], sanctions[i].target_public_enc_key, ENC_PUBLIC_KEY_SIZE); packed_len += ENC_PUBLIC_KEY_SIZE; } else { return -1; @@ -292,7 +293,7 @@ int sanctions_list_pack(uint8_t *data, uint16_t length, const Mod_Sanction *sanc } /* Signature must be packed last */ - memcpy(data + packed_len, sanctions[i].signature, SIGNATURE_SIZE); + memcpy(&data[packed_len], sanctions[i].signature, SIGNATURE_SIZE); packed_len += SIGNATURE_SIZE; } @@ -304,7 +305,7 @@ int sanctions_list_pack(uint8_t *data, uint16_t length, const Mod_Sanction *sanc return -1; } - const uint16_t cred_len = sanctions_creds_pack(creds, data + packed_len); + const uint16_t cred_len = sanctions_creds_pack(creds, &data[packed_len]); if (cred_len != MOD_SANCTIONS_CREDS_SIZE) { return -1; @@ -317,15 +318,15 @@ uint16_t sanctions_creds_unpack(Mod_Sanction_Creds *creds, const uint8_t *data) { uint16_t len_processed = 0; - net_unpack_u32(data + len_processed, &creds->version); + net_unpack_u32(&data[len_processed], &creds->version); len_processed += sizeof(uint32_t); - memcpy(creds->hash, data + len_processed, MOD_SANCTION_HASH_SIZE); + memcpy(creds->hash, &data[len_processed], MOD_SANCTION_HASH_SIZE); len_processed += MOD_SANCTION_HASH_SIZE; - net_unpack_u16(data + len_processed, &creds->checksum); + net_unpack_u16(&data[len_processed], &creds->checksum); len_processed += sizeof(uint16_t); - memcpy(creds->sig_pk, data + len_processed, SIG_PUBLIC_KEY_SIZE); + memcpy(creds->sig_pk, &data[len_processed], SIG_PUBLIC_KEY_SIZE); len_processed += SIG_PUBLIC_KEY_SIZE; - memcpy(creds->sig, data + len_processed, SIGNATURE_SIZE); + memcpy(creds->sig, &data[len_processed], SIGNATURE_SIZE); len_processed += SIGNATURE_SIZE; return len_processed; @@ -342,11 +343,11 @@ int sanctions_list_unpack(Mod_Sanction *sanctions, Mod_Sanction_Creds *creds, ui return -1; } - memcpy(&sanctions[num].type, data + len_processed, sizeof(uint8_t)); + memcpy(&sanctions[num].type, &data[len_processed], sizeof(uint8_t)); len_processed += sizeof(uint8_t); - memcpy(sanctions[num].setter_public_sig_key, data + len_processed, SIG_PUBLIC_KEY_SIZE); + memcpy(sanctions[num].setter_public_sig_key, &data[len_processed], SIG_PUBLIC_KEY_SIZE); len_processed += SIG_PUBLIC_KEY_SIZE; - net_unpack_u64(data + len_processed, &sanctions[num].time_set); + net_unpack_u64(&data[len_processed], &sanctions[num].time_set); len_processed += TIME_STAMP_SIZE; if (sanctions[num].type == SA_OBSERVER) { @@ -354,7 +355,7 @@ int sanctions_list_unpack(Mod_Sanction *sanctions, Mod_Sanction_Creds *creds, ui return -1; } - memcpy(sanctions[num].target_public_enc_key, data + len_processed, ENC_PUBLIC_KEY_SIZE); + memcpy(sanctions[num].target_public_enc_key, &data[len_processed], ENC_PUBLIC_KEY_SIZE); len_processed += ENC_PUBLIC_KEY_SIZE; } else { return -1; @@ -364,7 +365,7 @@ int sanctions_list_unpack(Mod_Sanction *sanctions, Mod_Sanction_Creds *creds, ui return -1; } - memcpy(sanctions[num].signature, data + len_processed, SIGNATURE_SIZE); + memcpy(sanctions[num].signature, &data[len_processed], SIGNATURE_SIZE); len_processed += SIGNATURE_SIZE; ++num; @@ -382,7 +383,7 @@ int sanctions_list_unpack(Mod_Sanction *sanctions, Mod_Sanction_Creds *creds, ui return num; } - const uint16_t creds_len = sanctions_creds_unpack(creds, data + len_processed); + const uint16_t creds_len = sanctions_creds_unpack(creds, &data[len_processed]); if (creds_len != MOD_SANCTIONS_CREDS_SIZE) { return -1; @@ -395,7 +396,6 @@ int sanctions_list_unpack(Mod_Sanction *sanctions, Mod_Sanction_Creds *creds, ui return num; } - /** @brief Creates a new sanction list hash and puts it in hash. * * The hash is derived from the signature of all entries plus the version number. @@ -410,7 +410,7 @@ static bool sanctions_list_make_hash(const Mod_Sanction *sanctions, uint32_t new uint8_t *hash) { if (num_sanctions == 0 || sanctions == nullptr) { - memset(hash, 0, MOD_SANCTION_HASH_SIZE); + memzero(hash, MOD_SANCTION_HASH_SIZE); return true; } @@ -864,9 +864,7 @@ uint16_t sanctions_list_replace_sig(Moderation *moderation, const uint8_t *publi void sanctions_list_cleanup(Moderation *moderation) { - if (moderation->sanctions != nullptr) { - free(moderation->sanctions); - } + free(moderation->sanctions); moderation->sanctions = nullptr; moderation->num_sanctions = 0; diff --git a/toxcore/group_moderation.h b/toxcore/group_moderation.h index c57e0a81..eeab32fc 100644 --- a/toxcore/group_moderation.h +++ b/toxcore/group_moderation.h @@ -14,7 +14,10 @@ #include #include "DHT.h" +#include "attributes.h" +#include "crypto_core.h" #include "logger.h" +#include "mem.h" #ifdef __cplusplus extern "C" { @@ -291,7 +294,7 @@ non_null() void sanctions_list_cleanup(Moderation *moderation); #ifdef __cplusplus -} // extern "C" +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_GROUP_MODERATION_H +#endif /* C_TOXCORE_TOXCORE_GROUP_MODERATION_H */ diff --git a/toxcore/group_moderation_fuzz_test.cc b/toxcore/group_moderation_fuzz_test.cc index 9edca19d..dde78ba1 100644 --- a/toxcore/group_moderation_fuzz_test.cc +++ b/toxcore/group_moderation_fuzz_test.cc @@ -1,6 +1,6 @@ #include "group_moderation.h" -#include "../testing/fuzzing/fuzz_support.h" +#include "../testing/fuzzing/fuzz_support.hh" #include "mem_test_util.hh" namespace { diff --git a/toxcore/group_moderation_test.cc b/toxcore/group_moderation_test.cc index 24e32ba2..ea72023e 100644 --- a/toxcore/group_moderation_test.cc +++ b/toxcore/group_moderation_test.cc @@ -6,6 +6,7 @@ #include #include +#include "DHT.h" #include "crypto_core.h" #include "crypto_core_test_util.hh" #include "logger.h" @@ -14,8 +15,6 @@ namespace { -using ExtPublicKey = std::array; -using ExtSecretKey = std::array; using ModerationHash = std::array; TEST(ModList, PackedSizeOfEmptyModListIsZero) @@ -190,9 +189,10 @@ TEST(SanctionsList, PackUnpackSanctionsCreds) struct SanctionsListMod : ::testing::Test { protected: - ExtPublicKey pk; - ExtSecretKey sk; + Extended_Public_Key pk; + Extended_Secret_Key sk; Logger *log = logger_new(); + Test_Random rng; Test_Memory mem; Moderation mod{mem}; @@ -202,14 +202,14 @@ protected: void SetUp() override { - ASSERT_TRUE(create_extended_keypair(pk.data(), sk.data())); + ASSERT_TRUE(create_extended_keypair(&pk, &sk, rng)); mod.log = log; - memcpy(mod.self_public_sig_key, get_sig_pk(pk.data()), SIG_PUBLIC_KEY_SIZE); - memcpy(mod.self_secret_sig_key, get_sig_sk(sk.data()), SIG_SECRET_KEY_SIZE); + memcpy(mod.self_public_sig_key, get_sig_pk(&pk), SIG_PUBLIC_KEY_SIZE); + memcpy(mod.self_secret_sig_key, get_sig_sk(&sk), SIG_SECRET_KEY_SIZE); - ASSERT_TRUE(mod_list_add_entry(&mod, get_sig_pk(pk.data()))); + ASSERT_TRUE(mod_list_add_entry(&mod, get_sig_pk(&pk))); EXPECT_FALSE(sanctions_list_check_integrity(&mod, &mod.sanctions_creds, &sanctions[0], 0)); EXPECT_FALSE(sanctions_list_check_integrity(&mod, &mod.sanctions_creds, &sanctions[0], 1)); @@ -230,7 +230,7 @@ protected: EXPECT_TRUE(sanctions_list_remove_observer(&mod, sanctioned_pk2, nullptr)); EXPECT_FALSE(sanctions_list_entry_exists(&mod, &sanctions[0])); EXPECT_FALSE(sanctions_list_entry_exists(&mod, &sanctions[1])); - EXPECT_TRUE(mod_list_remove_entry(&mod, get_sig_pk(pk.data()))); + EXPECT_TRUE(mod_list_remove_entry(&mod, get_sig_pk(&pk))); logger_kill(log); } diff --git a/toxcore/group_onion_announce.c b/toxcore/group_onion_announce.c index 16368e5c..d05db09a 100644 --- a/toxcore/group_onion_announce.c +++ b/toxcore/group_onion_announce.c @@ -8,6 +8,8 @@ #include #include +#include "DHT.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "group_announce.h" @@ -15,6 +17,7 @@ #include "mono_time.h" #include "network.h" #include "onion_announce.h" +#include "timed_auth.h" static_assert(GCA_ANNOUNCE_MAX_SIZE <= ONION_MAX_EXTRA_DATA_SIZE, "GC_Announce does not fit into the onion packet extra data"); diff --git a/toxcore/group_onion_announce.h b/toxcore/group_onion_announce.h index 5c6d64ec..5fbac02e 100644 --- a/toxcore/group_onion_announce.h +++ b/toxcore/group_onion_announce.h @@ -6,6 +6,8 @@ #ifndef C_TOXCORE_TOXCORE_GROUP_ONION_ANNOUNCE_H #define C_TOXCORE_TOXCORE_GROUP_ONION_ANNOUNCE_H +#include "attributes.h" +#include "crypto_core.h" #include "group_announce.h" #include "onion_announce.h" @@ -19,4 +21,4 @@ int create_gca_announce_request( const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data, const uint8_t *gc_data, uint16_t gc_data_length); -#endif // C_TOXCORE_TOXCORE_GROUP_ONION_ANNOUNCE_H +#endif /* C_TOXCORE_TOXCORE_GROUP_ONION_ANNOUNCE_H */ diff --git a/toxcore/group_pack.c b/toxcore/group_pack.c index f0351650..e3af82c6 100644 --- a/toxcore/group_pack.c +++ b/toxcore/group_pack.c @@ -14,12 +14,16 @@ #include #include "DHT.h" +#include "attributes.h" #include "bin_pack.h" #include "bin_unpack.h" #include "ccompat.h" +#include "crypto_core.h" +#include "crypto_core_pack.h" #include "group_common.h" #include "group_moderation.h" #include "logger.h" +#include "network.h" #include "util.h" bool group_privacy_state_from_int(uint8_t value, Group_Privacy_State *out) @@ -116,7 +120,7 @@ static bool load_unpack_state_bin(GC_Chat *chat, Bin_Unpack *bu) return false; } - if (!bin_unpack_bin_fixed(bu, chat->shared_state.founder_public_key, EXT_PUBLIC_KEY_SIZE)) { + if (!unpack_extended_public_key(&chat->shared_state.founder_public_key, bu)) { LOGGER_ERROR(chat->log, "Failed to unpack founder public key"); return false; } @@ -210,10 +214,10 @@ static bool load_unpack_keys(GC_Chat *chat, Bin_Unpack *bu) return false; } - if (!(bin_unpack_bin_fixed(bu, chat->chat_public_key, EXT_PUBLIC_KEY_SIZE) - && bin_unpack_bin_fixed(bu, chat->chat_secret_key, EXT_SECRET_KEY_SIZE) - && bin_unpack_bin_fixed(bu, chat->self_public_key, EXT_PUBLIC_KEY_SIZE) - && bin_unpack_bin_fixed(bu, chat->self_secret_key, EXT_SECRET_KEY_SIZE))) { + if (!(unpack_extended_public_key(&chat->chat_public_key, bu) + && unpack_extended_secret_key(&chat->chat_secret_key, bu) + && unpack_extended_public_key(&chat->self_public_key, bu) + && unpack_extended_secret_key(&chat->self_secret_key, bu))) { LOGGER_ERROR(chat->log, "Failed to unpack keys"); return false; } @@ -252,7 +256,7 @@ static bool load_unpack_self_info(GC_Chat *chat, Bin_Unpack *bu) } // we have to add ourself before setting self info - if (peer_add(chat, nullptr, chat->self_public_key) != 0) { + if (peer_add(chat, nullptr, chat->self_public_key.enc) != 0) { LOGGER_ERROR(chat->log, "Failed to add self to peer list"); return false; } @@ -264,7 +268,7 @@ static bool load_unpack_self_info(GC_Chat *chat, Bin_Unpack *bu) GC_Peer *self = &chat->group[0]; - memcpy(self->gconn.addr.public_key, chat->self_public_key, EXT_PUBLIC_KEY_SIZE); + self->gconn.addr.public_key = chat->self_public_key; memcpy(self->nick, self_nick, self_nick_len); self->nick_length = self_nick_len; self->role = (Group_Role)self_role; @@ -354,7 +358,7 @@ static void save_pack_state_bin(const GC_Chat *chat, Bin_Pack *bp) bin_pack_array(bp, 5); bin_pack_bin(bp, chat->shared_state_sig, SIGNATURE_SIZE); // 1 - bin_pack_bin(bp, chat->shared_state.founder_public_key, EXT_PUBLIC_KEY_SIZE); // 2 + pack_extended_public_key(&chat->shared_state.founder_public_key, bp); // 2 bin_pack_bin(bp, chat->shared_state.group_name, chat->shared_state.group_name_len); // 3 bin_pack_bin(bp, chat->shared_state.password, chat->shared_state.password_length); // 4 bin_pack_bin(bp, chat->shared_state.mod_list_hash, MOD_MODERATION_HASH_SIZE); // 5 @@ -412,10 +416,10 @@ static void save_pack_keys(const GC_Chat *chat, Bin_Pack *bp) { bin_pack_array(bp, 4); - bin_pack_bin(bp, chat->chat_public_key, EXT_PUBLIC_KEY_SIZE); // 1 - bin_pack_bin(bp, chat->chat_secret_key, EXT_SECRET_KEY_SIZE); // 2 - bin_pack_bin(bp, chat->self_public_key, EXT_PUBLIC_KEY_SIZE); // 3 - bin_pack_bin(bp, chat->self_secret_key, EXT_SECRET_KEY_SIZE); // 4 + pack_extended_public_key(&chat->chat_public_key, bp); // 1 + pack_extended_secret_key(&chat->chat_secret_key, bp); // 2 + pack_extended_public_key(&chat->self_public_key, bp); // 3 + pack_extended_secret_key(&chat->self_secret_key, bp); // 4 } non_null() diff --git a/toxcore/group_pack.h b/toxcore/group_pack.h index 70b0df8d..03252fb8 100644 --- a/toxcore/group_pack.h +++ b/toxcore/group_pack.h @@ -12,6 +12,7 @@ #include +#include "attributes.h" #include "bin_pack.h" #include "bin_unpack.h" #include "group_common.h" @@ -37,4 +38,4 @@ bool group_privacy_state_from_int(uint8_t value, Group_Privacy_State *out); non_null() bool group_voice_state_from_int(uint8_t value, Group_Voice_State *out); -#endif // C_TOXCORE_TOXCORE_GROUP_PACK_H +#endif /* C_TOXCORE_TOXCORE_GROUP_PACK_H */ diff --git a/toxcore/list.c b/toxcore/list.c index 1096befc..bf3db247 100644 --- a/toxcore/list.c +++ b/toxcore/list.c @@ -15,6 +15,7 @@ #include #include +#include "attributes.h" #include "ccompat.h" /** @@ -29,8 +30,7 @@ * - some considerations since the array size is never perfect */ -static int32_t -list_index(uint32_t i) +static int32_t list_index(uint32_t i) { return ~i; } @@ -60,7 +60,7 @@ static int find(const BS_List *list, const uint8_t *data) // closest match is found if we move back to where we have already been while (true) { - const int r = memcmp(data, list->data + list->element_size * i, list->element_size); + const int r = list->cmp_callback(data, list->data + list->element_size * i, list->element_size); if (r == 0) { return i; @@ -134,8 +134,7 @@ static bool resize(BS_List *list, uint32_t new_size) return true; } - -int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity) +int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity, bs_list_cmp_cb *cmp_callback) { // set initial values list->n = 0; @@ -143,6 +142,7 @@ int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity list->capacity = 0; list->data = nullptr; list->ids = nullptr; + list->cmp_callback = cmp_callback; if (initial_capacity != 0) { if (!resize(list, initial_capacity)) { diff --git a/toxcore/list.h b/toxcore/list.h index a7c0e56c..1dc66d01 100644 --- a/toxcore/list.h +++ b/toxcore/list.h @@ -12,6 +12,7 @@ #define C_TOXCORE_TOXCORE_LIST_H #include +#include // size_t #include #include "attributes.h" @@ -20,12 +21,15 @@ extern "C" { #endif +typedef int bs_list_cmp_cb(const void *a, const void *b, size_t size); + typedef struct BS_List { uint32_t n; // number of elements uint32_t capacity; // number of elements memory is allocated for uint32_t element_size; // size of the elements uint8_t *data; // array of elements int *ids; // array of element ids + bs_list_cmp_cb *cmp_callback; } BS_List; /** @brief Initialize a list. @@ -37,7 +41,7 @@ typedef struct BS_List { * @retval 0 failure */ non_null() -int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity); +int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity, bs_list_cmp_cb *cmp_callback); /** Free a list initiated with list_init */ nullable(1) @@ -68,7 +72,7 @@ non_null() bool bs_list_remove(BS_List *list, const uint8_t *data, int id); #ifdef __cplusplus -} // extern "C" +} /* extern "C" */ #endif -#endif +#endif /* C_TOXCORE_TOXCORE_LIST_H */ diff --git a/toxcore/list_test.cc b/toxcore/list_test.cc index 5bffb8a1..0d8f646c 100644 --- a/toxcore/list_test.cc +++ b/toxcore/list_test.cc @@ -7,21 +7,21 @@ namespace { TEST(List, CreateAndDestroyWithNonZeroSize) { BS_List list; - bs_list_init(&list, sizeof(int), 10); + bs_list_init(&list, sizeof(int), 10, memcmp); bs_list_free(&list); } TEST(List, CreateAndDestroyWithZeroSize) { BS_List list; - bs_list_init(&list, sizeof(int), 0); + bs_list_init(&list, sizeof(int), 0, memcmp); bs_list_free(&list); } TEST(List, DeleteFromEmptyList) { BS_List list; - bs_list_init(&list, sizeof(int), 0); + bs_list_init(&list, sizeof(int), 0, memcmp); const uint8_t data[sizeof(int)] = {0}; bs_list_remove(&list, data, 0); bs_list_free(&list); diff --git a/toxcore/logger.c b/toxcore/logger.c index 468e9ad5..67fa5233 100644 --- a/toxcore/logger.c +++ b/toxcore/logger.c @@ -13,6 +13,7 @@ #include #include +#include "attributes.h" #include "ccompat.h" struct Logger { @@ -43,7 +44,7 @@ static const char *logger_level_name(Logger_Level level) return ""; } -#endif +#endif /* NDEBUG */ non_null(1, 3, 5, 6) nullable(7) static void logger_stderr_handler(void *context, Logger_Level level, const char *file, int line, const char *func, @@ -54,7 +55,7 @@ static void logger_stderr_handler(void *context, Logger_Level level, const char fprintf(stderr, "[GL] %s %s:%d(%s): %s\n", logger_level_name(level), file, line, func, message); fprintf(stderr, "Default stderr logger triggered; aborting program\n"); abort(); -#endif +#endif /* NDEBUG */ } static const Logger logger_stderr = { @@ -105,7 +106,7 @@ void logger_write(const Logger *log, Logger_Level level, const char *file, int l // one too. const char *windows_filename = strrchr(file, '\\'); file = windows_filename != nullptr ? windows_filename + 1 : file; -#endif +#endif /* WIN32 */ // Format message char msg[1024]; diff --git a/toxcore/logger.h b/toxcore/logger.h index 8388b166..830db883 100644 --- a/toxcore/logger.h +++ b/toxcore/logger.h @@ -19,7 +19,7 @@ extern "C" { #ifndef MIN_LOGGER_LEVEL #define MIN_LOGGER_LEVEL LOGGER_LEVEL_INFO -#endif +#endif /* MIN_LOGGER_LEVEL */ // NOTE: Don't forget to update build system files after modifying the enum. typedef enum Logger_Level { @@ -70,7 +70,6 @@ void logger_write( /* @brief Terminate the program with a signal. */ void logger_abort(void); - #define LOGGER_WRITE(log, level, ...) \ do { \ if (level >= MIN_LOGGER_LEVEL) { \ @@ -100,7 +99,7 @@ void logger_abort(void); } while (0) #ifdef __cplusplus -} // extern "C" +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_LOGGER_H +#endif /* C_TOXCORE_TOXCORE_LOGGER_H */ diff --git a/toxcore/mem.c b/toxcore/mem.c index a15b9728..bddc335b 100644 --- a/toxcore/mem.c +++ b/toxcore/mem.c @@ -7,6 +7,7 @@ #include +#include "attributes.h" #include "ccompat.h" nullable(1) @@ -33,17 +34,17 @@ static void sys_free(void *obj, void *ptr) free(ptr); } -static const Memory_Funcs system_memory_funcs = { +static const Memory_Funcs os_memory_funcs = { sys_malloc, sys_calloc, sys_realloc, sys_free, }; -static const Memory system_memory_obj = {&system_memory_funcs}; +static const Memory os_memory_obj = {&os_memory_funcs}; -const Memory *system_memory(void) +const Memory *os_memory(void) { - return &system_memory_obj; + return &os_memory_obj; } void *mem_balloc(const Memory *mem, uint32_t size) diff --git a/toxcore/mem.h b/toxcore/mem.h index a9d9e1d2..7a96b6d3 100644 --- a/toxcore/mem.h +++ b/toxcore/mem.h @@ -35,7 +35,7 @@ typedef struct Memory { void *obj; } Memory; -const Memory *system_memory(void); +const Memory *os_memory(void); /** * @brief Allocate an array of a given size for built-in types. @@ -80,7 +80,7 @@ non_null(1) nullable(2) void *mem_vrealloc(const Memory *mem, void *ptr, uint32_ non_null(1) nullable(2) void mem_delete(const Memory *mem, void *ptr); #ifdef __cplusplus -} // extern "C" +} /* extern "C" */ #endif -#endif +#endif /* C_TOXCORE_TOXCORE_MEM_H */ diff --git a/toxcore/mem_test.cc b/toxcore/mem_test.cc index f7870366..5b649e21 100644 --- a/toxcore/mem_test.cc +++ b/toxcore/mem_test.cc @@ -9,7 +9,7 @@ TEST(Mem, AllocLarge) // Mebi prefix: https://en.wikipedia.org/wiki/Binary_prefix. constexpr uint32_t MI = 1024 * 1024; - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); void *ptr = mem_valloc(mem, 4, MI); EXPECT_NE(ptr, nullptr); @@ -22,7 +22,7 @@ TEST(Mem, AllocOverflow) // Gibi prefix. constexpr uint32_t GI = 1024 * 1024 * 1024; - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); // 1 gibi-elements of 100 bytes each. void *ptr = mem_valloc(mem, GI, 100); diff --git a/toxcore/mem_test_util.cc b/toxcore/mem_test_util.cc index 874bc66b..02ade8fc 100644 --- a/toxcore/mem_test_util.cc +++ b/toxcore/mem_test_util.cc @@ -2,6 +2,9 @@ #include +#include "mem.h" +#include "test_util.hh" + Memory_Funcs const Memory_Class::vtable = { Method::invoke<&Memory_Class::malloc>, Method::invoke<&Memory_Class::calloc>, diff --git a/toxcore/mem_test_util.hh b/toxcore/mem_test_util.hh index 6d1773d1..03094eb5 100644 --- a/toxcore/mem_test_util.hh +++ b/toxcore/mem_test_util.hh @@ -24,11 +24,11 @@ struct Memory_Class { }; /** - * Base test Memory class that just forwards to system_memory. Can be + * Base test Memory class that just forwards to os_memory. Can be * subclassed to override individual (or all) functions. */ class Test_Memory : public Memory_Class { - const Memory *mem = REQUIRE_NOT_NULL(system_memory()); + const Memory *mem = REQUIRE_NOT_NULL(os_memory()); void *malloc(void *obj, uint32_t size) override; void *calloc(void *obj, uint32_t nmemb, uint32_t size) override; diff --git a/toxcore/mono_time.c b/toxcore/mono_time.c index 2c741f51..124f94fc 100644 --- a/toxcore/mono_time.c +++ b/toxcore/mono_time.c @@ -4,34 +4,35 @@ */ #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 -#endif +#endif /* _XOPEN_SOURCE */ #if !defined(OS_WIN32) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) #define OS_WIN32 -#endif +#endif /* WIN32 */ #include "mono_time.h" #ifdef OS_WIN32 #define WIN32_LEAN_AND_MEAN #include -#endif +#endif /* OS_WIN32 */ #ifdef __APPLE__ #include #include -#endif +#endif /* __APPLE__ */ #ifndef OS_WIN32 #include -#endif +#endif /* OS_WIN32 */ #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION #include -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ #include #include +#include "attributes.h" #include "ccompat.h" #include "mem.h" #include "util.h" @@ -44,7 +45,7 @@ struct Mono_Time { #ifndef ESP_PLATFORM /* protect `time` from concurrent access */ pthread_rwlock_t *time_update_lock; -#endif +#endif /* ESP_PLATFORM */ mono_time_current_time_cb *current_time_callback; void *user_data; @@ -101,14 +102,13 @@ static uint64_t current_time_monotonic_default(void *user_data) // This assert should always fail. If it does, the fuzzing harness didn't // override the mono time callback. assert(user_data == nullptr); -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ struct timespec clock_mono; clock_gettime(CLOCK_MONOTONIC, &clock_mono); return timespec_to_u64(clock_mono); } -#endif // !__APPLE__ -#endif // !OS_WIN32 - +#endif /* !__APPLE__ */ +#endif /* !OS_WIN32 */ Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_time_callback, void *user_data) { @@ -133,7 +133,7 @@ Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_t } mono_time->time_update_lock = rwlock; -#endif +#endif /* ESP_PLATFORM */ mono_time_set_current_time_callback(mono_time, current_time_callback, user_data); @@ -145,7 +145,7 @@ Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_t // Never return time = 0 in case time() returns 0 (e.g. on microcontrollers // without battery-powered RTC or ones where NTP didn't initialise it yet). mono_time->base_time = max_u64(1, (uint64_t)time(nullptr)) * UINT64_C(1000) - current_time_monotonic(mono_time); -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ mono_time_update(mono_time); @@ -160,7 +160,7 @@ void mono_time_free(const Memory *mem, Mono_Time *mono_time) #ifndef ESP_PLATFORM pthread_rwlock_destroy(mono_time->time_update_lock); mem_delete(mem, mono_time->time_update_lock); -#endif +#endif /* ESP_PLATFORM */ mem_delete(mem, mono_time); } @@ -171,11 +171,11 @@ void mono_time_update(Mono_Time *mono_time) #ifndef ESP_PLATFORM pthread_rwlock_wrlock(mono_time->time_update_lock); -#endif +#endif /* ESP_PLATFORM */ mono_time->cur_time = cur_time; #ifndef ESP_PLATFORM pthread_rwlock_unlock(mono_time->time_update_lock); -#endif +#endif /* ESP_PLATFORM */ } uint64_t mono_time_get_ms(const Mono_Time *mono_time) @@ -183,11 +183,11 @@ uint64_t mono_time_get_ms(const Mono_Time *mono_time) #if !defined(ESP_PLATFORM) && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) // Fuzzing is only single thread for now, no locking needed */ pthread_rwlock_rdlock(mono_time->time_update_lock); -#endif +#endif /* !ESP_PLATFORM */ const uint64_t cur_time = mono_time->cur_time; #if !defined(ESP_PLATFORM) && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) pthread_rwlock_unlock(mono_time->time_update_lock); -#endif +#endif /* !ESP_PLATFORM */ return cur_time; } diff --git a/toxcore/mono_time.h b/toxcore/mono_time.h index bcd3d95b..d0f2b7a6 100644 --- a/toxcore/mono_time.h +++ b/toxcore/mono_time.h @@ -100,7 +100,7 @@ void mono_time_set_current_time_callback(Mono_Time *mono_time, mono_time_current_time_cb *current_time_callback, void *user_data); #ifdef __cplusplus -} +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_MONO_TIME_H +#endif /* C_TOXCORE_TOXCORE_MONO_TIME_H */ diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 1f53e696..1680b078 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -16,6 +16,7 @@ #include "LAN_discovery.h" #include "TCP_client.h" #include "TCP_connection.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "list.h" @@ -227,7 +228,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH]; memcpy(plain, c->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); - memset(plain + CRYPTO_PUBLIC_KEY_SIZE, 0, CRYPTO_PUBLIC_KEY_SIZE); + memzero(plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); memcpy(plain + (CRYPTO_PUBLIC_KEY_SIZE * 2), &number, sizeof(uint64_t)); const uint8_t *tmp_shared_key = dht_get_shared_key_sent(c->dht, dht_public_key); memcpy(shared_key, tmp_shared_key, CRYPTO_SHARED_KEY_SIZE); @@ -298,7 +299,6 @@ static int open_cookie(const Mono_Time *mono_time, uint8_t *bytes, const uint8_t return 0; } - /** @brief Create a cookie response packet and put it in packet. * @param request_plain must be COOKIE_REQUEST_PLAIN_LENGTH bytes. * @param packet must be of size COOKIE_RESPONSE_LENGTH or bigger. @@ -567,7 +567,6 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return true; } - non_null() static Crypto_Connection *get_crypto_connection(const Net_Crypto *c, int crypt_connection_id) { @@ -578,7 +577,6 @@ static Crypto_Connection *get_crypto_connection(const Net_Crypto *c, int crypt_c return &c->crypto_connections[crypt_connection_id]; } - /** @brief Associate an ip_port to a connection. * * @retval -1 on failure. @@ -694,7 +692,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t bool direct_send_attempt = false; pthread_mutex_lock(conn->mutex); - IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); + const IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); // TODO(irungentoo): on bad networks, direct connections might not last indefinitely. if (!net_family_is_unspec(ip_port.ip.family)) { @@ -748,7 +746,6 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t /*** START: Array Related functions */ - /** @brief Return number of packets in array * Note that holes are counted too. */ @@ -1116,7 +1113,7 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ increment_nonce(conn->sent_nonce); pthread_mutex_unlock(conn->mutex); - return send_packet_to(c, crypt_connection_id, packet, SIZEOF_VLA(packet)); + return send_packet_to(c, crypt_connection_id, packet, packet_size); } /** @brief Creates and sends a data packet with buffer_start and num to the peer using the fastest route. @@ -1136,13 +1133,14 @@ static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint3 num = net_htonl(num); buffer_start = net_htonl(buffer_start); const uint16_t padding_length = (MAX_CRYPTO_DATA_SIZE - length) % CRYPTO_MAX_PADDING; - VLA(uint8_t, packet, sizeof(uint32_t) + sizeof(uint32_t) + padding_length + length); + const uint16_t packet_size = sizeof(uint32_t) + sizeof(uint32_t) + padding_length + length; + VLA(uint8_t, packet, packet_size); memcpy(packet, &buffer_start, sizeof(uint32_t)); memcpy(packet + sizeof(uint32_t), &num, sizeof(uint32_t)); - memset(packet + (sizeof(uint32_t) * 2), PACKET_ID_PADDING, padding_length); + memzero(packet + (sizeof(uint32_t) * 2), padding_length); memcpy(packet + (sizeof(uint32_t) * 2) + padding_length, data, length); - return send_data_packet(c, crypt_connection_id, packet, SIZEOF_VLA(packet)); + return send_data_packet(c, crypt_connection_id, packet, packet_size); } non_null() @@ -1371,7 +1369,6 @@ static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint32 return num_sent; } - /** @brief Add a new temp packet to send repeatedly. * * @retval -1 on failure. @@ -1433,7 +1430,6 @@ static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id) return 0; } - /** @brief Send the temp packet. * * @retval -1 on failure. @@ -1506,9 +1502,9 @@ static int send_kill_packet(Net_Crypto *c, int crypt_connection_id) return -1; } - uint8_t kill_packet = PACKET_ID_KILL; + const uint8_t kill_packet[1] = {PACKET_ID_KILL}; return send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, conn->send_array.buffer_end, - &kill_packet, sizeof(kill_packet)); + kill_packet, sizeof(kill_packet)); } non_null(1) nullable(3) @@ -1589,7 +1585,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const const uint8_t *real_data = data + (sizeof(uint32_t) * 2); uint16_t real_length = len - (sizeof(uint32_t) * 2); - while (real_data[0] == PACKET_ID_PADDING) { /* Remove Padding */ + while (real_data[0] == 0) { /* Remove Padding */ ++real_data; --real_length; @@ -1675,7 +1671,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const } if (rtt_calc_time != 0) { - uint64_t rtt_time = current_time_monotonic(c->mono_time) - rtt_calc_time; + const uint64_t rtt_time = current_time_monotonic(c->mono_time) - rtt_calc_time; if (rtt_time < conn->rtt_time) { conn->rtt_time = rtt_time; @@ -1821,7 +1817,7 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) } Crypto_Connection *newcrypto_connections = (Crypto_Connection *)mem_vrealloc( - c->mem, c->crypto_connections, num, sizeof(Crypto_Connection)); + c->mem, c->crypto_connections, num, sizeof(Crypto_Connection)); if (newcrypto_connections == nullptr) { return -1; @@ -1831,7 +1827,6 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) return 0; } - /** @brief Create a new empty crypto connection. * * @retval -1 on failure. @@ -2000,7 +1995,6 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, return -1; } - /** @brief Set function to be called when someone requests a new connection to us. * * The set function should return -1 on failure and 0 on success. @@ -2227,9 +2221,8 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip return 0; } - non_null(1, 3) nullable(5) -static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_t *data, uint16_t length, +static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_t *packet, uint16_t length, void *userdata) { Net_Crypto *c = (Net_Crypto *)object; @@ -2244,14 +2237,14 @@ static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_ return -1; } - if (data[0] == NET_PACKET_COOKIE_REQUEST) { - return tcp_handle_cookie_request(c, conn->connection_number_tcp, data, length); + if (packet[0] == NET_PACKET_COOKIE_REQUEST) { + return tcp_handle_cookie_request(c, conn->connection_number_tcp, packet, length); } // This unlocks the mutex that at this point is locked by do_tcp before // calling do_tcp_connections. pthread_mutex_unlock(&c->tcp_mutex); - const int ret = handle_packet_connection(c, crypt_connection_id, data, length, false, userdata); + const int ret = handle_packet_connection(c, crypt_connection_id, packet, length, false, userdata); pthread_mutex_lock(&c->tcp_mutex); if (ret != 0) { @@ -2264,7 +2257,7 @@ static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_ non_null(1, 2, 4) nullable(6) static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned int tcp_connections_number, - const uint8_t *data, uint16_t length, void *userdata) + const uint8_t *packet, uint16_t length, void *userdata) { Net_Crypto *c = (Net_Crypto *)object; @@ -2272,14 +2265,14 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned in return -1; } - if (data[0] == NET_PACKET_COOKIE_REQUEST) { - return tcp_oob_handle_cookie_request(c, tcp_connections_number, public_key, data, length); + if (packet[0] == NET_PACKET_COOKIE_REQUEST) { + return tcp_oob_handle_cookie_request(c, tcp_connections_number, public_key, packet, length); } - if (data[0] == NET_PACKET_CRYPTO_HS) { - IP_Port source = tcp_connections_number_to_ip_port(tcp_connections_number); + if (packet[0] == NET_PACKET_CRYPTO_HS) { + const IP_Port source = tcp_connections_number_to_ip_port(tcp_connections_number); - if (handle_new_connection_handshake(c, &source, data, length, userdata) != 0) { + if (handle_new_connection_handshake(c, &source, packet, length, userdata) != 0) { return -1; } @@ -2380,7 +2373,7 @@ int send_tcp_forward_request(const Logger *logger, Net_Crypto *c, const IP_Port { pthread_mutex_lock(&c->tcp_mutex); const int ret = tcp_send_forward_request(logger, c->tcp_c, tcp_forwarder, dht_node, - chain_keys, chain_length, data, data_length); + chain_keys, chain_length, data, data_length); pthread_mutex_unlock(&c->tcp_mutex); return ret; @@ -2521,7 +2514,6 @@ int connection_lossy_data_handler(const Net_Crypto *c, int crypt_connection_id, return 0; } - /** @brief Set the function for this friend that will be callbacked with object and number if * the friend sends us a different dht public key than we have associated to him. * @@ -2815,8 +2807,8 @@ static void send_crypto_packets(Net_Crypto *c) 1000.0); n_packets += conn->last_packets_left_requested_rem; - uint32_t num_packets = n_packets; - double rem = n_packets - (double)num_packets; + const uint32_t num_packets = n_packets; + const double rem = n_packets - (double)num_packets; conn->packets_left_requested = num_packets; conn->last_packets_left_requested_set = temp_time; @@ -3162,7 +3154,7 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r networking_registerhandler(dht_get_net(dht), NET_PACKET_CRYPTO_HS, &udp_handle_packet, temp); networking_registerhandler(dht_get_net(dht), NET_PACKET_CRYPTO_DATA, &udp_handle_packet, temp); - bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8); + bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8, ipport_cmp_handler); return temp; } @@ -3193,7 +3185,7 @@ static void kill_timedout(Net_Crypto *c, void *userdata) /* do_timeout_here(); */ } -#endif +#endif /* 0 */ } } diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 939b672e..0d817e43 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -13,8 +13,14 @@ #include "DHT.h" #include "LAN_discovery.h" +#include "TCP_client.h" #include "TCP_connection.h" +#include "attributes.h" +#include "crypto_core.h" #include "logger.h" +#include "mem.h" +#include "mono_time.h" +#include "network.h" /*** Crypto payloads. */ @@ -44,7 +50,6 @@ /*** Messages. */ typedef enum Packet_Id { - PACKET_ID_PADDING = 0, // Denotes padding PACKET_ID_REQUEST = 1, // Used to request unreceived packets PACKET_ID_KILL = 2, // Used to kill connection @@ -135,7 +140,7 @@ typedef struct New_Connection { typedef int connection_status_cb(void *object, int id, bool status, void *userdata); typedef int connection_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); typedef int connection_lossy_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); -typedef void dht_pk_cb(void *data, int32_t number, const uint8_t *dht_public_key, void *userdata); +typedef void dht_pk_cb(void *object, int32_t number, const uint8_t *dht_public_key, void *userdata); typedef int new_connection_cb(void *object, const New_Connection *n_c); /** @brief Set function to be called when someone requests a new connection to us. @@ -200,7 +205,6 @@ non_null() int connection_data_handler(const Net_Crypto *c, int crypt_connection_id, connection_data_cb *connection_data_callback, void *object, int id); - /** @brief Set function to be called when connection with crypt_connection_id receives a lossy data packet of length. * * The set function should return -1 on failure and 0 on success. @@ -414,4 +418,4 @@ void do_net_crypto(Net_Crypto *c, void *userdata); nullable(1) void kill_net_crypto(Net_Crypto *c); -#endif +#endif /* C_TOXCORE_TOXCORE_NET_CRYPTO_H */ diff --git a/toxcore/network.c b/toxcore/network.c index 9c8bfdd2..55aa4e28 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -9,40 +9,34 @@ #ifdef __APPLE__ #define _DARWIN_C_SOURCE -#endif +#endif /* __APPLE__ */ // For Solaris. #ifdef __sun #define __EXTENSIONS__ 1 -#endif +#endif /* __sun */ // For Linux (and some BSDs). #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 700 -#endif +#endif /* _XOPEN_SOURCE */ -#if defined(_WIN32) && defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_WINXP +#if defined(_WIN32) && defined(_WIN32_WINNT) && defined(_WIN32_WINNT_WINXP) && _WIN32_WINNT >= _WIN32_WINNT_WINXP #undef _WIN32_WINNT #define _WIN32_WINNT 0x501 -#endif +#endif /* defined(_WIN32) && defined(_WIN32_WINNT) && defined(_WIN32_WINNT_WINXP) && _WIN32_WINNT >= _WIN32_WINNT_WINXP */ #if !defined(OS_WIN32) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) #define OS_WIN32 -#endif +#endif /* !defined(OS_WIN32) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) */ #if defined(OS_WIN32) && !defined(WINVER) // Windows XP #define WINVER 0x0501 -#endif +#endif /* defined(OS_WIN32) && !defined(WINVER) */ #include "network.h" -#ifdef PLAN9 -#include // Plan 9 requires this is imported first -// Comment line here to avoid reordering by source code formatters. -#include -#endif - #ifdef OS_WIN32 // Put win32 includes here // The mingw32/64 Windows library warns about including winsock2.h after // windows.h even though with the above it's a valid thing to do. So, to make @@ -51,12 +45,12 @@ // Comment line here to avoid reordering by source code formatters. #include #include -#endif +#endif /* OS_WIN32 */ #ifdef __APPLE__ #include #include -#endif +#endif /* __APPLE__ */ #if !defined(OS_WIN32) #include @@ -73,13 +67,13 @@ #ifdef __sun #include #include -#endif +#endif /* __sun */ #else #ifndef IPV6_V6ONLY #define IPV6_V6ONLY 27 -#endif -#endif +#endif /* IPV6_V6ONLY */ +#endif /* !defined(OS_WIN32) */ #include #include @@ -87,6 +81,8 @@ #include #include +#include "attributes.h" +#include "bin_pack.h" #include "ccompat.h" #include "logger.h" #include "mem.h" @@ -95,13 +91,13 @@ // Disable MSG_NOSIGNAL on systems not supporting it, e.g. Windows, FreeBSD #if !defined(MSG_NOSIGNAL) #define MSG_NOSIGNAL 0 -#endif +#endif /* !defined(MSG_NOSIGNAL) */ #ifndef IPV6_ADD_MEMBERSHIP #ifdef IPV6_JOIN_GROUP #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP -#endif -#endif +#endif /* IPV6_JOIN_GROUP */ +#endif /* IPV6_ADD_MEMBERSHIP */ static_assert(sizeof(IP4) == SIZE_IP4, "IP4 size must be 4"); @@ -148,7 +144,7 @@ static int inet_pton6(const char *addr_string, struct in6_addr *addrbuf) #else #ifndef IPV6_V6ONLY #define IPV6_V6ONLY 27 -#endif +#endif /* IPV6_V6ONLY */ static bool should_ignore_recv_error(int err) { @@ -228,7 +224,7 @@ static int inet_pton6(const char *addrString, struct in6_addr *addrbuf) return 1; } -#endif +#endif /* !defined(OS_WIN32) */ static_assert(TOX_INET6_ADDRSTRLEN >= INET6_ADDRSTRLEN, "TOX_INET6_ADDRSTRLEN should be greater or equal to INET6_ADDRSTRLEN (#INET6_ADDRSTRLEN)"); @@ -337,9 +333,7 @@ static void fill_addr6(const IP6 *ip, struct in6_addr *addr) #if !defined(INADDR_LOOPBACK) #define INADDR_LOOPBACK 0x7f000001 -#endif - -static const IP empty_ip = {{0}}; +#endif /* !defined(INADDR_LOOPBACK) */ IP4 get_ip4_broadcast(void) { @@ -365,19 +359,29 @@ IP4 get_ip4_loopback(void) IP6 get_ip6_loopback(void) { /* in6addr_loopback isn't available everywhere, so we do it ourselves. */ - IP6 loopback = empty_ip.ip.v6; + IP6 loopback = {{0}}; loopback.uint8[15] = 1; return loopback; } #ifndef OS_WIN32 #define INVALID_SOCKET (-1) -#endif +#endif /* OS_WIN32 */ + +int net_socket_to_native(Socket sock) +{ + return (force int)sock.value; +} + +Socket net_socket_from_native(int sock) +{ + const Socket res = {(force Socket_Value)sock}; + return res; +} Socket net_invalid_socket(void) { - const Socket invalid_socket = { (int)INVALID_SOCKET }; - return invalid_socket; + return net_socket_from_native(INVALID_SOCKET); } Family net_family_unspec(void) @@ -473,7 +477,7 @@ bool net_family_is_tox_tcp_ipv6(Family family) bool sock_valid(Socket sock) { const Socket invalid_socket = net_invalid_socket(); - return sock.sock != invalid_socket.sock; + return sock.value != invalid_socket.value; } struct Network_Addr { @@ -482,105 +486,107 @@ struct Network_Addr { }; non_null() -static int sys_close(void *obj, int sock) +static int sys_close(void *obj, Socket sock) { #if defined(OS_WIN32) - return closesocket(sock); + return closesocket(net_socket_to_native(sock)); #else // !OS_WIN32 - return close(sock); -#endif + return close(net_socket_to_native(sock)); +#endif /* OS_WIN32 */ } non_null() -static int sys_accept(void *obj, int sock) +static Socket sys_accept(void *obj, Socket sock) { - return accept(sock, nullptr, nullptr); + return net_socket_from_native(accept(net_socket_to_native(sock), nullptr, nullptr)); } non_null() -static int sys_bind(void *obj, int sock, const Network_Addr *addr) +static int sys_bind(void *obj, Socket sock, const Network_Addr *addr) { - return bind(sock, (const struct sockaddr *)&addr->addr, addr->size); + return bind(net_socket_to_native(sock), (const struct sockaddr *)&addr->addr, addr->size); } non_null() -static int sys_listen(void *obj, int sock, int backlog) +static int sys_listen(void *obj, Socket sock, int backlog) { - return listen(sock, backlog); + return listen(net_socket_to_native(sock), backlog); } non_null() -static int sys_recvbuf(void *obj, int sock) +static int sys_recvbuf(void *obj, Socket sock) { #ifdef OS_WIN32 u_long count = 0; - ioctlsocket(sock, FIONREAD, &count); + ioctlsocket(net_socket_to_native(sock), FIONREAD, &count); #else int count = 0; - ioctl(sock, FIONREAD, &count); -#endif + ioctl(net_socket_to_native(sock), FIONREAD, &count); +#endif /* OS_WIN32 */ return count; } non_null() -static int sys_recv(void *obj, int sock, uint8_t *buf, size_t len) +static int sys_recv(void *obj, Socket sock, uint8_t *buf, size_t len) { - return recv(sock, (char *)buf, len, MSG_NOSIGNAL); + return recv(net_socket_to_native(sock), (char *)buf, len, MSG_NOSIGNAL); } non_null() -static int sys_send(void *obj, int sock, const uint8_t *buf, size_t len) +static int sys_send(void *obj, Socket sock, const uint8_t *buf, size_t len) { - return send(sock, (const char *)buf, len, MSG_NOSIGNAL); + return send(net_socket_to_native(sock), (const char *)buf, len, MSG_NOSIGNAL); } non_null() -static int sys_sendto(void *obj, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr) { - return sendto(sock, (const char *)buf, len, 0, (const struct sockaddr *)&addr->addr, addr->size); +static int sys_sendto(void *obj, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr) +{ + return sendto(net_socket_to_native(sock), (const char *)buf, len, 0, (const struct sockaddr *)&addr->addr, addr->size); } non_null() -static int sys_recvfrom(void *obj, int sock, uint8_t *buf, size_t len, Network_Addr *addr) { +static int sys_recvfrom(void *obj, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) +{ socklen_t size = addr->size; - const int ret = recvfrom(sock, (char *)buf, len, 0, (struct sockaddr *)&addr->addr, &size); + const int ret = recvfrom(net_socket_to_native(sock), (char *)buf, len, 0, (struct sockaddr *)&addr->addr, &size); addr->size = size; return ret; } non_null() -static int sys_socket(void *obj, int domain, int type, int proto) +static Socket sys_socket(void *obj, int domain, int type, int proto) { - return (int)socket(domain, type, proto); + return net_socket_from_native(socket(domain, type, proto)); } non_null() -static int sys_socket_nonblock(void *obj, int sock, bool nonblock) +static int sys_socket_nonblock(void *obj, Socket sock, bool nonblock) { #ifdef OS_WIN32 u_long mode = nonblock ? 1 : 0; - return ioctlsocket(sock, FIONBIO, &mode); + return ioctlsocket(net_socket_to_native(sock), FIONBIO, &mode); #else - return fcntl(sock, F_SETFL, O_NONBLOCK, nonblock ? 1 : 0); + return fcntl(net_socket_to_native(sock), F_SETFL, O_NONBLOCK, nonblock ? 1 : 0); #endif /* OS_WIN32 */ } non_null() -static int sys_getsockopt(void *obj, int sock, int level, int optname, void *optval, size_t *optlen) +static int sys_getsockopt(void *obj, Socket sock, int level, int optname, void *optval, size_t *optlen) { socklen_t len = *optlen; - const int ret = getsockopt(sock, level, optname, (char *)optval, &len); + const int ret = getsockopt(net_socket_to_native(sock), level, optname, (char *)optval, &len); *optlen = len; return ret; } non_null() -static int sys_setsockopt(void *obj, int sock, int level, int optname, const void *optval, size_t optlen) +static int sys_setsockopt(void *obj, Socket sock, int level, int optname, const void *optval, size_t optlen) { - return setsockopt(sock, level, optname, (const char *)optval, optlen); + return setsockopt(net_socket_to_native(sock), level, optname, (const char *)optval, optlen); } -static const Network_Funcs system_network_funcs = { +static const Network_Funcs os_network_funcs = { sys_close, sys_accept, sys_bind, @@ -595,45 +601,45 @@ static const Network_Funcs system_network_funcs = { sys_getsockopt, sys_setsockopt, }; -static const Network system_network_obj = {&system_network_funcs}; +static const Network os_network_obj = {&os_network_funcs}; -const Network *system_network(void) +const Network *os_network(void) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if ((true)) { return nullptr; } -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ #ifdef OS_WIN32 WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) { return nullptr; } -#endif - return &system_network_obj; +#endif /* OS_WIN32 */ + return &os_network_obj; } #if 0 -/* TODO(iphydf): Call this from functions that use `system_network()`. */ -void system_network_deinit(const Network *ns) +/* TODO(iphydf): Call this from functions that use `os_network()`. */ +void os_network_deinit(const Network *ns) { #ifdef OS_WIN32 WSACleanup(); -#endif +#endif /* OS_WIN32 */ } -#endif +#endif /* 0 */ non_null() static int net_setsockopt(const Network *ns, Socket sock, int level, int optname, const void *optval, size_t optlen) { - return ns->funcs->setsockopt(ns->obj, sock.sock, level, optname, optval, optlen); + return ns->funcs->setsockopt(ns->obj, sock, level, optname, optval, optlen); } non_null() static int net_getsockopt(const Network *ns, Socket sock, int level, int optname, void *optval, size_t *optlen) { - return ns->funcs->getsockopt(ns->obj, sock.sock, level, optname, optval, optlen); + return ns->funcs->getsockopt(ns->obj, sock, level, optname, optval, optlen); } non_null() @@ -808,23 +814,23 @@ static void loglogdata(const Logger *log, const char *message, const uint8_t *bu int net_send(const Network *ns, const Logger *log, Socket sock, const uint8_t *buf, size_t len, const IP_Port *ip_port) { - const int res = ns->funcs->send(ns->obj, sock.sock, buf, len); + const int res = ns->funcs->send(ns->obj, sock, buf, len); loglogdata(log, "T=>", buf, len, ip_port, res); return res; } non_null() static int net_sendto( - const Network *ns, - Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr, const IP_Port *ip_port) + const Network *ns, + Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr, const IP_Port *ip_port) { - return ns->funcs->sendto(ns->obj, sock.sock, buf, len, addr); + return ns->funcs->sendto(ns->obj, sock, buf, len, addr); } int net_recv(const Network *ns, const Logger *log, Socket sock, uint8_t *buf, size_t len, const IP_Port *ip_port) { - const int res = ns->funcs->recv(ns->obj, sock.sock, buf, len); + const int res = ns->funcs->recv(ns->obj, sock, buf, len); loglogdata(log, "=>T", buf, len, ip_port, res); return res; } @@ -833,35 +839,34 @@ non_null() static int net_recvfrom(const Network *ns, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) { - return ns->funcs->recvfrom(ns->obj, sock.sock, buf, len, addr); + return ns->funcs->recvfrom(ns->obj, sock, buf, len, addr); } int net_listen(const Network *ns, Socket sock, int backlog) { - return ns->funcs->listen(ns->obj, sock.sock, backlog); + return ns->funcs->listen(ns->obj, sock, backlog); } non_null() static int net_bind(const Network *ns, Socket sock, const Network_Addr *addr) { - return ns->funcs->bind(ns->obj, sock.sock, addr); + return ns->funcs->bind(ns->obj, sock, addr); } Socket net_accept(const Network *ns, Socket sock) { - const Socket newsock = {ns->funcs->accept(ns->obj, sock.sock)}; - return newsock; + return ns->funcs->accept(ns->obj, sock); } /** Close the socket. */ void kill_sock(const Network *ns, Socket sock) { - ns->funcs->close(ns->obj, sock.sock); + ns->funcs->close(ns->obj, sock); } bool set_socket_nonblock(const Network *ns, Socket sock) { - return ns->funcs->socket_nonblock(ns->obj, sock.sock, true) == 0; + return ns->funcs->socket_nonblock(ns->obj, sock, true) == 0; } bool set_socket_nosigpipe(const Network *ns, Socket sock) @@ -871,7 +876,7 @@ bool set_socket_nosigpipe(const Network *ns, Socket sock) return net_setsockopt(ns, sock, SOL_SOCKET, SO_NOSIGPIPE, &set, sizeof(int)) == 0; #else return true; -#endif +#endif /* __APPLE__ */ } bool set_socket_reuseaddr(const Network *ns, Socket sock) @@ -894,7 +899,6 @@ bool set_socket_dualstack(const Network *ns, Socket sock) return net_setsockopt(ns, sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, sizeof(ipv6only)) == 0; } - typedef struct Packet_Handler { packet_handler_cb *function; void *object; @@ -1123,8 +1127,8 @@ void networking_poll(const Networking_Core *net, void *userdata) * If error is non NULL it is set to 0 if no issues, 1 if socket related error, 2 if other. */ Networking_Core *new_networking_ex( - const Logger *log, const Memory *mem, const Network *ns, const IP *ip, - uint16_t port_from, uint16_t port_to, unsigned int *error) + const Logger *log, const Memory *mem, const Network *ns, const IP *ip, + uint16_t port_from, uint16_t port_to, unsigned int *error) { /* If both from and to are 0, use default port range * If one is 0 and the other is non-0, use the non-0 value as only port @@ -1227,9 +1231,7 @@ Networking_Core *new_networking_ex( /* Bind our socket to port PORT and the given IP address (usually 0.0.0.0 or ::) */ uint16_t *portptr = nullptr; - Network_Addr addr; - - memset(&addr.addr, 0, sizeof(struct sockaddr_storage)); + Network_Addr addr = {{0}}; if (net_family_is_ipv4(temp->family)) { struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr.addr; @@ -1268,16 +1270,15 @@ Networking_Core *new_networking_ex( #ifndef ESP_PLATFORM /* multicast local nodes */ - struct ipv6_mreq mreq; - memset(&mreq, 0, sizeof(mreq)); - mreq.ipv6mr_multiaddr.s6_addr[ 0] = 0xFF; - mreq.ipv6mr_multiaddr.s6_addr[ 1] = 0x02; + struct ipv6_mreq mreq = {{{{0}}}}; + mreq.ipv6mr_multiaddr.s6_addr[0] = 0xFF; + mreq.ipv6mr_multiaddr.s6_addr[1] = 0x02; mreq.ipv6mr_multiaddr.s6_addr[15] = 0x01; mreq.ipv6mr_interface = 0; const int res = net_setsockopt(ns, temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); - int neterror = net_error(); + const int neterror = net_error(); char *strerror = net_new_strerror(neterror); if (res < 0) { @@ -1287,7 +1288,7 @@ Networking_Core *new_networking_ex( } net_kill_strerror(strerror); -#endif +#endif /* ESP_PLATFORM */ } /* A hanging program or a different user might block the standard port. @@ -1343,7 +1344,7 @@ Networking_Core *new_networking_ex( } Ip_Ntoa ip_str; - int neterror = net_error(); + const int neterror = net_error(); char *strerror = net_new_strerror(neterror); 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); @@ -1388,7 +1389,6 @@ void kill_networking(Networking_Core *net) mem_delete(net->mem, net); } - bool ip_equal(const IP *a, const IP *b) { if (a == nullptr || b == nullptr) { @@ -1444,6 +1444,63 @@ bool ipport_equal(const IP_Port *a, const IP_Port *b) return ip_equal(&a->ip, &b->ip); } +non_null() +static int ip4_cmp(const IP4 *a, const IP4 *b) +{ + return cmp_uint(a->uint32, b->uint32); +} + +non_null() +static int ip6_cmp(const IP6 *a, const IP6 *b) +{ + const int res = cmp_uint(a->uint64[0], b->uint64[0]); + if (res != 0) { + return res; + } + return cmp_uint(a->uint64[1], b->uint64[1]); +} + +non_null() +static int ip_cmp(const IP *a, const IP *b) +{ + const int res = cmp_uint(a->family.value, b->family.value); + if (res != 0) { + return res; + } + switch (a->family.value) { + case TOX_AF_UNSPEC: + return 0; + case TOX_AF_INET: + case TCP_INET: + case TOX_TCP_INET: + return ip4_cmp(&a->ip.v4, &b->ip.v4); + case TOX_AF_INET6: + case TCP_INET6: + case TOX_TCP_INET6: + case TCP_SERVER_FAMILY: // these happen to be ipv6 according to TCP_server.c. + case TCP_CLIENT_FAMILY: + return ip6_cmp(&a->ip.v6, &b->ip.v6); + } + // Invalid, we don't compare any further and consider them equal. + return 0; +} + +int ipport_cmp_handler(const void *a, const void *b, size_t size) +{ + const IP_Port *ipp_a = (const IP_Port *)a; + const IP_Port *ipp_b = (const IP_Port *)b; + assert(size == sizeof(IP_Port)); + + const int ip_res = ip_cmp(&ipp_a->ip, &ipp_b->ip); + if (ip_res != 0) { + return ip_res; + } + + return cmp_uint(ipp_a->port, ipp_b->port); +} + +static const IP empty_ip = {{0}}; + /** nulls out ip */ void ip_reset(IP *ip) { @@ -1454,6 +1511,8 @@ void ip_reset(IP *ip) *ip = empty_ip; } +static const IP_Port empty_ip_port = {{{0}}}; + /** nulls out ip_port */ void ipport_reset(IP_Port *ipport) { @@ -1461,7 +1520,6 @@ void ipport_reset(IP_Port *ipport) return; } - const IP_Port empty_ip_port = {{{0}}}; *ipport = empty_ip_port; } @@ -1472,7 +1530,7 @@ void ip_init(IP *ip, bool ipv6enabled) return; } - *ip = empty_ip; + ip_reset(ip); ip->family = ipv6enabled ? net_family_ipv6() : net_family_ipv4(); } @@ -1517,7 +1575,151 @@ void ipport_copy(IP_Port *target, const IP_Port *source) return; } - *target = *source; + // Write to a temporary object first, so that padding bytes are + // uninitialised and msan can catch mistakes in downstream code. + IP_Port tmp; + tmp.ip.family = source->ip.family; + tmp.ip.ip = source->ip.ip; + tmp.port = source->port; + + *target = tmp; +} + +/** @brief Packs an IP structure. + * + * It's the caller's responsibility to make sure `is_ipv4` tells the truth. This + * function is an implementation detail of @ref bin_pack_ip_port. + * + * @param is_ipv4 whether this IP is an IP4 or IP6. + * + * @retval true on success. + */ +non_null() +static bool bin_pack_ip(Bin_Pack *bp, const IP *ip, bool is_ipv4) +{ + if (is_ipv4) { + return bin_pack_bin_b(bp, ip->ip.v4.uint8, SIZE_IP4); + } else { + return bin_pack_bin_b(bp, ip->ip.v6.uint8, SIZE_IP6); + } +} + +/** @brief Packs an IP_Port structure. + * + * @retval true on success. + */ +bool bin_pack_ip_port(Bin_Pack *bp, const Logger *logger, const IP_Port *ip_port) +{ + bool is_ipv4; + uint8_t family; + + if (net_family_is_ipv4(ip_port->ip.family)) { + // TODO(irungentoo): use functions to convert endianness + is_ipv4 = true; + family = TOX_AF_INET; + } else if (net_family_is_tcp_ipv4(ip_port->ip.family)) { + is_ipv4 = true; + family = TOX_TCP_INET; + } else if (net_family_is_ipv6(ip_port->ip.family)) { + is_ipv4 = false; + family = TOX_AF_INET6; + } else if (net_family_is_tcp_ipv6(ip_port->ip.family)) { + is_ipv4 = false; + family = TOX_TCP_INET6; + } else { + Ip_Ntoa ip_str; + // TODO(iphydf): Find out why we're trying to pack invalid IPs, stop + // doing that, and turn this into an error. + LOGGER_TRACE(logger, "cannot pack invalid IP: %s", net_ip_ntoa(&ip_port->ip, &ip_str)); + return false; + } + + return bin_pack_u08_b(bp, family) + && bin_pack_ip(bp, &ip_port->ip, is_ipv4) + && bin_pack_u16_b(bp, net_ntohs(ip_port->port)); +} + +non_null() +static bool bin_pack_ip_port_handler(const void *obj, const Logger *logger, Bin_Pack *bp) +{ + const IP_Port *ip_port = (const IP_Port *)obj; + return bin_pack_ip_port(bp, logger, ip_port); +} + +int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_Port *ip_port) +{ + const uint32_t size = bin_pack_obj_size(bin_pack_ip_port_handler, ip_port, logger); + + if (size > length) { + return -1; + } + + if (!bin_pack_obj(bin_pack_ip_port_handler, ip_port, logger, data, length)) { + return -1; + } + + assert(size < INT_MAX); + return (int)size; +} + +int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool tcp_enabled) +{ + if (data == nullptr) { + return -1; + } + + bool is_ipv4; + Family host_family; + + if (data[0] == TOX_AF_INET) { + is_ipv4 = true; + host_family = net_family_ipv4(); + } else if (data[0] == TOX_TCP_INET) { + if (!tcp_enabled) { + return -1; + } + + is_ipv4 = true; + host_family = net_family_tcp_ipv4(); + } else if (data[0] == TOX_AF_INET6) { + is_ipv4 = false; + host_family = net_family_ipv6(); + } else if (data[0] == TOX_TCP_INET6) { + if (!tcp_enabled) { + return -1; + } + + is_ipv4 = false; + host_family = net_family_tcp_ipv6(); + } else { + return -1; + } + + ipport_reset(ip_port); + + if (is_ipv4) { + const uint32_t size = 1 + SIZE_IP4 + sizeof(uint16_t); + + if (size > length) { + return -1; + } + + ip_port->ip.family = host_family; + memcpy(ip_port->ip.ip.v4.uint8, data + 1, SIZE_IP4); + memcpy(&ip_port->port, data + 1 + SIZE_IP4, sizeof(uint16_t)); + return size; + } else { + const uint32_t size = 1 + SIZE_IP6 + sizeof(uint16_t); + + if (size > length) { + return -1; + } + + ip_port->ip.family = host_family; + memcpy(ip_port->ip.ip.v6.uint8, data + 1, SIZE_IP6); + memcpy(&ip_port->port, data + 1 + SIZE_IP6, sizeof(uint16_t)); + return size; + } } const char *net_ip_ntoa(const IP *ip, Ip_Ntoa *ip_str) @@ -1622,7 +1824,7 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr if ((true)) { return 0; } -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ if (address == nullptr || to == nullptr) { return 0; @@ -1631,8 +1833,7 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr const Family tox_family = to->family; const int family = make_family(tox_family); - struct addrinfo hints; - memset(&hints, 0, sizeof(hints)); + struct addrinfo hints = {0}; hints.ai_family = family; hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses. @@ -1750,14 +1951,14 @@ bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Por if ((true)) { return true; } -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ Ip_Ntoa ip_str; LOGGER_DEBUG(log, "connecting socket %d to %s:%d", - (int)sock.sock, net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port)); + net_socket_to_native(sock), net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port)); errno = 0; - if (connect(sock.sock, (struct sockaddr *)&addr, addrsize) == -1) { + if (connect(net_socket_to_native(sock), (struct sockaddr *)&addr, addrsize) == -1) { const int error = net_error(); // Non-blocking socket: "Operation in progress" means it's connecting. @@ -1807,7 +2008,7 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to *res = ip_port; return 1; } -#endif +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ // It's not an IP address, so now we try doing a DNS lookup. struct addrinfo *infos; @@ -1823,7 +2024,7 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to size_t count = 0; for (struct addrinfo *cur = infos; count < max_count && cur != nullptr; cur = cur->ai_next) { - if (cur->ai_socktype && type > 0 && cur->ai_socktype != type) { + if (cur->ai_socktype != 0 && type > 0 && cur->ai_socktype != type) { continue; } @@ -1852,16 +2053,16 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to *res = ip_port; for (struct addrinfo *cur = infos; cur != nullptr; cur = cur->ai_next) { - if (cur->ai_socktype && type > 0 && cur->ai_socktype != type) { + if (cur->ai_socktype != 0 && type > 0 && cur->ai_socktype != type) { continue; } if (cur->ai_family == AF_INET) { const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)cur->ai_addr; - memcpy(&ip_port->ip.ip.v4, &addr->sin_addr, sizeof(IP4)); + ip_port->ip.ip.v4.uint32 = addr->sin_addr.s_addr; } else if (cur->ai_family == AF_INET6) { const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(const void *)cur->ai_addr; - memcpy(&ip_port->ip.ip.v6, &addr->sin6_addr, sizeof(IP6)); + memcpy(ip_port->ip.ip.v6.uint8, addr->sin6_addr.s6_addr, sizeof(IP6)); } else { continue; } @@ -1917,13 +2118,12 @@ Socket net_socket(const Network *ns, Family domain, int type, int protocol) const int platform_domain = make_family(domain); const int platform_type = make_socktype(type); const int platform_prot = make_proto(protocol); - const Socket sock = {ns->funcs->socket(ns->obj, platform_domain, platform_type, platform_prot)}; - return sock; + return ns->funcs->socket(ns->obj, platform_domain, platform_type, platform_prot); } uint16_t net_socket_data_recv_buffer(const Network *ns, Socket sock) { - const int count = ns->funcs->recvbuf(ns->obj, sock.sock); + const int count = ns->funcs->recvbuf(ns->obj, sock); return (uint16_t)max_s32(0, min_s32(count, UINT16_MAX)); } @@ -2019,14 +2219,14 @@ bool ipv6_ipv4_in_v6(const IP6 *a) int net_error(void) { -#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +#ifdef OS_WIN32 return WSAGetLastError(); #else return errno; -#endif +#endif /* OS_WIN32 */ } -#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +#ifdef OS_WIN32 char *net_new_strerror(int error) { char *str = nullptr; @@ -2066,7 +2266,7 @@ static const char *net_strerror_r(int error, char *tmp, size_t tmp_size) return tmp; } -#endif +#endif /* GNU */ char *net_new_strerror(int error) { char tmp[256]; @@ -2086,13 +2286,13 @@ char *net_new_strerror(int error) return str; } -#endif +#endif /* OS_WIN32 */ void net_kill_strerror(char *strerror) { -#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +#ifdef OS_WIN32 LocalFree((char *)strerror); #else free(strerror); -#endif +#endif /* OS_WIN32 */ } diff --git a/toxcore/network.h b/toxcore/network.h index be7c52f7..06857b89 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -13,6 +13,8 @@ #include // size_t #include // uint*_t +#include "attributes.h" +#include "bin_pack.h" #include "logger.h" #include "mem.h" @@ -25,19 +27,27 @@ extern "C" { */ typedef struct Network_Addr Network_Addr; -typedef int net_close_cb(void *obj, int sock); -typedef int net_accept_cb(void *obj, int sock); -typedef int net_bind_cb(void *obj, int sock, const Network_Addr *addr); -typedef int net_listen_cb(void *obj, int sock, int backlog); -typedef int net_recvbuf_cb(void *obj, int sock); -typedef int net_recv_cb(void *obj, int sock, uint8_t *buf, size_t len); -typedef int net_recvfrom_cb(void *obj, int sock, uint8_t *buf, size_t len, Network_Addr *addr); -typedef int net_send_cb(void *obj, int sock, const uint8_t *buf, size_t len); -typedef int net_sendto_cb(void *obj, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr); -typedef int net_socket_cb(void *obj, int domain, int type, int proto); -typedef int net_socket_nonblock_cb(void *obj, int sock, bool nonblock); -typedef int net_getsockopt_cb(void *obj, int sock, int level, int optname, void *optval, size_t *optlen); -typedef int net_setsockopt_cb(void *obj, int sock, int level, int optname, const void *optval, size_t optlen); +typedef bitwise int Socket_Value; +typedef struct Socket { + Socket_Value value; +} Socket; + +int net_socket_to_native(Socket sock); +Socket net_socket_from_native(int sock); + +typedef int net_close_cb(void *obj, Socket sock); +typedef Socket net_accept_cb(void *obj, Socket sock); +typedef int net_bind_cb(void *obj, Socket sock, const Network_Addr *addr); +typedef int net_listen_cb(void *obj, Socket sock, int backlog); +typedef int net_recvbuf_cb(void *obj, Socket sock); +typedef int net_recv_cb(void *obj, Socket sock, uint8_t *buf, size_t len); +typedef int net_recvfrom_cb(void *obj, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr); +typedef int net_send_cb(void *obj, Socket sock, const uint8_t *buf, size_t len); +typedef int net_sendto_cb(void *obj, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr); +typedef Socket net_socket_cb(void *obj, int domain, int type, int proto); +typedef int net_socket_nonblock_cb(void *obj, Socket sock, bool nonblock); +typedef int net_getsockopt_cb(void *obj, Socket sock, int level, int optname, void *optval, size_t *optlen); +typedef int net_setsockopt_cb(void *obj, Socket sock, int level, int optname, const void *optval, size_t optlen); typedef int net_getaddrinfo_cb(void *obj, int family, Network_Addr **addrs); typedef int net_freeaddrinfo_cb(void *obj, Network_Addr *addrs); @@ -69,7 +79,7 @@ typedef struct Network { void *obj; } Network; -const Network *system_network(void); +const Network *os_network(void); typedef struct Family { uint8_t value; @@ -146,7 +156,6 @@ typedef enum Net_Packet_Type { NET_PACKET_MAX = 0xff, /* This type must remain within a single uint8. */ } Net_Packet_Type; - #define TOX_PORTRANGE_FROM 33445 #define TOX_PORTRANGE_TO 33545 #define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM @@ -210,10 +219,6 @@ typedef struct IP_Port { uint16_t port; } IP_Port; -typedef struct Socket { - int sock; -} Socket; - non_null() Socket net_socket(const Network *ns, Family domain, int type, int protocol); @@ -337,7 +342,7 @@ non_null() bool addr_parse_ip(const char *address, IP *to); /** - * Compares two IPAny structures. + * Compares two IP structures. * * Unset means unequal. * @@ -347,7 +352,7 @@ nullable(1, 2) bool ip_equal(const IP *a, const IP *b); /** - * Compares two IPAny_Port structures. + * Compares two IP_Port structures. * * Unset means unequal. * @@ -356,6 +361,18 @@ bool ip_equal(const IP *a, const IP *b); nullable(1, 2) bool ipport_equal(const IP_Port *a, const IP_Port *b); +/** + * @brief IP_Port comparison function with `memcmp` signature. + * + * Casts the void pointers to `IP_Port *` for comparison. + * + * @retval -1 if `a < b` + * @retval 0 if `a == b` + * @retval 1 if `a > b` + */ +non_null() +int ipport_cmp_handler(const void *a, const void *b, size_t size); + /** nulls out ip */ non_null() void ip_reset(IP *ip); @@ -399,7 +416,7 @@ bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP * Packet data is put into data. * Packet length is put into length. */ -typedef int packet_handler_cb(void *object, const IP_Port *ip_port, const uint8_t *data, uint16_t len, void *userdata); +typedef int packet_handler_cb(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata); typedef struct Networking_Core Networking_Core; @@ -506,6 +523,29 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to non_null(1) nullable(2) void net_freeipport(const Memory *mem, IP_Port *ip_ports); +non_null() +bool bin_pack_ip_port(Bin_Pack *bp, const Logger *logger, const IP_Port *ip_port); + +/** @brief Pack an IP_Port structure into data of max size length. + * + * Packed_length is the offset of data currently packed. + * + * @return size of packed IP_Port data on success. + * @retval -1 on failure. + */ +non_null() +int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_Port *ip_port); + +/** @brief Unpack IP_Port structure from data of max size length into ip_port. + * + * len_processed is the offset of data currently unpacked. + * + * @return size of unpacked ip_port on success. + * @retval -1 on failure. + */ +non_null() +int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool tcp_enabled); + /** * @return true on success, false on failure. */ @@ -553,8 +593,8 @@ void net_kill_strerror(char *strerror); */ non_null(1, 2, 3, 4) nullable(7) Networking_Core *new_networking_ex( - const Logger *log, const Memory *mem, const Network *ns, const IP *ip, - uint16_t port_from, uint16_t port_to, unsigned int *error); + const Logger *log, const Memory *mem, const Network *ns, const IP *ip, + uint16_t port_from, uint16_t port_to, unsigned int *error); non_null() Networking_Core *new_networking_no_udp(const Logger *log, const Memory *mem, const Network *ns); @@ -564,7 +604,7 @@ nullable(1) void kill_networking(Networking_Core *net); #ifdef __cplusplus -} // extern "C" +} /* extern "C" */ #endif -#endif +#endif /* C_TOXCORE_TOXCORE_NETWORK_H */ diff --git a/toxcore/network_test.cc b/toxcore/network_test.cc index a86436c8..8969c7d8 100644 --- a/toxcore/network_test.cc +++ b/toxcore/network_test.cc @@ -82,4 +82,90 @@ TEST(IpParseAddr, FormatsIPv6) EXPECT_EQ(std::string(ip_str), "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); } +TEST(IpportCmp, BehavesLikeMemcmp) +{ + auto cmp_val = [](int val) { return val < 0 ? -1 : val > 0 ? 1 : 0; }; + + IP_Port a = {0}; + IP_Port b = {0}; + + a.ip.family = net_family_ipv4(); + b.ip.family = net_family_ipv4(); + + a.port = 10; + b.port = 20; + + EXPECT_EQ( // + ipport_cmp_handler(&a, &b, sizeof(IP_Port)), -1) + << "a=" << a << "\n" + << "b=" << b; + EXPECT_EQ( // + ipport_cmp_handler(&a, &b, sizeof(IP_Port)), // + cmp_val(memcmp(&a, &b, sizeof(IP_Port)))) + << "a=" << a << "\n" + << "b=" << b; + + a.ip.ip.v4.uint8[0] = 192; + b.ip.ip.v4.uint8[0] = 10; + + EXPECT_EQ( // + ipport_cmp_handler(&a, &b, sizeof(IP_Port)), 1) + << "a=" << a << "\n" + << "b=" << b; + EXPECT_EQ( // + ipport_cmp_handler(&a, &b, sizeof(IP_Port)), // + cmp_val(memcmp(&a, &b, sizeof(IP_Port)))) + << "a=" << a << "\n" + << "b=" << b; +} + +TEST(IpportCmp, Ipv6BeginAndEndCompareCorrectly) +{ + IP_Port a = {0}; + IP_Port b = {0}; + + a.ip.family = net_family_ipv6(); + b.ip.family = net_family_ipv6(); + + a.ip.ip.v6.uint8[0] = 0xab; + b.ip.ip.v6.uint8[0] = 0xba; + + EXPECT_EQ(ipport_cmp_handler(&a, &b, sizeof(IP_Port)), -1); + + a.ip.ip.v6.uint8[0] = 0; + b.ip.ip.v6.uint8[0] = 0; + + a.ip.ip.v6.uint8[15] = 0xba; + + EXPECT_EQ(ipport_cmp_handler(&a, &b, sizeof(IP_Port)), 1); +} + +TEST(IpportCmp, UnspecAlwaysComparesEqual) +{ + IP_Port a = {0}; + IP_Port b = {0}; + + a.ip.family = net_family_unspec(); + b.ip.family = net_family_unspec(); + + a.ip.ip.v4.uint8[0] = 0xab; + b.ip.ip.v4.uint8[0] = 0xba; + + EXPECT_EQ(ipport_cmp_handler(&a, &b, sizeof(IP_Port)), 0); +} + +TEST(IpportCmp, InvalidAlwaysComparesEqual) +{ + IP_Port a = {0}; + IP_Port b = {0}; + + a.ip.family.value = 0xff; + b.ip.family.value = 0xff; + + a.ip.ip.v4.uint8[0] = 0xab; + b.ip.ip.v4.uint8[0] = 0xba; + + EXPECT_EQ(ipport_cmp_handler(&a, &b, sizeof(IP_Port)), 0); +} + } // namespace diff --git a/toxcore/network_test_util.cc b/toxcore/network_test_util.cc index 1f34e086..758e4950 100644 --- a/toxcore/network_test_util.cc +++ b/toxcore/network_test_util.cc @@ -2,6 +2,10 @@ #include +#include "crypto_core.h" +#include "network.h" +#include "test_util.hh" + Network_Funcs const Network_Class::vtable = { Method::invoke<&Network_Class::close>, Method::invoke<&Network_Class::accept>, @@ -20,49 +24,49 @@ Network_Funcs const Network_Class::vtable = { Method::invoke<&Network_Class::freeaddrinfo>, }; -int Test_Network::close(void *obj, int sock) { return net->funcs->close(net->obj, sock); } -int Test_Network::accept(void *obj, int sock) { return net->funcs->accept(net->obj, sock); } -int Test_Network::bind(void *obj, int sock, const Network_Addr *addr) +int Test_Network::close(void *obj, Socket sock) { return net->funcs->close(net->obj, sock); } +Socket Test_Network::accept(void *obj, Socket sock) { return net->funcs->accept(net->obj, sock); } +int Test_Network::bind(void *obj, Socket sock, const Network_Addr *addr) { return net->funcs->bind(net->obj, sock, addr); } -int Test_Network::listen(void *obj, int sock, int backlog) +int Test_Network::listen(void *obj, Socket sock, int backlog) { return net->funcs->listen(net->obj, sock, backlog); } -int Test_Network::recvbuf(void *obj, int sock) { return net->funcs->recvbuf(net->obj, sock); } -int Test_Network::recv(void *obj, int sock, uint8_t *buf, size_t len) +int Test_Network::recvbuf(void *obj, Socket sock) { return net->funcs->recvbuf(net->obj, sock); } +int Test_Network::recv(void *obj, Socket sock, uint8_t *buf, size_t len) { return net->funcs->recv(net->obj, sock, buf, len); } -int Test_Network::recvfrom(void *obj, int sock, uint8_t *buf, size_t len, Network_Addr *addr) +int Test_Network::recvfrom(void *obj, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) { return net->funcs->recvfrom(net->obj, sock, buf, len, addr); } -int Test_Network::send(void *obj, int sock, const uint8_t *buf, size_t len) +int Test_Network::send(void *obj, Socket sock, const uint8_t *buf, size_t len) { return net->funcs->send(net->obj, sock, buf, len); } int Test_Network::sendto( - void *obj, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr) + void *obj, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr) { return net->funcs->sendto(net->obj, sock, buf, len, addr); } -int Test_Network::socket(void *obj, int domain, int type, int proto) +Socket Test_Network::socket(void *obj, int domain, int type, int proto) { return net->funcs->socket(net->obj, domain, type, proto); } -int Test_Network::socket_nonblock(void *obj, int sock, bool nonblock) +int Test_Network::socket_nonblock(void *obj, Socket sock, bool nonblock) { return net->funcs->socket_nonblock(net->obj, sock, nonblock); } int Test_Network::getsockopt( - void *obj, int sock, int level, int optname, void *optval, size_t *optlen) + void *obj, Socket sock, int level, int optname, void *optval, size_t *optlen) { return net->funcs->getsockopt(net->obj, sock, level, optname, optval, optlen); } int Test_Network::setsockopt( - void *obj, int sock, int level, int optname, const void *optval, size_t optlen) + void *obj, Socket sock, int level, int optname, const void *optval, size_t optlen) { return net->funcs->setsockopt(net->obj, sock, level, optname, optval, optlen); } @@ -102,14 +106,11 @@ IP_Port random_ip_port(const Random *rng) return ip_port; } -bool operator==(Family const &a, Family const &b) { return a.value == b.value; } +bool operator==(Family a, Family b) { return a.value == b.value; } -bool operator==(IP4 const &a, IP4 const &b) { return a.uint32 == b.uint32; } +bool operator==(IP4 a, IP4 b) { return a.uint32 == b.uint32; } -bool operator==(IP6 const &a, IP6 const &b) -{ - return a.uint64[0] == b.uint64[0] && a.uint64[1] == b.uint64[1]; -} +bool operator==(IP6 a, IP6 b) { return a.uint64[0] == b.uint64[0] && a.uint64[1] == b.uint64[1]; } bool operator==(IP const &a, IP const &b) { diff --git a/toxcore/network_test_util.hh b/toxcore/network_test_util.hh index ede8397d..70f238aa 100644 --- a/toxcore/network_test_util.hh +++ b/toxcore/network_test_util.hh @@ -38,25 +38,28 @@ struct Network_Class { }; /** - * Base test Network class that just forwards to system_network. Can be + * Base test Network class that just forwards to os_network. Can be * subclassed to override individual (or all) functions. */ class Test_Network : public Network_Class { - const Network *net = REQUIRE_NOT_NULL(system_network()); + const Network *net = REQUIRE_NOT_NULL(os_network()); - int close(void *obj, int sock) override; - int accept(void *obj, int sock) override; - int bind(void *obj, int sock, const Network_Addr *addr) override; - int listen(void *obj, int sock, int backlog) override; - int recvbuf(void *obj, int sock) override; - int recv(void *obj, int sock, uint8_t *buf, size_t len) override; - int recvfrom(void *obj, int sock, uint8_t *buf, size_t len, Network_Addr *addr) override; - int send(void *obj, int sock, const uint8_t *buf, size_t len) override; - int sendto(void *obj, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr) override; - int socket(void *obj, int domain, int type, int proto) override; - int socket_nonblock(void *obj, int sock, bool nonblock) override; - int getsockopt(void *obj, int sock, int level, int optname, void *optval, size_t *optlen) override; - int setsockopt(void *obj, int sock, int level, int optname, const void *optval, size_t optlen) override; + int close(void *obj, Socket sock) override; + Socket accept(void *obj, Socket sock) override; + int bind(void *obj, Socket sock, const Network_Addr *addr) override; + int listen(void *obj, Socket sock, int backlog) override; + int recvbuf(void *obj, Socket sock) override; + int recv(void *obj, Socket sock, uint8_t *buf, size_t len) override; + int recvfrom(void *obj, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) override; + int send(void *obj, Socket sock, const uint8_t *buf, size_t len) override; + int sendto( + void *obj, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr) override; + Socket socket(void *obj, int domain, int type, int proto) override; + int socket_nonblock(void *obj, Socket sock, bool nonblock) override; + int getsockopt( + void *obj, Socket sock, int level, int optname, void *optval, size_t *optlen) override; + int setsockopt( + void *obj, Socket sock, int level, int optname, const void *optval, size_t optlen) override; int getaddrinfo(void *obj, int family, Network_Addr **addrs) override; int freeaddrinfo(void *obj, Network_Addr *addrs) override; }; @@ -80,10 +83,10 @@ public: IP_Port operator()(); }; -bool operator==(Family const &a, Family const &b); +bool operator==(Family a, Family b); -bool operator==(IP4 const &a, IP4 const &b); -bool operator==(IP6 const &a, IP6 const &b); +bool operator==(IP4 a, IP4 b); +bool operator==(IP6 a, IP6 b); bool operator==(IP const &a, IP const &b); bool operator==(IP_Port const &a, IP_Port const &b); diff --git a/toxcore/onion.c b/toxcore/onion.c index 0c4dfa58..9fab57af 100644 --- a/toxcore/onion.c +++ b/toxcore/onion.c @@ -12,6 +12,7 @@ #include #include "DHT.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "logger.h" @@ -19,6 +20,7 @@ #include "mono_time.h" #include "network.h" #include "shared_key_cache.h" +#include "util.h" #define RETURN_1 ONION_RETURN_1 #define RETURN_2 ONION_RETURN_2 @@ -31,7 +33,6 @@ #define KEY_REFRESH_INTERVAL (2 * 60 * 60) - // Settings for the shared key cache #define MAX_KEYS_PER_SLOT 4 #define KEYS_TIMEOUT 600 @@ -53,7 +54,7 @@ static void ip_pack_to_bytes(uint8_t *data, const IP *source) data[0] = source->family.value; if (net_family_is_ipv4(source->family) || net_family_is_tox_tcp_ipv4(source->family)) { - memset(data + 1, 0, SIZE_IP6); + memzero(data + 1, SIZE_IP6); memcpy(data + 1, source->ip.v4.uint8, SIZE_IP4); } else { memcpy(data + 1, source->ip.v6.uint8, SIZE_IP6); @@ -78,8 +79,8 @@ static int ip_unpack_from_bytes(IP *target, const uint8_t *data, unsigned int da } const bool valid = disable_family_check || - net_family_is_ipv4(target->family) || - net_family_is_ipv6(target->family); + net_family_is_ipv4(target->family) || + net_family_is_ipv6(target->family); return valid ? 0 : -1; } @@ -107,7 +108,6 @@ static int ipport_unpack(IP_Port *target, const uint8_t *data, unsigned int data return 0; } - /** @brief Create a new onion path. * * Create a new onion path out of nodes (nodes is a list of ONION_PATH_LENGTH nodes) @@ -188,7 +188,8 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_ return -1; } - VLA(uint8_t, step1, SIZE_IPPORT + length); + const uint16_t step1_size = SIZE_IPPORT + length; + VLA(uint8_t, step1, step1_size); ipport_pack(step1, dest); memcpy(step1 + SIZE_IPPORT, data, length); @@ -196,21 +197,23 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_ uint8_t nonce[CRYPTO_NONCE_SIZE]; random_nonce(rng, nonce); - VLA(uint8_t, step2, SIZE_IPPORT + SEND_BASE + length); + const uint16_t step2_size = SIZE_IPPORT + SEND_BASE + length; + VLA(uint8_t, step2, step2_size); ipport_pack(step2, &path->ip_port3); memcpy(step2 + SIZE_IPPORT, path->public_key3, CRYPTO_PUBLIC_KEY_SIZE); - int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, SIZEOF_VLA(step1), + int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, step1_size, step2 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE); if (len != SIZE_IPPORT + length + CRYPTO_MAC_SIZE) { return -1; } - VLA(uint8_t, step3, SIZE_IPPORT + SEND_BASE * 2 + length); + const uint16_t step3_size = SIZE_IPPORT + SEND_BASE * 2 + length; + VLA(uint8_t, step3, step3_size); ipport_pack(step3, &path->ip_port2); memcpy(step3 + SIZE_IPPORT, path->public_key2, CRYPTO_PUBLIC_KEY_SIZE); - len = encrypt_data_symmetric(path->shared_key2, nonce, step2, SIZEOF_VLA(step2), + len = encrypt_data_symmetric(path->shared_key2, nonce, step2, step2_size, step3 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE); if (len != SIZE_IPPORT + SEND_BASE + length + CRYPTO_MAC_SIZE) { @@ -221,7 +224,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_ memcpy(packet + 1, nonce, CRYPTO_NONCE_SIZE); memcpy(packet + 1 + CRYPTO_NONCE_SIZE, path->public_key1, CRYPTO_PUBLIC_KEY_SIZE); - len = encrypt_data_symmetric(path->shared_key1, nonce, step3, SIZEOF_VLA(step3), + len = encrypt_data_symmetric(path->shared_key1, nonce, step3, step3_size, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE); if (len != SIZE_IPPORT + SEND_BASE * 2 + length + CRYPTO_MAC_SIZE) { @@ -248,7 +251,8 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac return -1; } - VLA(uint8_t, step1, SIZE_IPPORT + length); + const uint16_t step1_size = SIZE_IPPORT + length; + VLA(uint8_t, step1, step1_size); ipport_pack(step1, dest); memcpy(step1 + SIZE_IPPORT, data, length); @@ -256,11 +260,12 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac uint8_t nonce[CRYPTO_NONCE_SIZE]; random_nonce(rng, nonce); - VLA(uint8_t, step2, SIZE_IPPORT + SEND_BASE + length); + const uint16_t step2_size = SIZE_IPPORT + SEND_BASE + length; + VLA(uint8_t, step2, step2_size); ipport_pack(step2, &path->ip_port3); memcpy(step2 + SIZE_IPPORT, path->public_key3, CRYPTO_PUBLIC_KEY_SIZE); - int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, SIZEOF_VLA(step1), + int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, step1_size, step2 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE); if (len != SIZE_IPPORT + length + CRYPTO_MAC_SIZE) { @@ -269,7 +274,7 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac ipport_pack(packet + CRYPTO_NONCE_SIZE, &path->ip_port2); memcpy(packet + CRYPTO_NONCE_SIZE + SIZE_IPPORT, path->public_key2, CRYPTO_PUBLIC_KEY_SIZE); - len = encrypt_data_symmetric(path->shared_key2, nonce, step2, SIZEOF_VLA(step2), + len = encrypt_data_symmetric(path->shared_key2, nonce, step2, step2_size, packet + CRYPTO_NONCE_SIZE + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE); if (len != SIZE_IPPORT + SEND_BASE + length + CRYPTO_MAC_SIZE) { @@ -350,7 +355,7 @@ static int handle_send_initial(void *object, const IP_Port *source, const uint8_ } const int len = decrypt_data_symmetric( - shared_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_length, plain); + shared_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_length, plain); if (len != plaintext_length) { LOGGER_TRACE(onion->log, "decrypt failed: %d != %d", len, plaintext_length); @@ -546,7 +551,6 @@ static int handle_send_2(void *object, const IP_Port *source, const uint8_t *pac return 0; } - non_null() static int handle_recv_3(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) { @@ -571,7 +575,7 @@ static int handle_recv_3(void *object, const IP_Port *source, const uint8_t *pac uint8_t plain[SIZE_IPPORT + RETURN_2]; const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, - SIZE_IPPORT + RETURN_2 + CRYPTO_MAC_SIZE, plain); + SIZE_IPPORT + RETURN_2 + CRYPTO_MAC_SIZE, plain); if ((uint32_t)len != sizeof(plain)) { return 1; @@ -624,7 +628,7 @@ static int handle_recv_2(void *object, const IP_Port *source, const uint8_t *pac uint8_t plain[SIZE_IPPORT + RETURN_1]; const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, - SIZE_IPPORT + RETURN_1 + CRYPTO_MAC_SIZE, plain); + SIZE_IPPORT + RETURN_1 + CRYPTO_MAC_SIZE, plain); if ((uint32_t)len != sizeof(plain)) { return 1; @@ -676,7 +680,7 @@ static int handle_recv_1(void *object, const IP_Port *source, const uint8_t *pac uint8_t plain[SIZE_IPPORT]; const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, - SIZE_IPPORT + CRYPTO_MAC_SIZE, plain); + SIZE_IPPORT + CRYPTO_MAC_SIZE, plain); if ((uint32_t)len != SIZE_IPPORT) { return 1; @@ -737,14 +741,13 @@ Onion *new_onion(const Logger *log, const Memory *mem, const Mono_Time *mono_tim onion->shared_keys_3 = shared_key_cache_new(log, mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); if (onion->shared_keys_1 == nullptr || - onion->shared_keys_2 == nullptr || - onion->shared_keys_3 == nullptr) { + onion->shared_keys_2 == nullptr || + onion->shared_keys_3 == nullptr) { // cppcheck-suppress mismatchAllocDealloc kill_onion(onion); return nullptr; } - networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_INITIAL, &handle_send_initial, onion); networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_1, &handle_send_1, onion); networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_2, &handle_send_2, onion); diff --git a/toxcore/onion.h b/toxcore/onion.h index 732d926c..a5d3554e 100644 --- a/toxcore/onion.h +++ b/toxcore/onion.h @@ -10,8 +10,12 @@ #define C_TOXCORE_TOXCORE_ONION_H #include "DHT.h" +#include "attributes.h" +#include "crypto_core.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" +#include "network.h" #include "shared_key_cache.h" typedef int onion_recv_1_cb(void *object, const IP_Port *dest, const uint8_t *data, uint16_t length); @@ -105,7 +109,6 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_ const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length); - /** @brief Create a onion packet to be sent over tcp. * * Use Onion_Path path to create packet for data of length to dest. @@ -154,5 +157,4 @@ Onion *new_onion(const Logger *log, const Memory *mem, const Mono_Time *mono_tim nullable(1) void kill_onion(Onion *onion); - -#endif +#endif /* C_TOXCORE_TOXCORE_ONION_H */ diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c index fe489c37..593d81aa 100644 --- a/toxcore/onion_announce.c +++ b/toxcore/onion_announce.c @@ -14,6 +14,7 @@ #include "DHT.h" #include "LAN_discovery.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "logger.h" @@ -192,11 +193,11 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_ * return 0 on success. */ int send_announce_request( - const Logger *log, const Networking_Core *net, const Random *rng, - const Onion_Path *path, const Node_format *dest, - const uint8_t *public_key, const uint8_t *secret_key, - const uint8_t *ping_id, const uint8_t *client_id, - const uint8_t *data_public_key, uint64_t sendback_data) + const Logger *log, const Networking_Core *net, const Random *rng, + const Onion_Path *path, const Node_format *dest, + const uint8_t *public_key, const uint8_t *secret_key, + const uint8_t *ping_id, const uint8_t *client_id, + const uint8_t *data_public_key, uint64_t sendback_data) { uint8_t request[ONION_ANNOUNCE_REQUEST_MIN_SIZE]; int len = create_announce_request(rng, request, sizeof(request), dest->public_key, public_key, secret_key, ping_id, @@ -237,9 +238,9 @@ int send_announce_request( * return 0 on success. */ int send_data_request( - const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, - const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, - const uint8_t *data, uint16_t length) + const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, + const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, + const uint8_t *data, uint16_t length) { uint8_t request[ONION_MAX_DATA_SIZE]; int len = create_data_request(rng, request, sizeof(request), public_key, encrypt_public_key, nonce, data, length); @@ -637,11 +638,12 @@ static int handle_data_request(void *object, const IP_Port *source, const uint8_ return 1; } - VLA(uint8_t, data, length - (CRYPTO_PUBLIC_KEY_SIZE + ONION_RETURN_3)); + const uint16_t data_size = length - (CRYPTO_PUBLIC_KEY_SIZE + ONION_RETURN_3); + VLA(uint8_t, data, data_size); data[0] = NET_PACKET_ONION_DATA_RESPONSE; memcpy(data + 1, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, length - (1 + CRYPTO_PUBLIC_KEY_SIZE + ONION_RETURN_3)); - if (send_onion_response(onion_a->log, onion_a->net, &onion_a->entries[index].ret_ip_port, data, SIZEOF_VLA(data), + if (send_onion_response(onion_a->log, onion_a->net, &onion_a->entries[index].ret_ip_port, data, data_size, onion_a->entries[index].ret) == -1) { return 1; } diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h index 90195351..11580931 100644 --- a/toxcore/onion_announce.h +++ b/toxcore/onion_announce.h @@ -9,7 +9,13 @@ #ifndef C_TOXCORE_TOXCORE_ONION_ANNOUNCE_H #define C_TOXCORE_TOXCORE_ONION_ANNOUNCE_H +#include "DHT.h" +#include "attributes.h" +#include "crypto_core.h" #include "logger.h" +#include "mem.h" +#include "mono_time.h" +#include "network.h" #include "onion.h" #include "timed_auth.h" @@ -95,11 +101,11 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_ */ non_null() int send_announce_request( - const Logger *log, const Networking_Core *net, const Random *rng, - const Onion_Path *path, const Node_format *dest, - const uint8_t *public_key, const uint8_t *secret_key, - const uint8_t *ping_id, const uint8_t *client_id, - const uint8_t *data_public_key, uint64_t sendback_data); + const Logger *log, const Networking_Core *net, const Random *rng, + const Onion_Path *path, const Node_format *dest, + const uint8_t *public_key, const uint8_t *secret_key, + const uint8_t *ping_id, const uint8_t *client_id, + const uint8_t *data_public_key, uint64_t sendback_data); /** @brief Create and send an onion data request packet. * @@ -119,10 +125,9 @@ int send_announce_request( */ non_null() int send_data_request( - const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, - const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, - const uint8_t *data, uint16_t length); - + const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, + const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, + const uint8_t *data, uint16_t length); typedef int pack_extra_data_cb(void *object, const Logger *logger, const Mono_Time *mono_time, uint8_t num_nodes, uint8_t *plain, uint16_t plain_size, @@ -138,4 +143,4 @@ Onion_Announce *new_onion_announce(const Logger *log, const Memory *mem, const R nullable(1) void kill_onion_announce(Onion_Announce *onion_a); -#endif +#endif /* C_TOXCORE_TOXCORE_ONION_ANNOUNCE_H */ diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index 56441ce1..9b0ac961 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -16,8 +16,10 @@ #include "DHT.h" #include "LAN_discovery.h" #include "TCP_connection.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" +#include "group_announce.h" #include "group_onion_announce.h" #include "logger.h" #include "mem.h" @@ -27,6 +29,7 @@ #include "onion.h" #include "onion_announce.h" #include "ping_array.h" +#include "timed_auth.h" #include "util.h" /** @brief defines for the array size and timeout for onion announce packets. */ @@ -480,17 +483,6 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa return 0; } -/** Does path with path_num exist. */ -non_null() -static bool path_exists(const Mono_Time *mono_time, const Onion_Client_Paths *onion_paths, uint32_t path_num) -{ - if (path_timed_out(mono_time, onion_paths, path_num)) { - return false; - } - - return onion_paths->paths[path_num % NUMBER_ONION_PATHS].path_num == path_num; -} - /** Set path timeouts, return the path number. */ non_null() static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, uint32_t path_num) @@ -1066,7 +1058,8 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con return 1; } - VLA(uint8_t, plain, 1 + ONION_PING_ID_SIZE + len_nodes); + const uint16_t plain_size = 1 + ONION_PING_ID_SIZE + len_nodes; + VLA(uint8_t, plain, plain_size); int len; const uint16_t nonce_start = 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH; const uint16_t ciphertext_start = nonce_start + CRYPTO_NONCE_SIZE; @@ -1090,8 +1083,8 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con return 1; } - if ((uint32_t)len != SIZEOF_VLA(plain)) { - LOGGER_WARNING(onion_c->logger, "decrypted size (%lu) is not the expected plain text size (%lu)", (unsigned long)len, (unsigned long)SIZEOF_VLA(plain)); + if ((uint32_t)len != plain_size) { + LOGGER_WARNING(onion_c->logger, "decrypted size (%lu) is not the expected plain text size (%u)", (unsigned long)len, plain_size); return 1; } @@ -1141,21 +1134,23 @@ static int handle_data_response(void *object, const IP_Port *source, const uint8 return 1; } - VLA(uint8_t, temp_plain, length - ONION_DATA_RESPONSE_MIN_SIZE); + const uint16_t temp_plain_size = length - ONION_DATA_RESPONSE_MIN_SIZE; + VLA(uint8_t, temp_plain, temp_plain_size); int len = decrypt_data(packet + 1 + CRYPTO_NONCE_SIZE, onion_c->temp_secret_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE), temp_plain); - if ((uint32_t)len != SIZEOF_VLA(temp_plain)) { + if ((uint32_t)len != temp_plain_size) { return 1; } - VLA(uint8_t, plain, SIZEOF_VLA(temp_plain) - DATA_IN_RESPONSE_MIN_SIZE); + const uint16_t plain_size = temp_plain_size - DATA_IN_RESPONSE_MIN_SIZE; + VLA(uint8_t, plain, plain_size); len = decrypt_data(temp_plain, nc_get_self_secret_key(onion_c->c), packet + 1, temp_plain + CRYPTO_PUBLIC_KEY_SIZE, - SIZEOF_VLA(temp_plain) - CRYPTO_PUBLIC_KEY_SIZE, plain); + temp_plain_size - CRYPTO_PUBLIC_KEY_SIZE, plain); - if ((uint32_t)len != SIZEOF_VLA(plain)) { + if ((uint32_t)len != plain_size) { return 1; } @@ -1164,7 +1159,7 @@ static int handle_data_response(void *object, const IP_Port *source, const uint8 } return onion_c->onion_data_handlers[plain[0]].function(onion_c->onion_data_handlers[plain[0]].object, temp_plain, plain, - SIZEOF_VLA(plain), userdata); + plain_size, userdata); } #define DHTPK_DATA_MIN_LENGTH (1 + sizeof(uint64_t) + CRYPTO_PUBLIC_KEY_SIZE) @@ -1307,13 +1302,14 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, uint8_t nonce[CRYPTO_NONCE_SIZE]; random_nonce(onion_c->rng, nonce); - VLA(uint8_t, packet, DATA_IN_RESPONSE_MIN_SIZE + length); + const uint16_t packet_size = DATA_IN_RESPONSE_MIN_SIZE + length; + VLA(uint8_t, packet, packet_size); memcpy(packet, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE); int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key, nc_get_self_secret_key(onion_c->c), nonce, data, length, packet + CRYPTO_PUBLIC_KEY_SIZE); - if ((uint32_t)len + CRYPTO_PUBLIC_KEY_SIZE != SIZEOF_VLA(packet)) { + if ((uint32_t)len + CRYPTO_PUBLIC_KEY_SIZE != packet_size) { return -1; } @@ -1329,7 +1325,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, uint8_t o_packet[ONION_MAX_PACKET_SIZE]; len = create_data_request( onion_c->rng, o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key, - node_list[good_nodes[i]].data_public_key, nonce, packet, SIZEOF_VLA(packet)); + node_list[good_nodes[i]].data_public_key, nonce, packet, packet_size); if (len == -1) { continue; @@ -1364,21 +1360,22 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin uint8_t nonce[CRYPTO_NONCE_SIZE]; random_nonce(onion_c->rng, nonce); - VLA(uint8_t, temp, DATA_IN_RESPONSE_MIN_SIZE + CRYPTO_NONCE_SIZE + length); + const uint16_t temp_size = DATA_IN_RESPONSE_MIN_SIZE + CRYPTO_NONCE_SIZE + length; + VLA(uint8_t, temp, temp_size); memcpy(temp, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE); memcpy(temp + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE); int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key, nc_get_self_secret_key(onion_c->c), nonce, data, length, temp + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); - if ((uint32_t)len + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE != SIZEOF_VLA(temp)) { + if ((uint32_t)len + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE != temp_size) { return -1; } uint8_t packet_data[MAX_CRYPTO_REQUEST_SIZE]; len = create_request( onion_c->rng, dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data, - onion_c->friends_list[friend_num].dht_public_key, temp, SIZEOF_VLA(temp), CRYPTO_PACKET_DHTPK); + onion_c->friends_list[friend_num].dht_public_key, temp, temp_size, CRYPTO_PACKET_DHTPK); assert(len <= UINT16_MAX); const Packet packet = {packet_data, (uint16_t)len}; @@ -1578,7 +1575,7 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num) dht_delfriend(onion_c->dht, onion_c->friends_list[friend_num].dht_public_key, 0); } -#endif +#endif /* 0 */ crypto_memzero(&onion_c->friends_list[friend_num], sizeof(Onion_Friend)); unsigned int i; @@ -1706,7 +1703,6 @@ int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_p return dht_getfriendip(onion_c->dht, dht_public_key, ip_port); } - /** @brief Set if friend is online or not. * * NOTE: This function is there and should be used so that we don't send @@ -1879,7 +1875,6 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum) } } - /** Function to call when onion data packet with contents beginning with byte is received. */ void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_cb *cb, void *object) { @@ -1911,6 +1906,33 @@ static bool key_list_contains(const uint8_t *const *keys, uint16_t keys_size, co return false; } +/** Does path with path_num exist. */ +non_null() +static bool path_exists(const Mono_Time *mono_time, const Onion_Client_Paths *onion_paths, uint32_t path_num) +{ + if (path_timed_out(mono_time, onion_paths, path_num)) { + return false; + } + + return onion_paths->paths[path_num % NUMBER_ONION_PATHS].path_num == path_num; +} + +/** + * A node/path is considered "stable" if it has survived for at least TIME_TO_STABLE + * and the latest packets sent to it are not timing out. + */ +non_null() +static bool path_is_stable(const Mono_Time *mono_time, const Onion_Client_Paths *paths, + uint32_t pathnum, const Onion_Node *node) +{ + return mono_time_is_timeout(mono_time, node->added_time, TIME_TO_STABLE) + && !(node->pings_since_last_response > 0 + && mono_time_is_timeout(mono_time, node->last_pinged, ONION_NODE_TIMEOUT)) + && mono_time_is_timeout(mono_time, paths->path_creation_time[pathnum], TIME_TO_STABLE) + && !(paths->last_path_used_times[pathnum] > 0 + && mono_time_is_timeout(mono_time, paths->last_path_used[pathnum], ONION_PATH_TIMEOUT)); +} + non_null() static void do_announce(Onion_Client *onion_c) { @@ -1934,7 +1956,6 @@ static void do_announce(Onion_Client *onion_c) continue; } - unsigned int interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED; if (node_list[i].is_stored != 0 @@ -1943,16 +1964,8 @@ static void do_announce(Onion_Client *onion_c) const uint32_t pathnum = node_list[i].path_used % NUMBER_ONION_PATHS; - /* A node/path is considered "stable", and can be pinged less - * aggressively, if it has survived for at least TIME_TO_STABLE - * and the latest packets sent to it are not timing out. - */ - if (mono_time_is_timeout(onion_c->mono_time, node_list[i].added_time, TIME_TO_STABLE) - && !(node_list[i].pings_since_last_response > 0 - && mono_time_is_timeout(onion_c->mono_time, node_list[i].last_pinged, ONION_NODE_TIMEOUT)) - && mono_time_is_timeout(onion_c->mono_time, onion_c->onion_paths_self.path_creation_time[pathnum], TIME_TO_STABLE) - && !(onion_c->onion_paths_self.last_path_used_times[pathnum] > 0 - && mono_time_is_timeout(onion_c->mono_time, onion_c->onion_paths_self.last_path_used[pathnum], ONION_PATH_TIMEOUT))) { + /* If a node/path is considered "stable", it can be pinged less aggressively. */ + if (path_is_stable(onion_c->mono_time, &onion_c->onion_paths_self, pathnum, &node_list[i])) { interval = ANNOUNCE_INTERVAL_STABLE; } } @@ -2021,7 +2034,7 @@ static void do_announce(Onion_Client *onion_c) } else { Ip_Ntoa ip_str; LOGGER_TRACE(onion_c->logger, "not sending repeated announce request to %s:%d", - net_ip_ntoa(&target->ip_port.ip, &ip_str), net_ntohs(target->ip_port.port)); + net_ip_ntoa(&target->ip_port.ip, &ip_str), net_ntohs(target->ip_port.port)); } } } diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h index 0b8fbffb..61e4e6fd 100644 --- a/toxcore/onion_client.h +++ b/toxcore/onion_client.h @@ -12,7 +12,14 @@ #include +#include "DHT.h" +#include "attributes.h" +#include "crypto_core.h" +#include "logger.h" +#include "mem.h" +#include "mono_time.h" #include "net_crypto.h" +#include "network.h" #include "onion_announce.h" #include "ping_array.h" @@ -145,7 +152,7 @@ non_null() int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, recv_tcp_relay_cb *callback, void *object, uint32_t number); -typedef void onion_dht_pk_cb(void *data, int32_t number, const uint8_t *dht_public_key, void *userdata); +typedef void onion_dht_pk_cb(void *object, int32_t number, const uint8_t *dht_public_key, void *userdata); /** @brief Set the function for this friend that will be callbacked with object and number * when that friend gives us their DHT temporary public key. @@ -191,7 +198,7 @@ non_null() int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, uint16_t length); typedef int oniondata_handler_cb(void *object, const uint8_t *source_pubkey, const uint8_t *data, - uint16_t len, void *userdata); + uint16_t length, void *userdata); /** Function to call when onion data packet with contents beginning with byte is received. */ non_null(1) nullable(3, 4) @@ -213,7 +220,6 @@ Onion_Client *new_onion_client(const Logger *logger, const Memory *mem, const Ra nullable(1) void kill_onion_client(Onion_Client *onion_c); - typedef enum Onion_Connection_Status { /** We are not connected to the network. */ ONION_CONNECTION_STATUS_NONE = 0, @@ -237,4 +243,4 @@ non_null(1) nullable(2) void onion_friend_set_gc_data(Onion_Friend *onion_friend, const uint8_t *gc_data, uint16_t gc_data_length); non_null() bool onion_friend_is_groupchat(const Onion_Friend *onion_friend); -#endif +#endif /* C_TOXCORE_TOXCORE_ONION_CLIENT_H */ diff --git a/toxcore/ping.c b/toxcore/ping.c index dc7658a2..303c418c 100644 --- a/toxcore/ping.c +++ b/toxcore/ping.c @@ -12,6 +12,7 @@ #include #include "DHT.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "mem.h" @@ -27,7 +28,6 @@ /** Ping newly announced nodes to ping per TIME_TO_PING seconds*/ #define TIME_TO_PING 2 - struct Ping { const Mono_Time *mono_time; const Random *rng; @@ -38,7 +38,6 @@ struct Ping { uint64_t last_to_ping; }; - #define PING_PLAIN_SIZE (1 + sizeof(uint64_t)) #define DHT_PING_SIZE (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + PING_PLAIN_SIZE + CRYPTO_MAC_SIZE) #define PING_DATA_SIZE (CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port)) @@ -53,7 +52,6 @@ void ping_send_request(Ping *ping, const IP_Port *ipp, const uint8_t *public_key return; } - // generate key to encrypt ping_id with recipient privkey const uint8_t *shared_key = dht_get_shared_key_sent(ping->dht, public_key); // Generate random ping_id. @@ -74,7 +72,6 @@ void ping_send_request(Ping *ping, const IP_Port *ipp, const uint8_t *public_key pk_copy(pk + 1, dht_get_self_public_key(ping->dht)); // Our pubkey random_nonce(ping->rng, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce - rc = encrypt_data_symmetric(shared_key, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE, ping_plain, sizeof(ping_plain), @@ -301,7 +298,6 @@ int32_t ping_add(Ping *ping, const uint8_t *public_key, const IP_Port *ip_port) return -1; } - /** @brief Ping all the valid nodes in the to_ping list every TIME_TO_PING seconds. * This function must be run at least once every TIME_TO_PING seconds. */ @@ -335,7 +331,6 @@ void ping_iterate(Ping *ping) } } - Ping *ping_new(const Memory *mem, const Mono_Time *mono_time, const Random *rng, DHT *dht) { Ping *ping = (Ping *)mem_alloc(mem, sizeof(Ping)); diff --git a/toxcore/ping.h b/toxcore/ping.h index c5613459..b0339ec7 100644 --- a/toxcore/ping.h +++ b/toxcore/ping.h @@ -13,6 +13,10 @@ #include #include "DHT.h" +#include "attributes.h" +#include "crypto_core.h" +#include "mem.h" +#include "mono_time.h" #include "network.h" typedef struct Ping Ping; @@ -45,4 +49,4 @@ void ping_iterate(Ping *ping); non_null() void ping_send_request(Ping *ping, const IP_Port *ipp, const uint8_t *public_key); -#endif // C_TOXCORE_TOXCORE_PING_H +#endif /* C_TOXCORE_TOXCORE_PING_H */ diff --git a/toxcore/ping_array.c b/toxcore/ping_array.c index 6ba1cf68..c40215ea 100644 --- a/toxcore/ping_array.c +++ b/toxcore/ping_array.c @@ -10,6 +10,7 @@ #include +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "mem.h" diff --git a/toxcore/ping_array.h b/toxcore/ping_array.h index 5fc04017..3e50e668 100644 --- a/toxcore/ping_array.h +++ b/toxcore/ping_array.h @@ -12,6 +12,7 @@ #include #include +#include "attributes.h" #include "crypto_core.h" #include "mem.h" #include "mono_time.h" @@ -60,7 +61,7 @@ int32_t ping_array_check(Ping_Array *array, const Mono_Time *mono_time, uint8_t uint64_t ping_id); #ifdef __cplusplus -} // extern "C" +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_PING_ARRAY_H +#endif /* C_TOXCORE_TOXCORE_PING_ARRAY_H */ diff --git a/toxcore/ping_array_test.cc b/toxcore/ping_array_test.cc index 6f6f4c21..cc9d0bfc 100644 --- a/toxcore/ping_array_test.cc +++ b/toxcore/ping_array_test.cc @@ -4,6 +4,7 @@ #include +#include "crypto_core_test_util.hh" #include "mem_test_util.hh" #include "mono_time.h" @@ -23,7 +24,7 @@ struct Mono_Time_Deleter { void operator()(Mono_Time *arr) { mono_time_free(mem_, arr); } private: - const Memory *mem_; + const Test_Memory &mem_; }; using Mono_Time_Ptr = std::unique_ptr; @@ -61,12 +62,11 @@ TEST(PingArray, ArraySizeMustBePowerOfTwo) TEST(PingArray, StoredDataCanBeRetrieved) { Test_Memory mem; + Test_Random rng; Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); ASSERT_NE(mono_time, nullptr); - const Random *rng = system_random(); - ASSERT_NE(rng, nullptr); uint64_t const ping_id = ping_array_add( arr.get(), mono_time.get(), rng, std::vector{1, 2, 3, 4}.data(), 4); @@ -80,12 +80,11 @@ TEST(PingArray, StoredDataCanBeRetrieved) TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect) { Test_Memory mem; + Test_Random rng; Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); ASSERT_NE(mono_time, nullptr); - const Random *rng = system_random(); - ASSERT_NE(rng, nullptr); uint64_t const ping_id = ping_array_add( arr.get(), mono_time.get(), rng, (std::vector{1, 2, 3, 4}).data(), 4); @@ -103,12 +102,11 @@ TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect) TEST(PingArray, ZeroLengthDataCanBeAdded) { Test_Memory mem; + Test_Random rng; Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); ASSERT_NE(mono_time, nullptr); - const Random *rng = system_random(); - ASSERT_NE(rng, nullptr); uint8_t c = 0; uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), rng, &c, sizeof(c)); @@ -133,12 +131,11 @@ TEST(PingArray, PingId0IsInvalid) TEST(PingArray, DataCanOnlyBeRetrievedOnce) { Test_Memory mem; + Test_Random rng; Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); ASSERT_NE(mono_time, nullptr); - const Random *rng = system_random(); - ASSERT_NE(rng, nullptr); uint8_t c = 0; uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), rng, &c, sizeof(c)); @@ -151,12 +148,11 @@ TEST(PingArray, DataCanOnlyBeRetrievedOnce) TEST(PingArray, PingIdMustMatchOnCheck) { Test_Memory mem; + Test_Random rng; Ping_Array_Ptr const arr(ping_array_new(mem, 1, 1)); Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); ASSERT_NE(mono_time, nullptr); - const Random *rng = system_random(); - ASSERT_NE(rng, nullptr); uint8_t c = 0; uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), rng, &c, sizeof(c)); diff --git a/toxcore/shared_key_cache.c b/toxcore/shared_key_cache.c index b52869b7..80d74aec 100644 --- a/toxcore/shared_key_cache.c +++ b/toxcore/shared_key_cache.c @@ -7,6 +7,7 @@ #include #include // memcpy(...) +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "logger.h" @@ -21,7 +22,7 @@ typedef struct Shared_Key { struct Shared_Key_Cache { Shared_Key *keys; - const uint8_t* self_secret_key; + const uint8_t *self_secret_key; uint64_t timeout; /** After this time (in seconds), a key is erased on the next housekeeping cycle */ const Mono_Time *mono_time; const Memory *mem; @@ -30,7 +31,8 @@ struct Shared_Key_Cache { }; non_null() -static bool shared_key_is_empty(const Logger *log, const Shared_Key *k) { +static bool shared_key_is_empty(const Logger *log, const Shared_Key *k) +{ LOGGER_ASSERT(log, k != nullptr, "shared key must not be NULL"); /* * Since time can never be 0, we use that to determine if a key slot is empty. @@ -40,8 +42,9 @@ static bool shared_key_is_empty(const Logger *log, const Shared_Key *k) { } non_null() -static void shared_key_set_empty(const Logger *log, Shared_Key *k) { - crypto_memzero(k, sizeof (Shared_Key)); +static void shared_key_set_empty(const Logger *log, Shared_Key *k) +{ + crypto_memzero(k, sizeof(Shared_Key)); LOGGER_ASSERT(log, shared_key_is_empty(log, k), "shared key must be empty after clearing it"); } @@ -93,8 +96,8 @@ void shared_key_cache_free(Shared_Key_Cache *cache) const size_t cache_size = 256 * cache->keys_per_slot; // Don't leave key material in memory - crypto_memzero(cache->keys, cache_size * sizeof (Shared_Key)); - crypto_memunlock(cache->keys, cache_size * sizeof (Shared_Key)); + crypto_memzero(cache->keys, cache_size * sizeof(Shared_Key)); + crypto_memunlock(cache->keys, cache_size * sizeof(Shared_Key)); mem_delete(cache->mem, cache->keys); mem_delete(cache->mem, cache); } @@ -106,12 +109,12 @@ const uint8_t *shared_key_cache_lookup(Shared_Key_Cache *cache, const uint8_t pu const uint64_t cur_time = mono_time_get(cache->mono_time); // We can't use the first and last bytes because they are masked in curve25519. Selected 8 for good alignment. const uint8_t bucket_idx = public_key[8]; - Shared_Key* bucket_start = &cache->keys[bucket_idx*cache->keys_per_slot]; + Shared_Key *bucket_start = &cache->keys[bucket_idx * cache->keys_per_slot]; - const uint8_t* found = nullptr; + const uint8_t *found = nullptr; // Perform lookup - for(size_t i = 0; i < cache->keys_per_slot; ++i) { + for (size_t i = 0; i < cache->keys_per_slot; ++i) { if (shared_key_is_empty(cache->log, &bucket_start[i])) { continue; } diff --git a/toxcore/shared_key_cache.h b/toxcore/shared_key_cache.h index b7112720..f6e84c31 100644 --- a/toxcore/shared_key_cache.h +++ b/toxcore/shared_key_cache.h @@ -7,6 +7,7 @@ #include // uint*_t +#include "attributes.h" #include "crypto_core.h" #include "logger.h" #include "mem.h" @@ -29,9 +30,9 @@ typedef struct Shared_Key_Cache Shared_Key_Cache; */ non_null() Shared_Key_Cache *shared_key_cache_new( - const Logger *log, const Mono_Time *mono_time, const Memory *mem, - const uint8_t *self_secret_key, - uint64_t timeout, uint8_t keys_per_slot); + const Logger *log, const Mono_Time *mono_time, const Memory *mem, + const uint8_t *self_secret_key, + uint64_t timeout, uint8_t keys_per_slot); /** * @brief Deletes the cache and frees all resources. @@ -49,6 +50,6 @@ void shared_key_cache_free(Shared_Key_Cache *cache); * @return nullptr on error. */ non_null() -const uint8_t* shared_key_cache_lookup(Shared_Key_Cache *cache, const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]); +const uint8_t *shared_key_cache_lookup(Shared_Key_Cache *cache, const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]); -#endif // C_TOXCORE_TOXCORE_SHARED_KEY_CACHE_H +#endif /* C_TOXCORE_TOXCORE_SHARED_KEY_CACHE_H */ diff --git a/toxcore/state.c b/toxcore/state.c index 69f11f3c..6835ca00 100644 --- a/toxcore/state.c +++ b/toxcore/state.c @@ -18,7 +18,6 @@ int state_load(const Logger *log, state_load_cb *state_load_callback, void *oute return -1; } - const uint32_t size_head = sizeof(uint32_t) * 2; while (length >= size_head) { @@ -86,7 +85,7 @@ uint16_t lendian_to_host16(uint16_t lendian) return (lendian << 8) | (lendian >> 8); #else return lendian; -#endif +#endif /* WORDS_BIGENDIAN */ } uint16_t host_to_lendian16(uint16_t host) @@ -100,7 +99,7 @@ void host_to_lendian_bytes64(uint8_t *dest, uint64_t num) num = ((num << 8) & 0xFF00FF00FF00FF00) | ((num >> 8) & 0xFF00FF00FF00FF); num = ((num << 16) & 0xFFFF0000FFFF0000) | ((num >> 16) & 0xFFFF0000FFFF); num = (num << 32) | (num >> 32); -#endif +#endif /* WORDS_BIGENDIAN */ memcpy(dest, &num, sizeof(uint64_t)); } @@ -112,7 +111,7 @@ void lendian_bytes_to_host64(uint64_t *dest, const uint8_t *lendian) d = ((d << 8) & 0xFF00FF00FF00FF00) | ((d >> 8) & 0xFF00FF00FF00FF); d = ((d << 16) & 0xFFFF0000FFFF0000) | ((d >> 16) & 0xFFFF0000FFFF); d = (d << 32) | (d >> 32); -#endif +#endif /* WORDS_BIGENDIAN */ *dest = d; } @@ -121,7 +120,7 @@ void host_to_lendian_bytes32(uint8_t *dest, uint32_t num) #ifdef WORDS_BIGENDIAN num = ((num << 8) & 0xFF00FF00) | ((num >> 8) & 0xFF00FF); num = (num << 16) | (num >> 16); -#endif +#endif /* WORDS_BIGENDIAN */ memcpy(dest, &num, sizeof(uint32_t)); } @@ -132,7 +131,7 @@ void lendian_bytes_to_host32(uint32_t *dest, const uint8_t *lendian) #ifdef WORDS_BIGENDIAN d = ((d << 8) & 0xFF00FF00) | ((d >> 8) & 0xFF00FF); d = (d << 16) | (d >> 16); -#endif +#endif /* WORDS_BIGENDIAN */ *dest = d; } @@ -140,7 +139,7 @@ void host_to_lendian_bytes16(uint8_t *dest, uint16_t num) { #ifdef WORDS_BIGENDIAN num = (num << 8) | (num >> 8); -#endif +#endif /* WORDS_BIGENDIAN */ memcpy(dest, &num, sizeof(uint16_t)); } @@ -150,6 +149,6 @@ void lendian_bytes_to_host16(uint16_t *dest, const uint8_t *lendian) memcpy(&d, lendian, sizeof(uint16_t)); #ifdef WORDS_BIGENDIAN d = (d << 8) | (d >> 8); -#endif +#endif /* WORDS_BIGENDIAN */ *dest = d; } diff --git a/toxcore/state.h b/toxcore/state.h index 0cc188d5..ebe0c372 100644 --- a/toxcore/state.h +++ b/toxcore/state.h @@ -17,6 +17,7 @@ #ifndef C_TOXCORE_TOXCORE_STATE_H #define C_TOXCORE_TOXCORE_STATE_H +#include "attributes.h" #include "logger.h" #ifdef __cplusplus @@ -51,7 +52,7 @@ typedef enum State_Load_Status { STATE_LOAD_STATUS_END, } State_Load_Status; -typedef State_Load_Status state_load_cb(void *outer, const uint8_t *data, uint32_t len, uint16_t type); +typedef State_Load_Status state_load_cb(void *outer, const uint8_t *data, uint32_t length, uint16_t type); /** state load/save */ non_null() @@ -82,7 +83,7 @@ non_null() void lendian_bytes_to_host16(uint16_t *dest, const uint8_t *lendian); #ifdef __cplusplus -} // extern "C" +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_STATE_H +#endif /* C_TOXCORE_TOXCORE_STATE_H */ diff --git a/toxcore/test_util_test.cc b/toxcore/test_util_test.cc index 2ef2e944..8dc97ab5 100644 --- a/toxcore/test_util_test.cc +++ b/toxcore/test_util_test.cc @@ -5,6 +5,7 @@ #include +#include "crypto_core.h" #include "crypto_core_test_util.hh" namespace { diff --git a/toxcore/timed_auth.c b/toxcore/timed_auth.c index a52f9d9a..87500325 100644 --- a/toxcore/timed_auth.c +++ b/toxcore/timed_auth.c @@ -5,11 +5,12 @@ #include +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "mono_time.h" -non_null(1,6) nullable(4) +non_null(1, 6) nullable(4) static void create_timed_auth_to_hash(const Mono_Time *mono_time, uint16_t timeout, bool previous, const uint8_t *data, uint16_t length, uint8_t *to_hash) { @@ -24,20 +25,22 @@ static void create_timed_auth_to_hash(const Mono_Time *mono_time, uint16_t timeo void generate_timed_auth(const Mono_Time *mono_time, uint16_t timeout, const uint8_t *key, const uint8_t *data, uint16_t length, uint8_t *timed_auth) { - VLA(uint8_t, to_hash, sizeof(uint64_t) + length); + const uint16_t to_hash_size = sizeof(uint64_t) + length; + VLA(uint8_t, to_hash, to_hash_size); create_timed_auth_to_hash(mono_time, timeout, false, data, length, to_hash); - crypto_hmac(timed_auth, key, to_hash, SIZEOF_VLA(to_hash)); + crypto_hmac(timed_auth, key, to_hash, to_hash_size); } bool check_timed_auth(const Mono_Time *mono_time, uint16_t timeout, const uint8_t *key, const uint8_t *data, uint16_t length, const uint8_t *timed_auth) { - VLA(uint8_t, to_hash, sizeof(uint64_t) + length); + const uint16_t to_hash_size = sizeof(uint64_t) + length; + VLA(uint8_t, to_hash, to_hash_size); for (uint8_t i = 0; i < 2; ++i) { create_timed_auth_to_hash(mono_time, timeout, i != 0, data, length, to_hash); - if (crypto_hmac_verify(timed_auth, key, to_hash, SIZEOF_VLA(to_hash))) { + if (crypto_hmac_verify(timed_auth, key, to_hash, to_hash_size)) { return true; } } diff --git a/toxcore/timed_auth.h b/toxcore/timed_auth.h index 691b04d0..bb195708 100644 --- a/toxcore/timed_auth.h +++ b/toxcore/timed_auth.h @@ -4,6 +4,7 @@ #ifndef C_TOXCORE_TOXCORE_TIMED_AUTH_H #define C_TOXCORE_TOXCORE_TIMED_AUTH_H +#include "attributes.h" #include "crypto_core.h" #include "mono_time.h" @@ -32,4 +33,4 @@ void generate_timed_auth(const Mono_Time *mono_time, uint16_t timeout, const uin non_null(1, 3, 6) nullable(4) bool check_timed_auth(const Mono_Time *mono_time, uint16_t timeout, const uint8_t *key, const uint8_t *data, uint16_t length, const uint8_t *timed_auth); -#endif +#endif /* C_TOXCORE_TOXCORE_TIMED_AUTH_H */ diff --git a/toxcore/tox.c b/toxcore/tox.c index 15fe74c7..7943167a 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -8,7 +8,7 @@ */ #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 -#endif +#endif /* _XOPEN_SOURCE */ #include "tox.h" @@ -18,6 +18,7 @@ #include "DHT.h" #include "Messenger.h" #include "TCP_client.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "friend_requests.h" @@ -33,6 +34,7 @@ #include "state.h" #include "tox_private.h" #include "tox_struct.h" +#include "util.h" #include "../toxencryptsave/defines.h" @@ -95,7 +97,9 @@ static void tox_self_connection_status_handler(Messenger *m, Onion_Connection_St struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->self_connection_status_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->self_connection_status_callback(tox_data->tox, (Tox_Connection)connection_status, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -107,7 +111,9 @@ static void tox_friend_name_handler(Messenger *m, uint32_t friend_number, const struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->friend_name_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->friend_name_callback(tox_data->tox, friend_number, name, length, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -119,7 +125,9 @@ static void tox_friend_status_message_handler(Messenger *m, uint32_t friend_numb struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->friend_status_message_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->friend_status_message_callback(tox_data->tox, friend_number, message, length, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -130,7 +138,9 @@ static void tox_friend_status_handler(Messenger *m, uint32_t friend_number, unsi struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->friend_status_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->friend_status_callback(tox_data->tox, friend_number, (Tox_User_Status)status, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -142,8 +152,10 @@ static void tox_friend_connection_status_handler(Messenger *m, uint32_t friend_n struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->friend_connection_status_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->friend_connection_status_callback(tox_data->tox, friend_number, (Tox_Connection)connection_status, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -154,7 +166,9 @@ static void tox_friend_typing_handler(Messenger *m, uint32_t friend_number, bool struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->friend_typing_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->friend_typing_callback(tox_data->tox, friend_number, is_typing, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -165,7 +179,9 @@ static void tox_friend_read_receipt_handler(Messenger *m, uint32_t friend_number struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->friend_read_receipt_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->friend_read_receipt_callback(tox_data->tox, friend_number, message_id, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -177,7 +193,9 @@ static void tox_friend_request_handler(Messenger *m, const uint8_t public_key[TO struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->friend_request_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->friend_request_callback(tox_data->tox, public_key, message, length, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -189,8 +207,10 @@ static void tox_friend_message_handler(Messenger *m, uint32_t friend_number, uns struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->friend_message_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->friend_message_callback(tox_data->tox, friend_number, (Tox_Message_Type)message_type, message, length, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -202,8 +222,10 @@ static void tox_file_recv_control_handler(Messenger *m, uint32_t friend_number, struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->file_recv_control_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->file_recv_control_callback(tox_data->tox, friend_number, file_number, (Tox_File_Control)control, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -215,8 +237,10 @@ static void tox_file_chunk_request_handler(Messenger *m, uint32_t friend_number, struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->file_chunk_request_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->file_chunk_request_callback(tox_data->tox, friend_number, file_number, position, length, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -228,8 +252,10 @@ static void tox_file_recv_handler(Messenger *m, uint32_t friend_number, uint32_t struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->file_recv_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->file_recv_callback(tox_data->tox, friend_number, file_number, kind, file_size, filename, filename_length, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -241,8 +267,10 @@ static void tox_file_recv_chunk_handler(Messenger *m, uint32_t friend_number, ui struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->file_recv_chunk_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->file_recv_chunk_callback(tox_data->tox, friend_number, file_number, position, data, length, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -254,8 +282,10 @@ static void tox_conference_invite_handler(Messenger *m, uint32_t friend_number, struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->conference_invite_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->conference_invite_callback(tox_data->tox, friend_number, (Tox_Conference_Type)type, cookie, length, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -266,7 +296,9 @@ static void tox_conference_connected_handler(Messenger *m, uint32_t conference_n struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->conference_connected_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->conference_connected_callback(tox_data->tox, conference_number, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -278,8 +310,10 @@ static void tox_conference_message_handler(Messenger *m, uint32_t conference_num struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->conference_message_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->conference_message_callback(tox_data->tox, conference_number, peer_number, (Tox_Message_Type)type, message, length, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -291,8 +325,10 @@ static void tox_conference_title_handler(Messenger *m, uint32_t conference_numbe struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->conference_title_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->conference_title_callback(tox_data->tox, conference_number, peer_number, title, length, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -304,8 +340,10 @@ static void tox_conference_peer_name_handler(Messenger *m, uint32_t conference_n struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->conference_peer_name_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->conference_peer_name_callback(tox_data->tox, conference_number, peer_number, name, length, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -316,7 +354,9 @@ static void tox_conference_peer_list_changed_handler(Messenger *m, uint32_t conf struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->conference_peer_list_changed_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->conference_peer_list_changed_callback(tox_data->tox, conference_number, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -331,9 +371,11 @@ static void tox_dht_get_nodes_response_handler(const DHT *dht, const Node_format } Ip_Ntoa 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->user_data); + tox_lock(tox_data->tox); } static m_friend_lossy_packet_cb tox_friend_lossy_packet_handler; @@ -347,8 +389,10 @@ static void tox_friend_lossy_packet_handler(Messenger *m, uint32_t friend_number assert(length > 0); if (tox_data->tox->friend_lossy_packet_callback_per_pktid[packet_id] != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->friend_lossy_packet_callback_per_pktid[packet_id](tox_data->tox, friend_number, data, length, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -363,42 +407,50 @@ static void tox_friend_lossless_packet_handler(Messenger *m, uint32_t friend_num assert(length > 0); if (tox_data->tox->friend_lossless_packet_callback_per_pktid[packet_id] != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->friend_lossless_packet_callback_per_pktid[packet_id](tox_data->tox, friend_number, data, length, tox_data->user_data); + tox_lock(tox_data->tox); } } non_null(1, 4) nullable(6) -static void tox_group_peer_name_handler(const Messenger *m, uint32_t group_number, uint32_t peer_id, +static void tox_group_peer_name_handler(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, const uint8_t *name, size_t length, void *user_data) { struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_peer_name_callback != nullptr) { - tox_data->tox->group_peer_name_callback(tox_data->tox, group_number, peer_id, name, length, tox_data->user_data); + tox_unlock(tox_data->tox); + tox_data->tox->group_peer_name_callback(tox_data->tox, group_number, gc_peer_id_to_int(peer_id), name, length, tox_data->user_data); + tox_lock(tox_data->tox); } } non_null(1) nullable(5) -static void tox_group_peer_status_handler(const Messenger *m, uint32_t group_number, uint32_t peer_id, +static void tox_group_peer_status_handler(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, unsigned int status, void *user_data) { struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_peer_status_callback != nullptr) { - tox_data->tox->group_peer_status_callback(tox_data->tox, group_number, peer_id, (Tox_User_Status)status, + tox_unlock(tox_data->tox); + tox_data->tox->group_peer_status_callback(tox_data->tox, group_number, gc_peer_id_to_int(peer_id), (Tox_User_Status)status, tox_data->user_data); + tox_lock(tox_data->tox); } } non_null(1, 4) nullable(6) -static void tox_group_topic_handler(const Messenger *m, uint32_t group_number, uint32_t peer_id, const uint8_t *topic, +static void tox_group_topic_handler(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, const uint8_t *topic, size_t length, void *user_data) { struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_topic_callback != nullptr) { - tox_data->tox->group_topic_callback(tox_data->tox, group_number, peer_id, topic, length, tox_data->user_data); + tox_unlock(tox_data->tox); + tox_data->tox->group_topic_callback(tox_data->tox, group_number, gc_peer_id_to_int(peer_id), topic, length, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -409,8 +461,10 @@ static void tox_group_topic_lock_handler(const Messenger *m, uint32_t group_numb struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_topic_lock_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->group_topic_lock_callback(tox_data->tox, group_number, (Tox_Group_Topic_Lock)topic_lock, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -421,8 +475,10 @@ static void tox_group_voice_state_handler(const Messenger *m, uint32_t group_num struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_voice_state_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->group_voice_state_callback(tox_data->tox, group_number, (Tox_Group_Voice_State)voice_state, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -433,7 +489,9 @@ static void tox_group_peer_limit_handler(const Messenger *m, uint32_t group_numb struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_peer_limit_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->group_peer_limit_callback(tox_data->tox, group_number, peer_limit, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -444,8 +502,10 @@ static void tox_group_privacy_state_handler(const Messenger *m, uint32_t group_n struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_privacy_state_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->group_privacy_state_callback(tox_data->tox, group_number, (Tox_Group_Privacy_State)privacy_state, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -456,55 +516,64 @@ static void tox_group_password_handler(const Messenger *m, uint32_t group_number struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_password_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->group_password_callback(tox_data->tox, group_number, password, length, tox_data->user_data); + tox_lock(tox_data->tox); } } non_null(1, 5) nullable(8) -static void tox_group_message_handler(const Messenger *m, uint32_t group_number, uint32_t peer_id, unsigned int type, - const uint8_t *message, size_t length, uint32_t message_id, void *user_data) +static void tox_group_message_handler(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, unsigned int type, + const uint8_t *message, size_t length, Tox_Group_Message_Id message_id, void *user_data) { struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_message_callback != nullptr) { - tox_data->tox->group_message_callback(tox_data->tox, group_number, peer_id, (Tox_Message_Type)type, message, length, + tox_unlock(tox_data->tox); + tox_data->tox->group_message_callback(tox_data->tox, group_number, gc_peer_id_to_int(peer_id), (Tox_Message_Type)type, message, length, message_id, tox_data->user_data); + tox_lock(tox_data->tox); } } -non_null(1, 5) nullable(7) -static void tox_group_private_message_handler(const Messenger *m, uint32_t group_number, uint32_t peer_id, - unsigned int type, const uint8_t *message, size_t length, void *user_data) +non_null(1, 5) nullable(8) +static void tox_group_private_message_handler(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, + unsigned int type, const uint8_t *message, size_t length, Tox_Group_Message_Id message_id, void *user_data) { struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_private_message_callback != nullptr) { - tox_data->tox->group_private_message_callback(tox_data->tox, group_number, peer_id, (Tox_Message_Type)type, message, - length, - tox_data->user_data); + tox_unlock(tox_data->tox); + tox_data->tox->group_private_message_callback(tox_data->tox, group_number, gc_peer_id_to_int(peer_id), (Tox_Message_Type)type, message, + length, message_id, tox_data->user_data); + tox_lock(tox_data->tox); } } non_null(1, 4) nullable(6) -static void tox_group_custom_packet_handler(const Messenger *m, uint32_t group_number, uint32_t peer_id, +static void tox_group_custom_packet_handler(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, const uint8_t *data, size_t length, void *user_data) { struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_custom_packet_callback != nullptr) { - tox_data->tox->group_custom_packet_callback(tox_data->tox, group_number, peer_id, data, length, tox_data->user_data); + tox_unlock(tox_data->tox); + tox_data->tox->group_custom_packet_callback(tox_data->tox, group_number, gc_peer_id_to_int(peer_id), data, length, tox_data->user_data); + tox_lock(tox_data->tox); } } non_null(1, 4) nullable(6) -static void tox_group_custom_private_packet_handler(const Messenger *m, uint32_t group_number, uint32_t peer_id, +static void tox_group_custom_private_packet_handler(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, const uint8_t *data, size_t length, void *user_data) { struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_custom_private_packet_callback != nullptr) { - tox_data->tox->group_custom_private_packet_callback(tox_data->tox, group_number, peer_id, data, length, + tox_unlock(tox_data->tox); + tox_data->tox->group_custom_private_packet_callback(tox_data->tox, group_number, gc_peer_id_to_int(peer_id), data, length, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -515,32 +584,38 @@ static void tox_group_invite_handler(const Messenger *m, uint32_t friend_number, struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_invite_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->group_invite_callback(tox_data->tox, friend_number, invite_data, length, group_name, group_name_length, tox_data->user_data); + tox_lock(tox_data->tox); } } non_null(1) nullable(4) -static void tox_group_peer_join_handler(const Messenger *m, uint32_t group_number, uint32_t peer_id, void *user_data) +static void tox_group_peer_join_handler(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, void *user_data) { struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_peer_join_callback != nullptr) { - tox_data->tox->group_peer_join_callback(tox_data->tox, group_number, peer_id, tox_data->user_data); + tox_unlock(tox_data->tox); + tox_data->tox->group_peer_join_callback(tox_data->tox, group_number, gc_peer_id_to_int(peer_id), tox_data->user_data); + tox_lock(tox_data->tox); } } non_null(1, 5) nullable(7, 9) -static void tox_group_peer_exit_handler(const Messenger *m, uint32_t group_number, uint32_t peer_id, +static void tox_group_peer_exit_handler(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, unsigned int exit_type, const uint8_t *name, size_t name_length, const uint8_t *part_message, size_t length, void *user_data) { struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_peer_exit_callback != nullptr) { - tox_data->tox->group_peer_exit_callback(tox_data->tox, group_number, peer_id, (Tox_Group_Exit_Type) exit_type, name, - name_length, + tox_unlock(tox_data->tox); + tox_data->tox->group_peer_exit_callback(tox_data->tox, group_number, gc_peer_id_to_int(peer_id), + (Tox_Group_Exit_Type)exit_type, name, name_length, part_message, length, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -550,7 +625,9 @@ static void tox_group_self_join_handler(const Messenger *m, uint32_t group_numbe struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_self_join_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->group_self_join_callback(tox_data->tox, group_number, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -561,21 +638,25 @@ static void tox_group_join_fail_handler(const Messenger *m, uint32_t group_numbe struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_join_fail_callback != nullptr) { + tox_unlock(tox_data->tox); tox_data->tox->group_join_fail_callback(tox_data->tox, group_number, (Tox_Group_Join_Fail)fail_type, tox_data->user_data); + tox_lock(tox_data->tox); } } non_null(1) nullable(6) -static void tox_group_moderation_handler(const Messenger *m, uint32_t group_number, uint32_t source_peer_number, - uint32_t target_peer_number, unsigned int mod_type, void *user_data) +static void tox_group_moderation_handler(const Messenger *m, uint32_t group_number, GC_Peer_Id source_peer_number, + GC_Peer_Id target_peer_number, unsigned int mod_type, void *user_data) { struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data; if (tox_data->tox->group_moderation_callback != nullptr) { - tox_data->tox->group_moderation_callback(tox_data->tox, group_number, source_peer_number, target_peer_number, - (Tox_Group_Mod_Event)mod_type, - tox_data->user_data); + tox_unlock(tox_data->tox); + tox_data->tox->group_moderation_callback(tox_data->tox, group_number, + gc_peer_id_to_int(source_peer_number), gc_peer_id_to_int(target_peer_number), + (Tox_Group_Mod_Event)mod_type, tox_data->user_data); + tox_lock(tox_data->tox); } } @@ -669,7 +750,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) return nullptr; } - Messenger_Options m_options = {0}; + Messenger_Options m_options = {false}; bool load_savedata_sk = false; bool load_savedata_tox = false; @@ -714,6 +795,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) m_options.hole_punching_enabled = tox_options_get_hole_punching_enabled(opts); m_options.local_discovery_enabled = tox_options_get_local_discovery_enabled(opts); m_options.dht_announcements_enabled = tox_options_get_dht_announcements_enabled(opts); + m_options.groups_persistence_enabled = tox_options_get_experimental_groups_persistence(opts); if (m_options.udp_disabled) { m_options.local_discovery_enabled = false; @@ -805,10 +887,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) return nullptr; } - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(mutex, &attr); + pthread_mutex_init(mutex, nullptr); tox->mutex = mutex; } else { @@ -993,14 +1072,14 @@ void tox_get_savedata(const Tox *tox, uint8_t *savedata) return; } - memset(savedata, 0, tox_get_savedata_size(tox)); + memzero(savedata, tox_get_savedata_size(tox)); tox_lock(tox); const uint32_t size32 = sizeof(uint32_t); // write cookie - memset(savedata, 0, size32); + memzero(savedata, size32); savedata += size32; host_to_lendian_bytes32(savedata, STATE_COOKIE_GLOBAL); savedata += size32; @@ -1152,7 +1231,6 @@ Tox_Connection tox_self_get_connection_status(const Tox *tox) return TOX_CONNECTION_NONE; } - void tox_callback_self_connection_status(Tox *tox, tox_self_connection_status_cb *callback) { assert(tox != nullptr); @@ -3104,7 +3182,6 @@ bool tox_group_disconnect(const Tox *tox, uint32_t group_number, Tox_Err_Group_D return false; } - const bool ret = gc_disconnect_from_group(tox->m->group_handler, chat); tox_unlock(tox); @@ -3371,10 +3448,10 @@ uint32_t tox_group_self_get_peer_id(const Tox *tox, uint32_t group_number, Tox_E SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SELF_QUERY_OK); - const uint32_t ret = gc_get_self_peer_id(chat); + const GC_Peer_Id ret = gc_get_self_peer_id(chat); tox_unlock(tox); - return ret; + return gc_peer_id_to_int(ret); } bool tox_group_self_get_public_key(const Tox *tox, uint32_t group_number, uint8_t public_key[TOX_PUBLIC_KEY_SIZE], @@ -3413,7 +3490,7 @@ size_t tox_group_peer_get_name_size(const Tox *tox, uint32_t group_number, uint3 return -1; } - const int ret = gc_get_peer_nick_size(chat, peer_id); + const int ret = gc_get_peer_nick_size(chat, gc_peer_id_from_int(peer_id)); tox_unlock(tox); if (ret == -1) { @@ -3439,7 +3516,7 @@ bool tox_group_peer_get_name(const Tox *tox, uint32_t group_number, uint32_t pee return false; } - const bool ret = gc_get_peer_nick(chat, peer_id, name); + const bool ret = gc_get_peer_nick(chat, gc_peer_id_from_int(peer_id), name); tox_unlock(tox); if (!ret) { @@ -3465,7 +3542,7 @@ Tox_User_Status tox_group_peer_get_status(const Tox *tox, uint32_t group_number, return (Tox_User_Status) - 1; } - const uint8_t ret = gc_get_status(chat, peer_id); + const uint8_t ret = gc_get_status(chat, gc_peer_id_from_int(peer_id)); tox_unlock(tox); if (ret == UINT8_MAX) { @@ -3491,7 +3568,7 @@ Tox_Group_Role tox_group_peer_get_role(const Tox *tox, uint32_t group_number, ui return (Tox_Group_Role) - 1; } - const uint8_t ret = gc_get_role(chat, peer_id); + const uint8_t ret = gc_get_role(chat, gc_peer_id_from_int(peer_id)); tox_unlock(tox); if (ret == (uint8_t) -1) { @@ -3517,7 +3594,7 @@ bool tox_group_peer_get_public_key(const Tox *tox, uint32_t group_number, uint32 return false; } - const int ret = gc_get_peer_public_key_by_peer_id(chat, peer_id, public_key); + const int ret = gc_get_peer_public_key_by_peer_id(chat, gc_peer_id_from_int(peer_id), public_key); tox_unlock(tox); if (ret == -1) { @@ -3543,7 +3620,7 @@ Tox_Connection tox_group_peer_get_connection_status(const Tox *tox, uint32_t gro return TOX_CONNECTION_NONE; } - const unsigned int ret = gc_get_peer_connection_status(chat, peer_id); + const unsigned int ret = gc_get_peer_connection_status(chat, gc_peer_id_from_int(peer_id)); tox_unlock(tox); if (ret == 0) { @@ -3611,7 +3688,7 @@ bool tox_group_set_topic(Tox *tox, uint32_t group_number, const uint8_t *topic, return false; } -size_t tox_group_get_topic_size(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Queries *error) +size_t tox_group_get_topic_size(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Query *error) { assert(tox != nullptr); @@ -3619,12 +3696,12 @@ size_t tox_group_get_topic_size(const Tox *tox, uint32_t group_number, Tox_Err_G const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number); if (chat == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND); tox_unlock(tox); return -1; } - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK); const size_t ret = gc_get_topic_size(chat); tox_unlock(tox); @@ -3632,7 +3709,7 @@ size_t tox_group_get_topic_size(const Tox *tox, uint32_t group_number, Tox_Err_G return ret; } -bool tox_group_get_topic(const Tox *tox, uint32_t group_number, uint8_t *topic, Tox_Err_Group_State_Queries *error) +bool tox_group_get_topic(const Tox *tox, uint32_t group_number, uint8_t *topic, Tox_Err_Group_State_Query *error) { assert(tox != nullptr); @@ -3640,7 +3717,7 @@ bool tox_group_get_topic(const Tox *tox, uint32_t group_number, uint8_t *topic, const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number); if (chat == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND); tox_unlock(tox); return false; } @@ -3648,11 +3725,11 @@ bool tox_group_get_topic(const Tox *tox, uint32_t group_number, uint8_t *topic, gc_get_topic(chat, topic); tox_unlock(tox); - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK); return true; } -size_t tox_group_get_name_size(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Queries *error) +size_t tox_group_get_name_size(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Query *error) { assert(tox != nullptr); @@ -3660,12 +3737,12 @@ size_t tox_group_get_name_size(const Tox *tox, uint32_t group_number, Tox_Err_Gr const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number); if (chat == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND); tox_unlock(tox); return -1; } - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK); const size_t ret = gc_get_group_name_size(chat); tox_unlock(tox); @@ -3673,7 +3750,7 @@ size_t tox_group_get_name_size(const Tox *tox, uint32_t group_number, Tox_Err_Gr return ret; } -bool tox_group_get_name(const Tox *tox, uint32_t group_number, uint8_t *name, Tox_Err_Group_State_Queries *error) +bool tox_group_get_name(const Tox *tox, uint32_t group_number, uint8_t *name, Tox_Err_Group_State_Query *error) { assert(tox != nullptr); @@ -3681,7 +3758,7 @@ bool tox_group_get_name(const Tox *tox, uint32_t group_number, uint8_t *name, To const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number); if (chat == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND); tox_unlock(tox); return false; } @@ -3689,12 +3766,12 @@ bool tox_group_get_name(const Tox *tox, uint32_t group_number, uint8_t *name, To gc_get_group_name(chat, name); tox_unlock(tox); - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK); return true; } -bool tox_group_get_chat_id(const Tox *tox, uint32_t group_number, uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE], Tox_Err_Group_State_Queries *error) +bool tox_group_get_chat_id(const Tox *tox, uint32_t group_number, uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE], Tox_Err_Group_State_Query *error) { assert(tox != nullptr); @@ -3702,12 +3779,12 @@ bool tox_group_get_chat_id(const Tox *tox, uint32_t group_number, uint8_t chat_i const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number); if (chat == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND); tox_unlock(tox); return false; } - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK); gc_get_chat_id(chat, chat_id); tox_unlock(tox); @@ -3726,7 +3803,7 @@ uint32_t tox_group_get_number_groups(const Tox *tox) } Tox_Group_Privacy_State tox_group_get_privacy_state(const Tox *tox, uint32_t group_number, - Tox_Err_Group_State_Queries *error) + Tox_Err_Group_State_Query *error) { assert(tox != nullptr); @@ -3734,12 +3811,12 @@ Tox_Group_Privacy_State tox_group_get_privacy_state(const Tox *tox, uint32_t gro const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number); if (chat == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND); tox_unlock(tox); return (Tox_Group_Privacy_State) - 1; } - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK); const uint8_t state = gc_get_privacy_state(chat); tox_unlock(tox); @@ -3747,7 +3824,7 @@ Tox_Group_Privacy_State tox_group_get_privacy_state(const Tox *tox, uint32_t gro return (Tox_Group_Privacy_State)state; } -Tox_Group_Topic_Lock tox_group_get_topic_lock(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Queries *error) +Tox_Group_Topic_Lock tox_group_get_topic_lock(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Query *error) { assert(tox != nullptr); @@ -3755,12 +3832,12 @@ Tox_Group_Topic_Lock tox_group_get_topic_lock(const Tox *tox, uint32_t group_num const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number); if (chat == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND); tox_unlock(tox); return (Tox_Group_Topic_Lock) - 1; } - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK); const Group_Topic_Lock topic_lock = gc_get_topic_lock_state(chat); tox_unlock(tox); @@ -3769,7 +3846,7 @@ Tox_Group_Topic_Lock tox_group_get_topic_lock(const Tox *tox, uint32_t group_num } Tox_Group_Voice_State tox_group_get_voice_state(const Tox *tox, uint32_t group_number, - Tox_Err_Group_State_Queries *error) + Tox_Err_Group_State_Query *error) { assert(tox != nullptr); @@ -3777,12 +3854,12 @@ Tox_Group_Voice_State tox_group_get_voice_state(const Tox *tox, uint32_t group_n const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number); if (chat == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND); tox_unlock(tox); return (Tox_Group_Voice_State) - 1; } - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK); const Group_Voice_State voice_state = gc_get_voice_state(chat); tox_unlock(tox); @@ -3790,7 +3867,7 @@ Tox_Group_Voice_State tox_group_get_voice_state(const Tox *tox, uint32_t group_n return (Tox_Group_Voice_State)voice_state; } -uint16_t tox_group_get_peer_limit(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Queries *error) +uint16_t tox_group_get_peer_limit(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Query *error) { assert(tox != nullptr); @@ -3798,12 +3875,12 @@ uint16_t tox_group_get_peer_limit(const Tox *tox, uint32_t group_number, Tox_Err const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number); if (chat == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND); tox_unlock(tox); return -1; } - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK); const uint16_t ret = gc_get_max_peers(chat); tox_unlock(tox); @@ -3811,7 +3888,7 @@ uint16_t tox_group_get_peer_limit(const Tox *tox, uint32_t group_number, Tox_Err return ret; } -size_t tox_group_get_password_size(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Queries *error) +size_t tox_group_get_password_size(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Query *error) { assert(tox != nullptr); @@ -3819,12 +3896,12 @@ size_t tox_group_get_password_size(const Tox *tox, uint32_t group_number, Tox_Er const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number); if (chat == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND); tox_unlock(tox); return -1; } - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK); const size_t ret = gc_get_password_size(chat); tox_unlock(tox); @@ -3833,7 +3910,7 @@ size_t tox_group_get_password_size(const Tox *tox, uint32_t group_number, Tox_Er } bool tox_group_get_password(const Tox *tox, uint32_t group_number, uint8_t *password, - Tox_Err_Group_State_Queries *error) + Tox_Err_Group_State_Query *error) { assert(tox != nullptr); @@ -3841,12 +3918,12 @@ bool tox_group_get_password(const Tox *tox, uint32_t group_number, uint8_t *pass const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number); if (chat == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND); tox_unlock(tox); return false; } - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK); gc_get_password(chat, password); tox_unlock(tox); @@ -3855,8 +3932,8 @@ bool tox_group_get_password(const Tox *tox, uint32_t group_number, uint8_t *pass } Tox_Group_Message_Id tox_group_send_message( - const Tox *tox, uint32_t group_number, Tox_Message_Type type, const uint8_t *message, - size_t length, Tox_Err_Group_Send_Message *error) + const Tox *tox, uint32_t group_number, Tox_Message_Type type, const uint8_t *message, + size_t length, Tox_Err_Group_Send_Message *error) { assert(tox != nullptr); @@ -3917,8 +3994,8 @@ Tox_Group_Message_Id tox_group_send_message( return -1; } -bool tox_group_send_private_message(const Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Message_Type type, - const uint8_t *message, size_t length, Tox_Err_Group_Send_Private_Message *error) +Tox_Group_Message_Id tox_group_send_private_message(const Tox *tox, uint32_t group_number, uint32_t peer_id, + Tox_Message_Type type, const uint8_t *message, size_t length, Tox_Err_Group_Send_Private_Message *error) { assert(tox != nullptr); @@ -3928,59 +4005,60 @@ bool tox_group_send_private_message(const Tox *tox, uint32_t group_number, uint3 if (chat == nullptr) { SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_GROUP_NOT_FOUND); tox_unlock(tox); - return false; + return -1; } if (chat->connection_state == CS_DISCONNECTED) { SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_DISCONNECTED); tox_unlock(tox); - return false; + return -1; } - const int ret = gc_send_private_message(chat, peer_id, type, message, length); + uint32_t message_id = 0; + const int ret = gc_send_private_message(chat, gc_peer_id_from_int(peer_id), type, message, length, &message_id); tox_unlock(tox); switch (ret) { case 0: { SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_OK); - return true; + return message_id; } case -1: { SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_TOO_LONG); - return false; + return -1; } case -2: { SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_EMPTY); - return false; + return -1; } case -3: { SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_PEER_NOT_FOUND); - return false; + return -1; } case -4: { SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_BAD_TYPE); - return false; + return -1; } case -5: { SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_PERMISSIONS); - return false; + return -1; } case -6: { SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_FAIL_SEND); - return false; + return -1; } } /* can't happen */ LOGGER_FATAL(tox->m->log, "impossible return value: %d", ret); - return false; + return -1; } bool tox_group_send_custom_packet(const Tox *tox, uint32_t group_number, bool lossless, const uint8_t *data, @@ -4023,11 +4101,6 @@ bool tox_group_send_custom_packet(const Tox *tox, uint32_t group_number, bool lo } case -3: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_CUSTOM_PACKET_PERMISSIONS); - return false; - } - - case -4: { SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_CUSTOM_PACKET_FAIL_SEND); return false; } @@ -4060,7 +4133,7 @@ bool tox_group_send_custom_private_packet(const Tox *tox, uint32_t group_number, return false; } - const int ret = gc_send_custom_private_packet(chat, lossless, peer_id, data, length); + const int ret = gc_send_custom_private_packet(chat, lossless, gc_peer_id_from_int(peer_id), data, length); tox_unlock(tox); switch (ret) { @@ -4085,11 +4158,6 @@ bool tox_group_send_custom_private_packet(const Tox *tox, uint32_t group_number, } case -4: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_PERMISSIONS); - return false; - } - - case -5: { SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_FAIL_SEND); return false; } @@ -4217,8 +4285,8 @@ uint32_t tox_group_invite_accept(Tox *tox, uint32_t friend_number, const uint8_t return UINT32_MAX; } -bool tox_group_founder_set_password(Tox *tox, uint32_t group_number, const uint8_t *password, size_t length, - Tox_Err_Group_Founder_Set_Password *error) +bool tox_group_set_password(Tox *tox, uint32_t group_number, const uint8_t *password, size_t length, + Tox_Err_Group_Set_Password *error) { assert(tox != nullptr); @@ -4226,13 +4294,13 @@ bool tox_group_founder_set_password(Tox *tox, uint32_t group_number, const uint8 GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number); if (chat == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PASSWORD_GROUP_NOT_FOUND); tox_unlock(tox); return false; } if (chat->connection_state == CS_DISCONNECTED) { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_DISCONNECTED); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PASSWORD_DISCONNECTED); tox_unlock(tox); return false; } @@ -4242,27 +4310,27 @@ bool tox_group_founder_set_password(Tox *tox, uint32_t group_number, const uint8 switch (ret) { case 0: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PASSWORD_OK); return true; } case -1: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_PERMISSIONS); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PASSWORD_PERMISSIONS); return false; } case -2: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_TOO_LONG); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PASSWORD_TOO_LONG); return false; } case -3: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_FAIL_SEND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PASSWORD_FAIL_SEND); return false; } case -4: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_MALLOC); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PASSWORD_MALLOC); return false; } } @@ -4273,8 +4341,8 @@ bool tox_group_founder_set_password(Tox *tox, uint32_t group_number, const uint8 return false; } -bool tox_group_founder_set_privacy_state(Tox *tox, uint32_t group_number, Tox_Group_Privacy_State privacy_state, - Tox_Err_Group_Founder_Set_Privacy_State *error) +bool tox_group_set_privacy_state(Tox *tox, uint32_t group_number, Tox_Group_Privacy_State privacy_state, + Tox_Err_Group_Set_Privacy_State *error) { assert(tox != nullptr); @@ -4284,32 +4352,32 @@ bool tox_group_founder_set_privacy_state(Tox *tox, uint32_t group_number, Tox_Gr switch (ret) { case 0: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PRIVACY_STATE_OK); return true; } case -1: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PRIVACY_STATE_GROUP_NOT_FOUND); return false; } case -2: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_PERMISSIONS); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PRIVACY_STATE_PERMISSIONS); return false; } case -3: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_DISCONNECTED); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PRIVACY_STATE_DISCONNECTED); return false; } case -4: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SET); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SET); return false; } case -5: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SEND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SEND); return false; } } @@ -4320,8 +4388,8 @@ bool tox_group_founder_set_privacy_state(Tox *tox, uint32_t group_number, Tox_Gr return false; } -bool tox_group_founder_set_topic_lock(Tox *tox, uint32_t group_number, Tox_Group_Topic_Lock topic_lock, - Tox_Err_Group_Founder_Set_Topic_Lock *error) +bool tox_group_set_topic_lock(Tox *tox, uint32_t group_number, Tox_Group_Topic_Lock topic_lock, + Tox_Err_Group_Set_Topic_Lock *error) { assert(tox != nullptr); @@ -4331,37 +4399,37 @@ bool tox_group_founder_set_topic_lock(Tox *tox, uint32_t group_number, Tox_Group switch (ret) { case 0: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_TOPIC_LOCK_OK); return true; } case -1: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_TOPIC_LOCK_GROUP_NOT_FOUND); return false; } case -2: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_INVALID); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_TOPIC_LOCK_INVALID); return false; } case -3: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_PERMISSIONS); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_TOPIC_LOCK_PERMISSIONS); return false; } case -4: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_DISCONNECTED); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_TOPIC_LOCK_DISCONNECTED); return false; } case -5: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SET); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SET); return false; } case -6: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SEND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SEND); return false; } } @@ -4372,8 +4440,8 @@ bool tox_group_founder_set_topic_lock(Tox *tox, uint32_t group_number, Tox_Group return false; } -bool tox_group_founder_set_voice_state(Tox *tox, uint32_t group_number, Tox_Group_Voice_State voice_state, - Tox_Err_Group_Founder_Set_Voice_State *error) +bool tox_group_set_voice_state(Tox *tox, uint32_t group_number, Tox_Group_Voice_State voice_state, + Tox_Err_Group_Set_Voice_State *error) { assert(tox != nullptr); @@ -4383,32 +4451,32 @@ bool tox_group_founder_set_voice_state(Tox *tox, uint32_t group_number, Tox_Grou switch (ret) { case 0: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_VOICE_STATE_OK); return true; } case -1: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_VOICE_STATE_GROUP_NOT_FOUND); return false; } case -2: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_PERMISSIONS); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_VOICE_STATE_PERMISSIONS); return false; } case -3: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_DISCONNECTED); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_VOICE_STATE_DISCONNECTED); return false; } case -4: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SET); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SET); return false; } case -5: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SEND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SEND); return false; } } @@ -4419,8 +4487,8 @@ bool tox_group_founder_set_voice_state(Tox *tox, uint32_t group_number, Tox_Grou return false; } -bool tox_group_founder_set_peer_limit(Tox *tox, uint32_t group_number, uint16_t peer_limit, - Tox_Err_Group_Founder_Set_Peer_Limit *error) +bool tox_group_set_peer_limit(Tox *tox, uint32_t group_number, uint16_t peer_limit, + Tox_Err_Group_Set_Peer_Limit *error) { assert(tox != nullptr); @@ -4428,13 +4496,13 @@ bool tox_group_founder_set_peer_limit(Tox *tox, uint32_t group_number, uint16_t GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number); if (chat == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PEER_LIMIT_GROUP_NOT_FOUND); tox_unlock(tox); return false; } if (chat->connection_state == CS_DISCONNECTED) { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_DISCONNECTED); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PEER_LIMIT_DISCONNECTED); tox_unlock(tox); return false; } @@ -4444,22 +4512,22 @@ bool tox_group_founder_set_peer_limit(Tox *tox, uint32_t group_number, uint16_t switch (ret) { case 0: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PEER_LIMIT_OK); return true; } case -1: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_PERMISSIONS); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PEER_LIMIT_PERMISSIONS); return false; } case -2: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SET); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SET); return false; } case -3: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SEND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SEND); return false; } } @@ -4484,7 +4552,7 @@ bool tox_group_set_ignore(Tox *tox, uint32_t group_number, uint32_t peer_id, boo return false; } - const int ret = gc_set_ignore(chat, peer_id, ignore); + const int ret = gc_set_ignore(chat, gc_peer_id_from_int(peer_id), ignore); tox_unlock(tox); switch (ret) { @@ -4510,48 +4578,48 @@ bool tox_group_set_ignore(Tox *tox, uint32_t group_number, uint32_t peer_id, boo return false; } -bool tox_group_mod_set_role(Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Group_Role role, - Tox_Err_Group_Mod_Set_Role *error) +bool tox_group_set_role(Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Group_Role role, + Tox_Err_Group_Set_Role *error) { assert(tox != nullptr); tox_lock(tox); - const int ret = gc_set_peer_role(tox->m, group_number, peer_id, (Group_Role) role); + const int ret = gc_set_peer_role(tox->m, group_number, gc_peer_id_from_int(peer_id), (Group_Role) role); tox_unlock(tox); switch (ret) { case 0: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_SET_ROLE_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_ROLE_OK); return true; } case -1: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_SET_ROLE_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_ROLE_GROUP_NOT_FOUND); return false; } case -2: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_ROLE_PEER_NOT_FOUND); return false; } case -3: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_ROLE_PERMISSIONS); return false; } case -4: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_SET_ROLE_ASSIGNMENT); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_ROLE_ASSIGNMENT); return false; } case -5: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_SET_ROLE_FAIL_ACTION); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_ROLE_FAIL_ACTION); return false; } case -6: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_SET_ROLE_SELF); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_ROLE_SELF); return false; } } @@ -4562,48 +4630,48 @@ bool tox_group_mod_set_role(Tox *tox, uint32_t group_number, uint32_t peer_id, T return false; } -bool tox_group_mod_kick_peer(const Tox *tox, uint32_t group_number, uint32_t peer_id, - Tox_Err_Group_Mod_Kick_Peer *error) +bool tox_group_kick_peer(const Tox *tox, uint32_t group_number, uint32_t peer_id, + Tox_Err_Group_Kick_Peer *error) { assert(tox != nullptr); tox_lock(tox); - const int ret = gc_kick_peer(tox->m, group_number, peer_id); + const int ret = gc_kick_peer(tox->m, group_number, gc_peer_id_from_int(peer_id)); tox_unlock(tox); switch (ret) { case 0: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_KICK_PEER_OK); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_KICK_PEER_OK); return true; } case -1: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_KICK_PEER_GROUP_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_KICK_PEER_GROUP_NOT_FOUND); return false; } case -2: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_KICK_PEER_PEER_NOT_FOUND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_KICK_PEER_PEER_NOT_FOUND); return false; } case -3: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_KICK_PEER_PERMISSIONS); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_KICK_PEER_PERMISSIONS); return false; } case -4: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_ACTION); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_KICK_PEER_FAIL_ACTION); return false; } case -5: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_SEND); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_KICK_PEER_FAIL_SEND); return false; } case -6: { - SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_KICK_PEER_SELF); + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_KICK_PEER_SELF); return false; } } diff --git a/toxcore/tox.h b/toxcore/tox.h index 183ec1b0..a0f4d206 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -124,7 +124,6 @@ extern "C" { typedef struct Tox Tox; #endif /* TOX_DEFINED */ - /** @{ * @name API version */ @@ -202,7 +201,6 @@ bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch); /** @} */ - /** @{ * @name Numeric constants * @@ -344,7 +342,6 @@ uint32_t tox_max_hostname_length(void); /** @} */ - /** @{ * @name Global enumerations */ @@ -375,7 +372,6 @@ typedef enum Tox_User_Status { const char *tox_user_status_to_string(Tox_User_Status value); - /** * @brief Represents message types for tox_friend_send_message and conference * messages. @@ -399,7 +395,6 @@ const char *tox_message_type_to_string(Tox_Message_Type value); /** @} */ - /** @{ * @name Startup options */ @@ -428,7 +423,6 @@ typedef enum Tox_Proxy_Type { const char *tox_proxy_type_to_string(Tox_Proxy_Type value); - /** * @brief Type of savedata to create the Tox instance from. */ @@ -453,7 +447,6 @@ typedef enum Tox_Savedata_Type { const char *tox_savedata_type_to_string(Tox_Savedata_Type value); - /** * @brief Severity level of log messages. */ @@ -488,7 +481,6 @@ typedef enum Tox_Log_Level { const char *tox_log_level_to_string(Tox_Log_Level value); - /** * @brief This event is triggered when the toxcore library logs an events_alloc message. * @@ -500,6 +492,9 @@ const char *tox_log_level_to_string(Tox_Log_Level value); * 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. @@ -510,7 +505,6 @@ const char *tox_log_level_to_string(Tox_Log_Level value); 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 Operating system functions used by Tox. * @@ -520,7 +514,6 @@ typedef void tox_log_cb(Tox *tox, Tox_Log_Level level, const char *file, uint32_ */ typedef struct Tox_System Tox_System; - /** * @brief This struct contains all the startup options for Tox. * @@ -549,7 +542,6 @@ struct Tox_Options { */ bool ipv6_enabled; - /** * Enable the use of UDP communication when available. * @@ -561,7 +553,6 @@ struct Tox_Options { */ bool udp_enabled; - /** * Enable local network peer discovery. * @@ -569,7 +560,6 @@ struct Tox_Options { */ bool local_discovery_enabled; - /** * Enable storing DHT announcements and forwarding corresponding requests. * @@ -582,7 +572,6 @@ struct Tox_Options { */ Tox_Proxy_Type proxy_type; - /** * The IP address or DNS name of the proxy to be used. * @@ -597,7 +586,6 @@ struct Tox_Options { */ const char *proxy_host; - /** * The port to use to connect to the proxy server. * @@ -606,7 +594,6 @@ struct Tox_Options { */ uint16_t proxy_port; - /** * The start port of the inclusive port range to attempt to use. * @@ -621,13 +608,11 @@ struct Tox_Options { */ 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. @@ -641,19 +626,16 @@ struct Tox_Options { */ uint16_t tcp_port; - /** * Enables or disables UDP hole-punching in toxcore. (Default: enabled). */ bool hole_punching_enabled; - /** * The type of savedata to load from. */ Tox_Savedata_Type savedata_type; - /** * The savedata. * @@ -662,25 +644,21 @@ struct Tox_Options { */ 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 @@ -700,9 +678,19 @@ struct Tox_Options { */ const Tox_System *operating_system; + /** + * 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; }; - bool tox_options_get_ipv6_enabled(const Tox_Options *options); void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled); @@ -775,6 +763,10 @@ const Tox_System *tox_options_get_operating_system(const Tox_Options *options); void tox_options_set_operating_system(Tox_Options *options, const Tox_System *operating_system); +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); + /** * @brief Initialises a Tox_Options object with the default options. * @@ -804,7 +796,6 @@ typedef enum 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. @@ -829,7 +820,6 @@ void tox_options_free(Tox_Options *options); /** @} */ - /** @{ * @name Creation and destruction */ @@ -898,7 +888,6 @@ typedef enum Tox_Err_New { const char *tox_err_new_to_string(Tox_Err_New value); - /** * @brief Creates and initialises a new Tox instance with the options passed. * @@ -944,7 +933,6 @@ void tox_get_savedata(const Tox *tox, uint8_t savedata[]); /** @} */ - /** @{ * @name Connection lifecycle and event loop */ @@ -977,7 +965,6 @@ 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, * and public key to setup connections. @@ -1062,7 +1049,6 @@ Tox_Connection tox_self_get_connection_status(const Tox *tox); */ typedef void tox_self_connection_status_cb(Tox *tox, Tox_Connection connection_status, void *user_data); - /** * @brief Set the callback for the `self_connection_status` event. * @@ -1092,7 +1078,6 @@ void tox_iterate(Tox *tox, void *user_data); /** @} */ - /** @{ * @name Internal client information (Tox address/id) */ @@ -1144,7 +1129,6 @@ void tox_self_get_secret_key(const Tox *tox, uint8_t secret_key[TOX_SECRET_KEY_S /** @} */ - /** @{ * @name User-visible client information (nickname/status) */ @@ -1174,7 +1158,6 @@ typedef enum Tox_Err_Set_Info { const char *tox_err_set_info_to_string(Tox_Err_Set_Info value); - /** * @brief Set the nickname for the Tox client. * @@ -1220,7 +1203,7 @@ void tox_self_get_name(const Tox *tox, uint8_t name[]); * user status is set back to empty. */ bool tox_self_set_status_message( - Tox *tox, const uint8_t status_message[], size_t length, Tox_Err_Set_Info *error); + Tox *tox, const uint8_t status_message[], size_t length, Tox_Err_Set_Info *error); /** * @brief Return the length of the current status message as passed to tox_self_set_status_message. @@ -1260,7 +1243,6 @@ Tox_User_Status tox_self_get_status(const Tox *tox); /** @} */ - /** @{ * @name Friend list management */ @@ -1321,7 +1303,6 @@ typedef enum Tox_Err_Friend_Add { const char *tox_err_friend_add_to_string(Tox_Err_Friend_Add value); - /** * @brief Add a friend to the friend list and send a friend request. * @@ -1346,9 +1327,9 @@ const char *tox_err_friend_add_to_string(Tox_Err_Friend_Add value); * @return the friend number on success, an unspecified value on failure. */ Tox_Friend_Number tox_friend_add( - Tox *tox, const uint8_t address[TOX_ADDRESS_SIZE], - const uint8_t message[], size_t length, - Tox_Err_Friend_Add *error); + Tox *tox, const uint8_t address[TOX_ADDRESS_SIZE], + const uint8_t message[], size_t length, + Tox_Err_Friend_Add *error); /** * @brief Add a friend without sending a friend request. @@ -1369,7 +1350,7 @@ Tox_Friend_Number tox_friend_add( * @see tox_friend_add for a more detailed description of friend numbers. */ Tox_Friend_Number tox_friend_add_norequest( - Tox *tox, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE], Tox_Err_Friend_Add *error); + Tox *tox, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE], Tox_Err_Friend_Add *error); typedef enum Tox_Err_Friend_Delete { @@ -1387,7 +1368,6 @@ typedef enum Tox_Err_Friend_Delete { const char *tox_err_friend_delete_to_string(Tox_Err_Friend_Delete value); - /** * @brief Remove a friend from the friend list. * @@ -1403,7 +1383,6 @@ bool tox_friend_delete(Tox *tox, Tox_Friend_Number friend_number, Tox_Err_Friend /** @} */ - /** @{ * @name Friend list queries */ @@ -1429,7 +1408,6 @@ typedef enum Tox_Err_Friend_By_Public_Key { const char *tox_err_friend_by_public_key_to_string(Tox_Err_Friend_By_Public_Key value); - /** * @brief Return the friend number associated with that Public Key. * @@ -1478,7 +1456,6 @@ typedef enum Tox_Err_Friend_Get_Public_Key { const char *tox_err_friend_get_public_key_to_string(Tox_Err_Friend_Get_Public_Key value); - /** * @brief Copies the Public Key associated with a given friend number to a byte array. * @@ -1489,8 +1466,8 @@ const char *tox_err_friend_get_public_key_to_string(Tox_Err_Friend_Get_Public_Ke * @return true on success. */ bool tox_friend_get_public_key( - const Tox *tox, Tox_Friend_Number friend_number, uint8_t public_key[TOX_PUBLIC_KEY_SIZE], - Tox_Err_Friend_Get_Public_Key *error); + const Tox *tox, Tox_Friend_Number friend_number, uint8_t public_key[TOX_PUBLIC_KEY_SIZE], + Tox_Err_Friend_Get_Public_Key *error); typedef enum Tox_Err_Friend_Get_Last_Online { @@ -1508,7 +1485,6 @@ typedef enum Tox_Err_Friend_Get_Last_Online { const char *tox_err_friend_get_last_online_to_string(Tox_Err_Friend_Get_Last_Online value); - /** * @brief Return a unix-time timestamp of the last time the friend associated with a given * friend number was seen online. @@ -1518,11 +1494,10 @@ const char *tox_err_friend_get_last_online_to_string(Tox_Err_Friend_Get_Last_Onl * @param friend_number The friend number you want to query. */ uint64_t tox_friend_get_last_online( - const Tox *tox, Tox_Friend_Number friend_number, Tox_Err_Friend_Get_Last_Online *error); + const Tox *tox, Tox_Friend_Number friend_number, Tox_Err_Friend_Get_Last_Online *error); /** @} */ - /** @{ * @name Friend-specific state queries (can also be received through callbacks) */ @@ -1553,7 +1528,6 @@ typedef enum Tox_Err_Friend_Query { const char *tox_err_friend_query_to_string(Tox_Err_Friend_Query value); - /** * @brief Return the length of the friend's name. * @@ -1563,7 +1537,7 @@ const char *tox_err_friend_query_to_string(Tox_Err_Friend_Query value); * `friend_name` callback. */ size_t tox_friend_get_name_size( - const Tox *tox, Tox_Friend_Number friend_number, Tox_Err_Friend_Query *error); + const Tox *tox, Tox_Friend_Number friend_number, Tox_Err_Friend_Query *error); /** * @brief Write the name of the friend designated by the given friend number to a byte @@ -1580,7 +1554,7 @@ size_t tox_friend_get_name_size( * @return true on success. */ bool tox_friend_get_name( - const Tox *tox, Tox_Friend_Number friend_number, uint8_t name[], Tox_Err_Friend_Query *error); + const Tox *tox, Tox_Friend_Number friend_number, uint8_t name[], Tox_Err_Friend_Query *error); /** * @param friend_number The friend number of the friend whose name changed. @@ -1590,9 +1564,8 @@ bool tox_friend_get_name( * tox_friend_get_name_size. */ typedef void tox_friend_name_cb( - Tox *tox, Tox_Friend_Number friend_number, - const uint8_t name[], size_t length, void *user_data); - + Tox *tox, Tox_Friend_Number friend_number, + const uint8_t name[], size_t length, void *user_data); /** * @brief Set the callback for the `friend_name` event. @@ -1609,7 +1582,7 @@ void tox_callback_friend_name(Tox *tox, tox_friend_name_cb *callback); * If the friend number isinvalid, the return value is SIZE_MAX. */ size_t tox_friend_get_status_message_size( - const Tox *tox, Tox_Friend_Number friend_number, Tox_Err_Friend_Query *error); + const Tox *tox, Tox_Friend_Number friend_number, Tox_Err_Friend_Query *error); /** * @brief Write the status message of the friend designated by the given friend number to a byte @@ -1624,8 +1597,8 @@ size_t tox_friend_get_status_message_size( * @param status_message A valid memory region large enough to store the friend's status message. */ bool tox_friend_get_status_message( - const Tox *tox, Tox_Friend_Number friend_number, uint8_t status_message[], - Tox_Err_Friend_Query *error); + const Tox *tox, Tox_Friend_Number friend_number, uint8_t status_message[], + Tox_Err_Friend_Query *error); /** * @param friend_number The friend number of the friend whose status message @@ -1636,9 +1609,8 @@ bool tox_friend_get_status_message( * tox_friend_get_status_message_size. */ typedef void tox_friend_status_message_cb( - Tox *tox, Tox_Friend_Number friend_number, - const uint8_t message[], size_t length, void *user_data); - + Tox *tox, Tox_Friend_Number friend_number, + const uint8_t message[], size_t length, void *user_data); /** * @brief Set the callback for the `friend_status_message` event. @@ -1661,7 +1633,7 @@ void tox_callback_friend_status_message(Tox *tox, tox_friend_status_message_cb * * in the client state. */ Tox_User_Status tox_friend_get_status( - const Tox *tox, Tox_Friend_Number friend_number, Tox_Err_Friend_Query *error); + const Tox *tox, Tox_Friend_Number friend_number, Tox_Err_Friend_Query *error); /** * @param friend_number The friend number of the friend whose user status @@ -1669,8 +1641,7 @@ Tox_User_Status tox_friend_get_status( * @param status The new user status. */ typedef void tox_friend_status_cb( - Tox *tox, Tox_Friend_Number friend_number, Tox_User_Status status, void *user_data); - + Tox *tox, Tox_Friend_Number friend_number, Tox_User_Status status, void *user_data); /** * @brief Set the callback for the `friend_status` event. @@ -1697,7 +1668,7 @@ void tox_callback_friend_status(Tox *tox, tox_friend_status_cb *callback); * in the client state. */ Tox_Connection tox_friend_get_connection_status( - const Tox *tox, Tox_Friend_Number friend_number, Tox_Err_Friend_Query *error); + const Tox *tox, Tox_Friend_Number friend_number, Tox_Err_Friend_Query *error); /** * @param friend_number The friend number of the friend whose connection status @@ -1706,8 +1677,7 @@ Tox_Connection tox_friend_get_connection_status( * tox_friend_get_connection_status on the passed friend_number. */ typedef void tox_friend_connection_status_cb( - Tox *tox, Tox_Friend_Number friend_number, Tox_Connection connection_status, void *user_data); - + Tox *tox, Tox_Friend_Number friend_number, Tox_Connection connection_status, void *user_data); /** * @brief Set the callback for the `friend_connection_status` event. @@ -1735,7 +1705,7 @@ void tox_callback_friend_connection_status(Tox *tox, tox_friend_connection_statu * in the client state. */ bool tox_friend_get_typing( - const Tox *tox, Tox_Friend_Number friend_number, Tox_Err_Friend_Query *error); + const Tox *tox, Tox_Friend_Number friend_number, Tox_Err_Friend_Query *error); /** * @param friend_number The friend number of the friend who started or stopped @@ -1744,8 +1714,7 @@ bool tox_friend_get_typing( * friend_number. */ typedef void tox_friend_typing_cb( - Tox *tox, Tox_Friend_Number friend_number, bool typing, void *user_data); - + Tox *tox, Tox_Friend_Number friend_number, bool typing, void *user_data); /** * @brief Set the callback for the `friend_typing` event. @@ -1758,7 +1727,6 @@ void tox_callback_friend_typing(Tox *tox, tox_friend_typing_cb *callback); /** @} */ - /** @{ * @name Sending private messages */ @@ -1779,7 +1747,6 @@ typedef enum Tox_Err_Set_Typing { const char *tox_err_set_typing_to_string(Tox_Err_Set_Typing value); - /** * @brief Set the client's typing status for a friend. * @@ -1791,7 +1758,7 @@ const char *tox_err_set_typing_to_string(Tox_Err_Set_Typing value); * @return true on success. */ bool tox_self_set_typing( - Tox *tox, Tox_Friend_Number friend_number, bool typing, Tox_Err_Set_Typing *error); + Tox *tox, Tox_Friend_Number friend_number, bool typing, Tox_Err_Set_Typing *error); typedef enum Tox_Err_Friend_Send_Message { @@ -1860,8 +1827,8 @@ typedef uint32_t Tox_Friend_Message_Id; * @param length Length of the message to be sent. */ Tox_Friend_Message_Id tox_friend_send_message( - Tox *tox, Tox_Friend_Number friend_number, Tox_Message_Type type, - const uint8_t message[], size_t length, Tox_Err_Friend_Send_Message *error); + Tox *tox, Tox_Friend_Number friend_number, Tox_Message_Type type, + const uint8_t message[], size_t length, Tox_Err_Friend_Send_Message *error); /** * @param friend_number The friend number of the friend who received the message. @@ -1869,8 +1836,7 @@ Tox_Friend_Message_Id tox_friend_send_message( * corresponding to the message sent. */ typedef void tox_friend_read_receipt_cb( - Tox *tox, Tox_Friend_Number friend_number, Tox_Friend_Message_Id message_id, void *user_data); - + Tox *tox, Tox_Friend_Number friend_number, Tox_Friend_Message_Id message_id, void *user_data); /** * @brief Set the callback for the `friend_read_receipt` event. @@ -1884,7 +1850,6 @@ void tox_callback_friend_read_receipt(Tox *tox, tox_friend_read_receipt_cb *call /** @} */ - /** @{ * @name Receiving private messages and friend requests */ @@ -1895,10 +1860,9 @@ void tox_callback_friend_read_receipt(Tox *tox, tox_friend_read_receipt_cb *call * @param length The size of the message byte array. */ typedef void tox_friend_request_cb( - Tox *tox, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE], - const uint8_t message[], size_t length, - void *user_data); - + Tox *tox, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE], + const uint8_t message[], size_t length, + void *user_data); /** * @brief Set the callback for the `friend_request` event. @@ -1915,9 +1879,8 @@ void tox_callback_friend_request(Tox *tox, tox_friend_request_cb *callback); * @param length The size of the message byte array. */ typedef void tox_friend_message_cb( - Tox *tox, Tox_Friend_Number friend_number, Tox_Message_Type type, - const uint8_t message[], size_t length, void *user_data); - + Tox *tox, Tox_Friend_Number friend_number, Tox_Message_Type type, + const uint8_t message[], size_t length, void *user_data); /** * @brief Set the callback for the `friend_message` event. @@ -1930,7 +1893,6 @@ void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *callback); /** @} */ - /** @{ * @name File transmission: common between sending and receiving */ @@ -1999,7 +1961,6 @@ enum Tox_File_Kind { }; - typedef enum Tox_File_Control { /** @@ -2026,7 +1987,6 @@ typedef enum Tox_File_Control { const char *tox_file_control_to_string(Tox_File_Control value); - typedef enum Tox_Err_File_Control { /** @@ -2074,7 +2034,6 @@ typedef enum Tox_Err_File_Control { const char *tox_err_file_control_to_string(Tox_Err_File_Control value); - /** * @brief Sends a file control command to a friend for a given file transfer. * @@ -2086,8 +2045,8 @@ const char *tox_err_file_control_to_string(Tox_Err_File_Control value); * @return true on success. */ bool tox_file_control( - Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, Tox_File_Control control, - Tox_Err_File_Control *error); + Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, Tox_File_Control control, + Tox_Err_File_Control *error); /** * @brief When receiving TOX_FILE_CONTROL_CANCEL, the client should release the @@ -2099,9 +2058,8 @@ bool tox_file_control( * @param control The file control command received. */ typedef void tox_file_recv_control_cb( - Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, Tox_File_Control control, - void *user_data); - + Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, Tox_File_Control control, + void *user_data); /** * @brief Set the callback for the `file_recv_control` event. @@ -2154,7 +2112,6 @@ typedef enum Tox_Err_File_Seek { const char *tox_err_file_seek_to_string(Tox_Err_File_Seek value); - /** * @brief Sends a file seek control command to a friend for a given file transfer. * @@ -2167,7 +2124,7 @@ const char *tox_err_file_seek_to_string(Tox_Err_File_Seek value); * @param position The position that the file should be seeked to. */ bool tox_file_seek( - Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, uint64_t position, Tox_Err_File_Seek *error); + Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, uint64_t position, Tox_Err_File_Seek *error); typedef enum Tox_Err_File_Get { @@ -2195,7 +2152,6 @@ typedef enum Tox_Err_File_Get { const char *tox_err_file_get_to_string(Tox_Err_File_Get value); - /** * @brief Copy the file id associated to the file transfer to a byte array. * @@ -2208,13 +2164,12 @@ const char *tox_err_file_get_to_string(Tox_Err_File_Get value); * @return true on success. */ bool tox_file_get_file_id( - const Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, - uint8_t file_id[TOX_FILE_ID_LENGTH], - Tox_Err_File_Get *error); + const Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, + uint8_t file_id[TOX_FILE_ID_LENGTH], + Tox_Err_File_Get *error); /** @} */ - /** @{ * @name File transmission: sending */ @@ -2256,7 +2211,6 @@ typedef enum Tox_Err_File_Send { const char *tox_err_file_send_to_string(Tox_Err_File_Send value); - /** * @brief Send a file transmission request. * @@ -2316,9 +2270,9 @@ const char *tox_err_file_send_to_string(Tox_Err_File_Send value); * should not be relied on. */ Tox_File_Number tox_file_send( - Tox *tox, Tox_Friend_Number friend_number, uint32_t kind, uint64_t file_size, - const uint8_t file_id[TOX_FILE_ID_LENGTH], const uint8_t filename[], size_t filename_length, - Tox_Err_File_Send *error); + Tox *tox, Tox_Friend_Number friend_number, uint32_t kind, uint64_t file_size, + const uint8_t file_id[TOX_FILE_ID_LENGTH], const uint8_t filename[], size_t filename_length, + Tox_Err_File_Send *error); typedef enum Tox_Err_File_Send_Chunk { @@ -2374,7 +2328,6 @@ typedef enum Tox_Err_File_Send_Chunk { const char *tox_err_file_send_chunk_to_string(Tox_Err_File_Send_Chunk value); - /** * @brief Send a chunk of file data to a friend. * @@ -2392,8 +2345,8 @@ const char *tox_err_file_send_chunk_to_string(Tox_Err_File_Send_Chunk value); * @return true on success. */ bool tox_file_send_chunk( - Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, uint64_t position, - const uint8_t data[], size_t length, Tox_Err_File_Send_Chunk *error); + Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, uint64_t position, + const uint8_t data[], size_t length, Tox_Err_File_Send_Chunk *error); /** * If the length parameter is 0, the file transfer is finished, and the client's @@ -2418,9 +2371,8 @@ bool tox_file_send_chunk( * @param length The number of bytes requested for the current chunk. */ typedef void tox_file_chunk_request_cb( - Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, uint64_t position, - size_t length, void *user_data); - + Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, uint64_t position, + size_t length, void *user_data); /** * @brief Set the callback for the `file_chunk_request` event. @@ -2433,7 +2385,6 @@ void tox_callback_file_chunk_request(Tox *tox, tox_file_chunk_request_cb *callba /** @} */ - /** @{ * @name File transmission: receiving */ @@ -2457,9 +2408,8 @@ void tox_callback_file_chunk_request(Tox *tox, tox_file_chunk_request_cb *callba * @param filename_length Size in bytes of the filename. */ typedef void tox_file_recv_cb( - Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, uint32_t kind, uint64_t file_size, - const uint8_t filename[], size_t filename_length, void *user_data); - + Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, uint32_t kind, uint64_t file_size, + const uint8_t filename[], size_t filename_length, void *user_data); /** * @brief Set the callback for the `file_recv` event. @@ -2487,9 +2437,8 @@ void tox_callback_file_recv(Tox *tox, tox_file_recv_cb *callback); * @param length The length of the received chunk. */ typedef void tox_file_recv_chunk_cb( - Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, uint64_t position, - const uint8_t data[], size_t length, void *user_data); - + Tox *tox, Tox_Friend_Number friend_number, Tox_File_Number file_number, uint64_t position, + const uint8_t data[], size_t length, void *user_data); /** * @brief Set the callback for the `file_recv_chunk` event. @@ -2503,13 +2452,13 @@ void tox_callback_file_recv_chunk(Tox *tox, tox_file_recv_chunk_cb *callback); /** @} */ - /** @{ * @name Conference management */ typedef uint32_t Tox_Conference_Number; typedef uint32_t Tox_Conference_Peer_Number; +typedef uint32_t Tox_Conference_Offline_Peer_Number; /** * @brief Conference types for the conference_invite event. @@ -2530,7 +2479,6 @@ typedef enum Tox_Conference_Type { const char *tox_conference_type_to_string(Tox_Conference_Type value); - /** * The invitation will remain valid until the inviting friend goes offline * or exits the conference. @@ -2542,9 +2490,8 @@ const char *tox_conference_type_to_string(Tox_Conference_Type value); * @param length The length of the cookie. */ typedef void tox_conference_invite_cb( - Tox *tox, Tox_Friend_Number friend_number, Tox_Conference_Type type, - const uint8_t cookie[], size_t length, void *user_data); - + Tox *tox, Tox_Friend_Number friend_number, Tox_Conference_Type type, + const uint8_t cookie[], size_t length, void *user_data); /** * @brief Set the callback for the `conference_invite` event. @@ -2560,7 +2507,6 @@ void tox_callback_conference_invite(Tox *tox, tox_conference_invite_cb *callback */ typedef void tox_conference_connected_cb(Tox *tox, Tox_Conference_Number conference_number, void *user_data); - /** * @brief Set the callback for the `conference_connected` event. * @@ -2580,9 +2526,8 @@ void tox_callback_conference_connected(Tox *tox, tox_conference_connected_cb *ca * @param length The length of the message. */ typedef void tox_conference_message_cb( - Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number peer_number, - Tox_Message_Type type, const uint8_t message[], size_t length, void *user_data); - + Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number peer_number, + Tox_Message_Type type, const uint8_t message[], size_t length, void *user_data); /** * @brief Set the callback for the `conference_message` event. @@ -2601,9 +2546,8 @@ void tox_callback_conference_message(Tox *tox, tox_conference_message_cb *callba * @param length The title length. */ typedef void tox_conference_title_cb( - Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number peer_number, - const uint8_t title[], size_t length, void *user_data); - + Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number peer_number, + const uint8_t title[], size_t length, void *user_data); /** * @brief Set the callback for the `conference_title` event. @@ -2624,9 +2568,8 @@ void tox_callback_conference_title(Tox *tox, tox_conference_title_cb *callback); * @param length The size of the name byte array. */ typedef void tox_conference_peer_name_cb( - Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number peer_number, - const uint8_t name[], size_t length, void *user_data); - + Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number peer_number, + const uint8_t name[], size_t length, void *user_data); /** * @brief Set the callback for the `conference_peer_name` event. @@ -2643,7 +2586,6 @@ void tox_callback_conference_peer_name(Tox *tox, tox_conference_peer_name_cb *ca */ typedef void tox_conference_peer_list_changed_cb(Tox *tox, Tox_Conference_Number conference_number, void *user_data); - /** * @brief Set the callback for the `conference_peer_list_changed` event. * @@ -2669,7 +2611,6 @@ typedef enum Tox_Err_Conference_New { const char *tox_err_conference_new_to_string(Tox_Err_Conference_New value); - /** * @brief Creates a new conference. * @@ -2697,7 +2638,6 @@ typedef enum Tox_Err_Conference_Delete { const char *tox_err_conference_delete_to_string(Tox_Err_Conference_Delete value); - /** * @brief This function deletes a conference. * @@ -2736,7 +2676,6 @@ typedef enum Tox_Err_Conference_Peer_Query { const char *tox_err_conference_peer_query_to_string(Tox_Err_Conference_Peer_Query value); - /** * @brief Return the number of online peers in the conference. * @@ -2744,8 +2683,8 @@ const char *tox_err_conference_peer_query_to_string(Tox_Err_Conference_Peer_Quer * peer_number for the functions querying these peers. Return value is * unspecified on failure. */ -Tox_Conference_Peer_Number tox_conference_peer_count( - const Tox *tox, Tox_Conference_Number conference_number, Tox_Err_Conference_Peer_Query *error); +uint32_t tox_conference_peer_count( + const Tox *tox, Tox_Conference_Number conference_number, Tox_Err_Conference_Peer_Query *error); /** * @brief Return the length of the peer's name. @@ -2753,8 +2692,8 @@ Tox_Conference_Peer_Number tox_conference_peer_count( * Return value is unspecified on failure. */ size_t tox_conference_peer_get_name_size( - const Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number peer_number, - Tox_Err_Conference_Peer_Query *error); + const Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number peer_number, + Tox_Err_Conference_Peer_Query *error); /** * @brief Copy the name of peer_number who is in conference_number to name. @@ -2766,8 +2705,8 @@ size_t tox_conference_peer_get_name_size( * @return true on success. */ bool tox_conference_peer_get_name( - const Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number peer_number, - uint8_t name[], Tox_Err_Conference_Peer_Query *error); + const Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number peer_number, + uint8_t name[], Tox_Err_Conference_Peer_Query *error); /** * @brief Copy the public key of peer_number who is in conference_number to public_key. @@ -2777,15 +2716,15 @@ bool tox_conference_peer_get_name( * @return true on success. */ bool tox_conference_peer_get_public_key( - const Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number peer_number, - uint8_t public_key[TOX_PUBLIC_KEY_SIZE], Tox_Err_Conference_Peer_Query *error); + const Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number peer_number, + uint8_t public_key[TOX_PUBLIC_KEY_SIZE], Tox_Err_Conference_Peer_Query *error); /** * @brief Return true if passed peer_number corresponds to our own. */ bool tox_conference_peer_number_is_ours( - const Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number peer_number, - Tox_Err_Conference_Peer_Query *error); + const Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number peer_number, + Tox_Err_Conference_Peer_Query *error); /** * @brief Return the number of offline peers in the conference. @@ -2796,8 +2735,8 @@ bool tox_conference_peer_number_is_ours( * Return value is unspecified on failure. */ uint32_t tox_conference_offline_peer_count( - const Tox *tox, Tox_Conference_Number conference_number, - Tox_Err_Conference_Peer_Query *error); + const Tox *tox, Tox_Conference_Number conference_number, + Tox_Err_Conference_Peer_Query *error); /** * @brief Return the length of the offline peer's name. @@ -2805,8 +2744,8 @@ uint32_t tox_conference_offline_peer_count( * Return value is unspecified on failure. */ size_t tox_conference_offline_peer_get_name_size( - const Tox *tox, Tox_Conference_Number conference_number, - Tox_Conference_Peer_Number offline_peer_number, Tox_Err_Conference_Peer_Query *error); + const Tox *tox, Tox_Conference_Number conference_number, + Tox_Conference_Offline_Peer_Number offline_peer_number, Tox_Err_Conference_Peer_Query *error); /** * @brief Copy the name of offline_peer_number who is in conference_number to name. @@ -2819,8 +2758,8 @@ size_t tox_conference_offline_peer_get_name_size( * @return true on success. */ bool tox_conference_offline_peer_get_name( - const Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number offline_peer_number, - uint8_t name[], Tox_Err_Conference_Peer_Query *error); + const Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Offline_Peer_Number offline_peer_number, + uint8_t name[], Tox_Err_Conference_Peer_Query *error); /** * @brief Copy the public key of offline_peer_number who is in conference_number to public_key. @@ -2830,15 +2769,15 @@ bool tox_conference_offline_peer_get_name( * @return true on success. */ bool tox_conference_offline_peer_get_public_key( - const Tox *tox, Tox_Conference_Number conference_number, - Tox_Conference_Peer_Number offline_peer_number, uint8_t public_key[TOX_PUBLIC_KEY_SIZE], Tox_Err_Conference_Peer_Query *error); + const Tox *tox, Tox_Conference_Number conference_number, + Tox_Conference_Offline_Peer_Number offline_peer_number, uint8_t public_key[TOX_PUBLIC_KEY_SIZE], Tox_Err_Conference_Peer_Query *error); /** * @brief Return a unix-time timestamp of the last time offline_peer_number was seen to be active. */ uint64_t tox_conference_offline_peer_get_last_active( - const Tox *tox, Tox_Conference_Number conference_number, - Tox_Conference_Peer_Number offline_peer_number, Tox_Err_Conference_Peer_Query *error); + const Tox *tox, Tox_Conference_Number conference_number, + Tox_Conference_Offline_Peer_Number offline_peer_number, Tox_Err_Conference_Peer_Query *error); typedef enum Tox_Err_Conference_Set_Max_Offline { @@ -2856,13 +2795,12 @@ typedef enum Tox_Err_Conference_Set_Max_Offline { const char *tox_err_conference_set_max_offline_to_string(Tox_Err_Conference_Set_Max_Offline value); - /** * @brief Set maximum number of offline peers to store, overriding the default. */ bool tox_conference_set_max_offline( - Tox *tox, Tox_Conference_Number conference_number, uint32_t max_offline, - Tox_Err_Conference_Set_Max_Offline *error); + Tox *tox, Tox_Conference_Number conference_number, uint32_t max_offline, + Tox_Err_Conference_Set_Max_Offline *error); typedef enum Tox_Err_Conference_Invite { @@ -2890,7 +2828,6 @@ typedef enum Tox_Err_Conference_Invite { const char *tox_err_conference_invite_to_string(Tox_Err_Conference_Invite value); - /** * @brief Invites a friend to a conference. * @@ -2900,8 +2837,8 @@ const char *tox_err_conference_invite_to_string(Tox_Err_Conference_Invite value) * @return true on success. */ bool tox_conference_invite( - Tox *tox, Tox_Friend_Number friend_number, Tox_Conference_Number conference_number, - Tox_Err_Conference_Invite *error); + Tox *tox, Tox_Friend_Number friend_number, Tox_Conference_Number conference_number, + Tox_Err_Conference_Invite *error); typedef enum Tox_Err_Conference_Join { @@ -2944,7 +2881,6 @@ typedef enum Tox_Err_Conference_Join { const char *tox_err_conference_join_to_string(Tox_Err_Conference_Join value); - /** * @brief Joins a conference that the client has been invited to. * @@ -2963,9 +2899,9 @@ const char *tox_err_conference_join_to_string(Tox_Err_Conference_Join value); * @return conference number on success, an unspecified value on failure. */ Tox_Conference_Number tox_conference_join( - Tox *tox, Tox_Friend_Number friend_number, - const uint8_t cookie[], size_t length, - Tox_Err_Conference_Join *error); + Tox *tox, Tox_Friend_Number friend_number, + const uint8_t cookie[], size_t length, + Tox_Err_Conference_Join *error); typedef enum Tox_Err_Conference_Send_Message { @@ -2998,7 +2934,6 @@ typedef enum Tox_Err_Conference_Send_Message { const char *tox_err_conference_send_message_to_string(Tox_Err_Conference_Send_Message value); - /** * @brief Send a text chat message to the conference. * @@ -3019,9 +2954,9 @@ const char *tox_err_conference_send_message_to_string(Tox_Err_Conference_Send_Me * @return true on success. */ bool tox_conference_send_message( - Tox *tox, Tox_Conference_Number conference_number, Tox_Message_Type type, - const uint8_t message[], size_t length, - Tox_Err_Conference_Send_Message *error); + Tox *tox, Tox_Conference_Number conference_number, Tox_Message_Type type, + const uint8_t message[], size_t length, + Tox_Err_Conference_Send_Message *error); typedef enum Tox_Err_Conference_Title { @@ -3049,7 +2984,6 @@ typedef enum Tox_Err_Conference_Title { const char *tox_err_conference_title_to_string(Tox_Err_Conference_Title value); - /** * @brief Return the length of the conference title. * @@ -3059,7 +2993,7 @@ const char *tox_err_conference_title_to_string(Tox_Err_Conference_Title value); * `conference_title` callback. */ size_t tox_conference_get_title_size( - const Tox *tox, Tox_Conference_Number conference_number, Tox_Err_Conference_Title *error); + const Tox *tox, Tox_Conference_Number conference_number, Tox_Err_Conference_Title *error); /** * @brief Write the title designated by the given conference number to a byte array. @@ -3075,9 +3009,9 @@ size_t tox_conference_get_title_size( * @return true on success. */ bool tox_conference_get_title( - const Tox *tox, Tox_Conference_Number conference_number, - uint8_t title[], - Tox_Err_Conference_Title *error); + const Tox *tox, Tox_Conference_Number conference_number, + uint8_t title[], + Tox_Err_Conference_Title *error); /** * @brief Set the conference title and broadcast it to the rest of the conference. @@ -3087,9 +3021,9 @@ bool tox_conference_get_title( * @return true on success. */ bool tox_conference_set_title( - Tox *tox, Tox_Conference_Number conference_number, - const uint8_t title[], size_t length, - Tox_Err_Conference_Title *error); + Tox *tox, Tox_Conference_Number conference_number, + const uint8_t title[], size_t length, + Tox_Err_Conference_Title *error); /** * @brief Return the number of conferences in the Tox instance. @@ -3135,13 +3069,12 @@ typedef enum Tox_Err_Conference_Get_Type { const char *tox_err_conference_get_type_to_string(Tox_Err_Conference_Get_Type value); - /** * @brief Get the type (text or A/V) for the conference. */ Tox_Conference_Type tox_conference_get_type( - const Tox *tox, Tox_Conference_Number conference_number, - Tox_Err_Conference_Get_Type *error); + const Tox *tox, Tox_Conference_Number conference_number, + Tox_Err_Conference_Get_Type *error); /** * @brief Get the conference unique ID. @@ -3153,7 +3086,7 @@ Tox_Conference_Type tox_conference_get_type( * @return true on success. */ bool tox_conference_get_id( - const Tox *tox, Tox_Conference_Number conference_number, uint8_t id[TOX_CONFERENCE_ID_SIZE]); + const Tox *tox, Tox_Conference_Number conference_number, uint8_t id[TOX_CONFERENCE_ID_SIZE]); typedef enum Tox_Err_Conference_By_Id { @@ -3176,7 +3109,6 @@ typedef enum Tox_Err_Conference_By_Id { const char *tox_err_conference_by_id_to_string(Tox_Err_Conference_By_Id value); - /** * @brief Return the conference number associated with the specified id. * @@ -3185,7 +3117,7 @@ const char *tox_err_conference_by_id_to_string(Tox_Err_Conference_By_Id value); * @return the conference number on success, an unspecified value on failure. */ Tox_Conference_Number tox_conference_by_id( - const Tox *tox, const uint8_t id[TOX_CONFERENCE_ID_SIZE], Tox_Err_Conference_By_Id *error); + const Tox *tox, const uint8_t id[TOX_CONFERENCE_ID_SIZE], Tox_Err_Conference_By_Id *error); /** * @brief Get the conference unique ID. @@ -3198,7 +3130,7 @@ Tox_Conference_Number tox_conference_by_id( * @deprecated use tox_conference_get_id instead (exactly the same function, just renamed). */ bool tox_conference_get_uid( - const Tox *tox, Tox_Conference_Number conference_number, uint8_t uid[TOX_CONFERENCE_UID_SIZE]); + const Tox *tox, Tox_Conference_Number conference_number, uint8_t uid[TOX_CONFERENCE_UID_SIZE]); typedef enum Tox_Err_Conference_By_Uid { @@ -3221,7 +3153,6 @@ typedef enum Tox_Err_Conference_By_Uid { const char *tox_err_conference_by_uid_to_string(Tox_Err_Conference_By_Uid value); - /** * @brief Return the conference number associated with the specified uid. * @@ -3231,11 +3162,10 @@ const char *tox_err_conference_by_uid_to_string(Tox_Err_Conference_By_Uid value) * @deprecated use tox_conference_by_id instead (exactly the same function, just renamed). */ Tox_Conference_Number tox_conference_by_uid( - const Tox *tox, const uint8_t uid[TOX_CONFERENCE_UID_SIZE], Tox_Err_Conference_By_Uid *error); + const Tox *tox, const uint8_t uid[TOX_CONFERENCE_UID_SIZE], Tox_Err_Conference_By_Uid *error); /** @} */ - /** @{ * @name Low-level custom packet sending and receiving */ @@ -3287,7 +3217,6 @@ typedef enum Tox_Err_Friend_Custom_Packet { const char *tox_err_friend_custom_packet_to_string(Tox_Err_Friend_Custom_Packet value); - /** * @brief Send a custom lossy packet to a friend. * @@ -3309,9 +3238,9 @@ const char *tox_err_friend_custom_packet_to_string(Tox_Err_Friend_Custom_Packet * @return true on success. */ bool tox_friend_send_lossy_packet( - Tox *tox, Tox_Friend_Number friend_number, - const uint8_t data[], size_t length, - Tox_Err_Friend_Custom_Packet *error); + Tox *tox, Tox_Friend_Number friend_number, + const uint8_t data[], size_t length, + Tox_Err_Friend_Custom_Packet *error); /** * @brief Send a custom lossless packet to a friend. @@ -3330,9 +3259,9 @@ bool tox_friend_send_lossy_packet( * @return true on success. */ bool tox_friend_send_lossless_packet( - Tox *tox, Tox_Friend_Number friend_number, - const uint8_t data[], size_t length, - Tox_Err_Friend_Custom_Packet *error); + Tox *tox, Tox_Friend_Number friend_number, + const uint8_t data[], size_t length, + Tox_Err_Friend_Custom_Packet *error); /** * @param friend_number The friend number of the friend who sent a lossy packet. @@ -3340,10 +3269,9 @@ bool tox_friend_send_lossless_packet( * @param length The length of the packet data byte array. */ typedef void tox_friend_lossy_packet_cb( - Tox *tox, Tox_Friend_Number friend_number, - const uint8_t data[], size_t length, - void *user_data); - + Tox *tox, Tox_Friend_Number friend_number, + const uint8_t data[], size_t length, + void *user_data); /** * @brief Set the callback for the `friend_lossy_packet` event. @@ -3358,10 +3286,9 @@ void tox_callback_friend_lossy_packet(Tox *tox, tox_friend_lossy_packet_cb *call * @param length The length of the packet data byte array. */ typedef void tox_friend_lossless_packet_cb( - Tox *tox, Tox_Friend_Number friend_number, - const uint8_t data[], size_t length, - void *user_data); - + Tox *tox, Tox_Friend_Number friend_number, + const uint8_t data[], size_t length, + void *user_data); /** * @brief Set the callback for the `friend_lossless_packet` event. @@ -3372,7 +3299,6 @@ void tox_callback_friend_lossless_packet(Tox *tox, tox_friend_lossless_packet_cb /** @} */ - /** @{ * @name Low-level network information */ @@ -3393,7 +3319,6 @@ typedef enum Tox_Err_Get_Port { const char *tox_err_get_port_to_string(Tox_Err_Get_Port value); - /** * @brief Writes the temporary DHT public key of this instance to a byte array. * @@ -3430,16 +3355,12 @@ typedef uint32_t Tox_Group_Number; typedef uint32_t Tox_Group_Peer_Number; typedef uint32_t Tox_Group_Message_Id; - - /******************************************************************************* * * :: Group chat numeric constants * ******************************************************************************/ - - /** * Maximum length of a group topic. */ @@ -3503,15 +3424,12 @@ uint32_t tox_group_chat_id_size(void); uint32_t tox_group_peer_public_key_size(void); - /******************************************************************************* * * :: Group chat state enumerators * ******************************************************************************/ - - /** * Represents the group privacy state. */ @@ -3541,7 +3459,6 @@ typedef enum Tox_Group_Privacy_State { const char *tox_group_privacy_state_to_string(Tox_Group_Privacy_State value); - /** * Represents the state of the group topic lock. */ @@ -3618,16 +3535,12 @@ typedef enum Tox_Group_Role { const char *tox_group_role_to_string(Tox_Group_Role value); - - /******************************************************************************* * * :: Group chat instance management * ******************************************************************************/ - - typedef enum Tox_Err_Group_New { /** @@ -3665,7 +3578,6 @@ typedef enum Tox_Err_Group_New { const char *tox_err_group_new_to_string(Tox_Err_Group_New value); - /** * Creates a new group chat. * @@ -3689,9 +3601,9 @@ const char *tox_err_group_new_to_string(Tox_Err_Group_New value); * @return group_number on success, UINT32_MAX on failure. */ Tox_Group_Number tox_group_new( - Tox *tox, Tox_Group_Privacy_State privacy_state, - const uint8_t group_name[], size_t group_name_length, - const uint8_t name[], size_t name_length, Tox_Err_Group_New *error); + Tox *tox, Tox_Group_Privacy_State privacy_state, + const uint8_t group_name[], size_t group_name_length, + const uint8_t name[], size_t name_length, Tox_Err_Group_New *error); typedef enum Tox_Err_Group_Join { @@ -3735,7 +3647,6 @@ typedef enum Tox_Err_Group_Join { const char *tox_err_group_join_to_string(Tox_Err_Group_Join value); - /** * Joins a group chat with specified Chat ID. * @@ -3754,10 +3665,10 @@ const char *tox_err_group_join_to_string(Tox_Err_Group_Join value); * @return group_number on success, UINT32_MAX on failure. */ Tox_Group_Number tox_group_join( - Tox *tox, const uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE], - const uint8_t name[], size_t name_length, - const uint8_t password[], size_t password_length, - Tox_Err_Group_Join *error); + Tox *tox, const uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE], + const uint8_t name[], size_t name_length, + const uint8_t password[], size_t password_length, + Tox_Err_Group_Join *error); typedef enum Tox_Err_Group_Is_Connected { @@ -3775,7 +3686,6 @@ typedef enum Tox_Err_Group_Is_Connected { const char *tox_err_group_is_connected_to_string(Tox_Err_Group_Is_Connected value); - /** * Returns true if the group chat is currently connected or attempting to connect to other peers * in the group. @@ -3804,7 +3714,6 @@ typedef enum Tox_Err_Group_Disconnect { const char *tox_err_group_disconnect_to_string(Tox_Err_Group_Disconnect value); - /** * Disconnects from a group chat while retaining the group state and credentials. * @@ -3835,7 +3744,6 @@ typedef enum Tox_Err_Group_Reconnect { const char *tox_err_group_reconnect_to_string(Tox_Err_Group_Reconnect value); - /** * Reconnects to a group. * @@ -3873,7 +3781,6 @@ typedef enum Tox_Err_Group_Leave { const char *tox_err_group_leave_to_string(Tox_Err_Group_Leave value); - /** * Leaves a group. * @@ -3889,10 +3796,9 @@ const char *tox_err_group_leave_to_string(Tox_Err_Group_Leave value); * @return true if the group chat instance is successfully deleted. */ bool tox_group_leave( - Tox *tox, Tox_Group_Number group_number, - const uint8_t part_message[], size_t length, - Tox_Err_Group_Leave *error); - + Tox *tox, Tox_Group_Number group_number, + const uint8_t part_message[], size_t length, + Tox_Err_Group_Leave *error); /******************************************************************************* * @@ -3900,8 +3806,6 @@ bool tox_group_leave( * ******************************************************************************/ - - /** * General error codes for self state get and size functions. */ @@ -3921,7 +3825,6 @@ typedef enum Tox_Err_Group_Self_Query { const char *tox_err_group_self_query_to_string(Tox_Err_Group_Self_Query value); - /** * Error codes for self name setting. */ @@ -3956,7 +3859,6 @@ typedef enum Tox_Err_Group_Self_Name_Set { const char *tox_err_group_self_name_set_to_string(Tox_Err_Group_Self_Name_Set value); - /** * Set the client's nickname for the group instance designated by the given group number. * @@ -3969,9 +3871,9 @@ const char *tox_err_group_self_name_set_to_string(Tox_Err_Group_Self_Name_Set va * @return true on success. */ bool tox_group_self_set_name( - Tox *tox, Tox_Group_Number group_number, - const uint8_t name[], size_t length, - Tox_Err_Group_Self_Name_Set *error); + Tox *tox, Tox_Group_Number group_number, + const uint8_t name[], size_t length, + Tox_Err_Group_Self_Name_Set *error); /** * Return the length of the client's current nickname for the group instance designated @@ -3998,8 +3900,8 @@ size_t tox_group_self_get_name_size(const Tox *tox, Tox_Group_Number group_numbe * @return true on success. */ bool tox_group_self_get_name( - const Tox *tox, Tox_Group_Number group_number, - uint8_t name[], Tox_Err_Group_Self_Query *error); + const Tox *tox, Tox_Group_Number group_number, + uint8_t name[], Tox_Err_Group_Self_Query *error); /** * Error codes for self status setting. @@ -4025,7 +3927,6 @@ typedef enum Tox_Err_Group_Self_Status_Set { const char *tox_err_group_self_status_set_to_string(Tox_Err_Group_Self_Status_Set value); - /** * Set the client's status for the group instance. Status must be a Tox_User_Status. * @@ -4069,15 +3970,12 @@ Tox_Group_Peer_Number tox_group_self_get_peer_id(const Tox *tox, Tox_Group_Numbe bool tox_group_self_get_public_key(const Tox *tox, Tox_Group_Number group_number, uint8_t public_key[TOX_PUBLIC_KEY_SIZE], Tox_Err_Group_Self_Query *error); - /******************************************************************************* * * :: Peer-specific group state queries. * ******************************************************************************/ - - /** * Error codes for peer info queries. */ @@ -4102,7 +4000,6 @@ typedef enum Tox_Err_Group_Peer_Query { const char *tox_err_group_peer_query_to_string(Tox_Err_Group_Peer_Query value); - /** * Return the length of the peer's name. If the group number or ID is invalid, the * return value is unspecified. @@ -4132,8 +4029,8 @@ size_t tox_group_peer_get_name_size(const Tox *tox, Tox_Group_Number group_numbe * @return true on success. */ bool tox_group_peer_get_name( - const Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, - uint8_t name[], Tox_Err_Group_Peer_Query *error); + const Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, + uint8_t name[], Tox_Err_Group_Peer_Query *error); /** * Return the peer's user status (away/busy/...). If the ID or group number is @@ -4190,8 +4087,8 @@ Tox_Connection tox_group_peer_get_connection_status(const Tox *tox, Tox_Group_Nu * @return true on success. */ bool tox_group_peer_get_public_key( - const Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, - uint8_t public_key[TOX_PUBLIC_KEY_SIZE], Tox_Err_Group_Peer_Query *error); + const Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, + uint8_t public_key[TOX_PUBLIC_KEY_SIZE], Tox_Err_Group_Peer_Query *error); /** * @param group_number The group number of the group the name change is intended for. @@ -4200,9 +4097,8 @@ bool tox_group_peer_get_public_key( * @param length The length of the name. */ typedef void tox_group_peer_name_cb( - Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, - const uint8_t name[], size_t length, void *user_data); - + Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, + const uint8_t name[], size_t length, void *user_data); /** * Set the callback for the `group_peer_name` event. Pass NULL to unset. @@ -4219,7 +4115,6 @@ void tox_callback_group_peer_name(Tox *tox, tox_group_peer_name_cb *callback); typedef void tox_group_peer_status_cb(Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_User_Status status, void *user_data); - /** * Set the callback for the `group_peer_status` event. Pass NULL to unset. * @@ -4227,34 +4122,30 @@ typedef void tox_group_peer_status_cb(Tox *tox, Tox_Group_Number group_number, T */ void tox_callback_group_peer_status(Tox *tox, tox_group_peer_status_cb *callback); - /******************************************************************************* * * :: Group chat state queries and events. * ******************************************************************************/ - - /** * General error codes for group state get and size functions. */ -typedef enum Tox_Err_Group_State_Queries { +typedef enum Tox_Err_Group_State_Query { /** * The function returned successfully. */ - TOX_ERR_GROUP_STATE_QUERIES_OK, + TOX_ERR_GROUP_STATE_QUERY_OK, /** * The group number passed did not designate a valid group. */ - TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND, + TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND, -} Tox_Err_Group_State_Queries; - -const char *tox_err_group_state_queries_to_string(Tox_Err_Group_State_Queries value); +} Tox_Err_Group_State_Query; +const char *tox_err_group_state_query_to_string(Tox_Err_Group_State_Query value); /** * Error codes for group topic setting. @@ -4300,7 +4191,6 @@ typedef enum Tox_Err_Group_Topic_Set { const char *tox_err_group_topic_set_to_string(Tox_Err_Group_Topic_Set value); - /** * Set the group topic and broadcast it to the rest of the group. * @@ -4310,9 +4200,9 @@ const char *tox_err_group_topic_set_to_string(Tox_Err_Group_Topic_Set value); * @return true on success. */ bool tox_group_set_topic( - Tox *tox, Tox_Group_Number group_number, - const uint8_t topic[], size_t length, - Tox_Err_Group_Topic_Set *error); + Tox *tox, Tox_Group_Number group_number, + const uint8_t topic[], size_t length, + Tox_Err_Group_Topic_Set *error); /** * Return the length of the group topic. If the group number is invalid, the @@ -4321,7 +4211,7 @@ bool tox_group_set_topic( * The return value is equal to the `length` argument received by the last * `group_topic` callback. */ -size_t tox_group_get_topic_size(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Queries *error); +size_t tox_group_get_topic_size(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Query *error); /** * Write the topic designated by the given group number to a byte array. @@ -4337,8 +4227,8 @@ size_t tox_group_get_topic_size(const Tox *tox, Tox_Group_Number group_number, T * @return true on success. */ bool tox_group_get_topic( - const Tox *tox, Tox_Group_Number group_number, - uint8_t topic[], Tox_Err_Group_State_Queries *error); + const Tox *tox, Tox_Group_Number group_number, + uint8_t topic[], Tox_Err_Group_State_Query *error); /** * @param group_number The group number of the group the topic change is intended for. @@ -4348,10 +4238,9 @@ bool tox_group_get_topic( * @param length The topic length. */ typedef void tox_group_topic_cb( - Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, - const uint8_t topic[], size_t length, - void *user_data); - + Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, + const uint8_t topic[], size_t length, + void *user_data); /** * Set the callback for the `group_topic` event. Pass NULL to unset. @@ -4364,7 +4253,7 @@ void tox_callback_group_topic(Tox *tox, tox_group_topic_cb *callback); * Return the length of the group name. If the group number is invalid, the * return value is unspecified. */ -size_t tox_group_get_name_size(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Queries *error); +size_t tox_group_get_name_size(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Query *error); /** * Write the name of the group designated by the given group number to a byte array. @@ -4377,8 +4266,8 @@ size_t tox_group_get_name_size(const Tox *tox, Tox_Group_Number group_number, To * @return true on success. */ bool tox_group_get_name( - const Tox *tox, Tox_Group_Number group_number, - uint8_t name[], Tox_Err_Group_State_Queries *error); + const Tox *tox, Tox_Group_Number group_number, + uint8_t name[], Tox_Err_Group_State_Query *error); /** * Write the Chat ID designated by the given group number to a byte array. @@ -4391,8 +4280,8 @@ bool tox_group_get_name( * @return true on success. */ bool tox_group_get_chat_id( - const Tox *tox, Tox_Group_Number group_number, uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE], - Tox_Err_Group_State_Queries *error); + const Tox *tox, Tox_Group_Number group_number, uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE], + Tox_Err_Group_State_Query *error); /** * Return the number of groups in the Tox chats array. @@ -4409,7 +4298,7 @@ uint32_t tox_group_get_number_groups(const Tox *tox); * @see the `Group chat founder controls` section for the respective set function. */ Tox_Group_Privacy_State tox_group_get_privacy_state(const Tox *tox, Tox_Group_Number group_number, - Tox_Err_Group_State_Queries *error); + Tox_Err_Group_State_Query *error); /** * @param group_number The group number of the group the privacy state is intended for. @@ -4418,7 +4307,6 @@ Tox_Group_Privacy_State tox_group_get_privacy_state(const Tox *tox, Tox_Group_Nu typedef void tox_group_privacy_state_cb(Tox *tox, Tox_Group_Number group_number, Tox_Group_Privacy_State privacy_state, void *user_data); - /** * Set the callback for the `group_privacy_state` event. Pass NULL to unset. * @@ -4435,7 +4323,7 @@ void tox_callback_group_privacy_state(Tox *tox, tox_group_privacy_state_cb *call * @see the `Group chat founder controls` section for the respective set function. */ Tox_Group_Voice_State tox_group_get_voice_state(const Tox *tox, Tox_Group_Number group_number, - Tox_Err_Group_State_Queries *error); + Tox_Err_Group_State_Query *error); /** * @param group_number The group number of the group the voice state change is intended for. @@ -4444,7 +4332,6 @@ Tox_Group_Voice_State tox_group_get_voice_state(const Tox *tox, Tox_Group_Number typedef void tox_group_voice_state_cb(Tox *tox, Tox_Group_Number group_number, Tox_Group_Voice_State voice_state, void *user_data); - /** * Set the callback for the `group_privacy_state` event. Pass NULL to unset. * @@ -4462,7 +4349,7 @@ void tox_callback_group_voice_state(Tox *tox, tox_group_voice_state_cb *callback * @see the `Group chat founder contols` section for the respective set function. */ Tox_Group_Topic_Lock tox_group_get_topic_lock(const Tox *tox, Tox_Group_Number group_number, - Tox_Err_Group_State_Queries *error); + Tox_Err_Group_State_Query *error); /** * @param group_number The group number of the group for which the topic lock has changed. @@ -4470,8 +4357,6 @@ Tox_Group_Topic_Lock tox_group_get_topic_lock(const Tox *tox, Tox_Group_Number g */ typedef void tox_group_topic_lock_cb(Tox *tox, Tox_Group_Number group_number, Tox_Group_Topic_Lock topic_lock, void *user_data); - - /** * Set the callback for the `group_topic_lock` event. Pass NULL to unset. * @@ -4488,7 +4373,7 @@ void tox_callback_group_topic_lock(Tox *tox, tox_group_topic_lock_cb *callback); * * @see the `Group chat founder controls` section for the respective set function. */ -uint16_t tox_group_get_peer_limit(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Queries *error); +uint16_t tox_group_get_peer_limit(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Query *error); /** * @param group_number The group number of the group for which the peer limit has changed. @@ -4496,7 +4381,6 @@ uint16_t tox_group_get_peer_limit(const Tox *tox, Tox_Group_Number group_number, */ typedef void tox_group_peer_limit_cb(Tox *tox, Tox_Group_Number group_number, uint32_t peer_limit, void *user_data); - /** * Set the callback for the `group_peer_limit` event. Pass NULL to unset. * @@ -4508,7 +4392,7 @@ void tox_callback_group_peer_limit(Tox *tox, tox_group_peer_limit_cb *callback); * Return the length of the group password. If the group number is invalid, the * return value is unspecified. */ -size_t tox_group_get_password_size(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Queries *error); +size_t tox_group_get_password_size(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Query *error); /** * Write the password for the group designated by the given group number to a byte array. @@ -4518,7 +4402,7 @@ size_t tox_group_get_password_size(const Tox *tox, Tox_Group_Number group_number * The data received is equal to the data received by the last * `group_password` callback. * - * @see the `Group chat founder controls` section for the respective set function. + * @see the `Group chat Founder controls` section for the respective set function. * * @param password A valid memory region large enough to store the group password. * If this parameter is NULL, this function call has no effect. @@ -4526,8 +4410,8 @@ size_t tox_group_get_password_size(const Tox *tox, Tox_Group_Number group_number * @return true on success. */ bool tox_group_get_password( - const Tox *tox, Tox_Group_Number group_number, uint8_t password[], - Tox_Err_Group_State_Queries *error); + const Tox *tox, Tox_Group_Number group_number, uint8_t password[], + Tox_Err_Group_State_Query *error); /** * @param group_number The group number of the group for which the password has changed. @@ -4535,10 +4419,9 @@ bool tox_group_get_password( * @param length The length of the password. */ typedef void tox_group_password_cb( - Tox *tox, Tox_Group_Number group_number, - const uint8_t password[], size_t length, - void *user_data); - + Tox *tox, Tox_Group_Number group_number, + const uint8_t password[], size_t length, + void *user_data); /** * Set the callback for the `group_password` event. Pass NULL to unset. @@ -4547,15 +4430,12 @@ typedef void tox_group_password_cb( */ void tox_callback_group_password(Tox *tox, tox_group_password_cb *callback); - /******************************************************************************* * * :: Group chat message sending * ******************************************************************************/ - - typedef enum Tox_Err_Group_Send_Message { /** @@ -4602,7 +4482,6 @@ typedef enum Tox_Err_Group_Send_Message { const char *tox_err_group_send_message_to_string(Tox_Err_Group_Send_Message value); - /** * Send a text chat message to the group. * @@ -4623,9 +4502,9 @@ const char *tox_err_group_send_message_to_string(Tox_Err_Group_Send_Message valu * returned message ID value will be undefined. */ Tox_Group_Message_Id tox_group_send_message( - const Tox *tox, Tox_Group_Number group_number, Tox_Message_Type type, - const uint8_t message[], size_t length, - Tox_Err_Group_Send_Message *error); + const Tox *tox, Tox_Group_Number group_number, Tox_Message_Type type, + const uint8_t message[], size_t length, + Tox_Err_Group_Send_Message *error); typedef enum Tox_Err_Group_Send_Private_Message { @@ -4678,7 +4557,6 @@ typedef enum Tox_Err_Group_Send_Private_Message { const char *tox_err_group_send_private_message_to_string(Tox_Err_Group_Send_Private_Message value); - /** * Send a text chat message to the specified peer in the specified group. * @@ -4697,10 +4575,10 @@ const char *tox_err_group_send_private_message_to_string(Tox_Err_Group_Send_Priv * * @return true on success. */ -bool tox_group_send_private_message( - const Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Message_Type type, - const uint8_t message[], size_t length, - Tox_Err_Group_Send_Private_Message *error); +Tox_Group_Message_Id tox_group_send_private_message( + const Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Message_Type type, + const uint8_t message[], size_t length, + Tox_Err_Group_Send_Private_Message *error); typedef enum Tox_Err_Group_Send_Custom_Packet { @@ -4726,11 +4604,6 @@ typedef enum Tox_Err_Group_Send_Custom_Packet { */ TOX_ERR_GROUP_SEND_CUSTOM_PACKET_EMPTY, - /** - * The caller does not have the required permissions to send group messages. - */ - TOX_ERR_GROUP_SEND_CUSTOM_PACKET_PERMISSIONS, - /** * The group is disconnected. */ @@ -4746,7 +4619,6 @@ typedef enum Tox_Err_Group_Send_Custom_Packet { const char *tox_err_group_send_custom_packet_to_string(Tox_Err_Group_Send_Custom_Packet value); - /** * Send a custom packet to the group. * @@ -4772,10 +4644,9 @@ const char *tox_err_group_send_custom_packet_to_string(Tox_Err_Group_Send_Custom * @return true on success. */ bool tox_group_send_custom_packet( - const Tox *tox, Tox_Group_Number group_number, bool lossless, - const uint8_t data[], size_t length, - Tox_Err_Group_Send_Custom_Packet *error); - + const Tox *tox, Tox_Group_Number group_number, bool lossless, + const uint8_t data[], size_t length, + Tox_Err_Group_Send_Custom_Packet *error); typedef enum Tox_Err_Group_Send_Custom_Private_Packet { @@ -4806,11 +4677,6 @@ typedef enum Tox_Err_Group_Send_Custom_Private_Packet { */ TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_PEER_NOT_FOUND, - /** - * The caller does not have the required permissions to send group messages. - */ - TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_PERMISSIONS, - /** * The packet failed to send. */ @@ -4854,15 +4720,12 @@ bool tox_group_send_custom_private_packet(const Tox *tox, Tox_Group_Number group const uint8_t data[], size_t length, Tox_Err_Group_Send_Custom_Private_Packet *error); - /******************************************************************************* * * :: Group chat message receiving * ******************************************************************************/ - - /** * @param group_number The group number of the group the message is intended for. * @param peer_id The ID of the peer who sent the message. @@ -4872,9 +4735,8 @@ bool tox_group_send_custom_private_packet(const Tox *tox, Tox_Group_Number group * @param length The length of the message. */ typedef void tox_group_message_cb( - Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Message_Type type, - const uint8_t message[], size_t length, Tox_Group_Message_Id message_id, void *user_data); - + Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Message_Type type, + const uint8_t message[], size_t length, Tox_Group_Message_Id message_id, void *user_data); /** * Set the callback for the `group_message` event. Pass NULL to unset. @@ -4890,9 +4752,8 @@ void tox_callback_group_message(Tox *tox, tox_group_message_cb *callback); * @param length The length of the message. */ typedef void tox_group_private_message_cb( - Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Message_Type type, - const uint8_t message[], size_t length, void *user_data); - + Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Message_Type type, + const uint8_t message[], size_t length, Tox_Group_Message_Id message_id, void *user_data); /** * Set the callback for the `group_private_message` event. Pass NULL to unset. @@ -4908,9 +4769,8 @@ void tox_callback_group_private_message(Tox *tox, tox_group_private_message_cb * * @param length The length of the data. */ typedef void tox_group_custom_packet_cb( - Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, - const uint8_t data[], size_t length, void *user_data); - + Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, + const uint8_t data[], size_t length, void *user_data); /** * Set the callback for the `group_custom_packet` event. Pass NULL to unset. @@ -4926,9 +4786,8 @@ void tox_callback_group_custom_packet(Tox *tox, tox_group_custom_packet_cb *call * @param length The length of the data. */ typedef void tox_group_custom_private_packet_cb( - Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, - const uint8_t data[], size_t length, void *user_data); - + Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, + const uint8_t data[], size_t length, void *user_data); /** * Set the callback for the `group_custom_private_packet` event. Pass NULL to unset. @@ -4937,15 +4796,12 @@ typedef void tox_group_custom_private_packet_cb( */ void tox_callback_group_custom_private_packet(Tox *tox, tox_group_custom_private_packet_cb *callback); - /******************************************************************************* * * :: Group chat inviting and join/part events * ******************************************************************************/ - - typedef enum Tox_Err_Group_Invite_Friend { /** @@ -4982,7 +4838,6 @@ typedef enum Tox_Err_Group_Invite_Friend { const char *tox_err_group_invite_friend_to_string(Tox_Err_Group_Invite_Friend value); - /** * Invite a friend to a group. * @@ -4994,8 +4849,8 @@ const char *tox_err_group_invite_friend_to_string(Tox_Err_Group_Invite_Friend va * @return true on success. */ bool tox_group_invite_friend( - const Tox *tox, Tox_Group_Number group_number, Tox_Friend_Number friend_number, - Tox_Err_Group_Invite_Friend *error); + const Tox *tox, Tox_Group_Number group_number, Tox_Friend_Number friend_number, + Tox_Err_Group_Invite_Friend *error); typedef enum Tox_Err_Group_Invite_Accept { @@ -5043,7 +4898,6 @@ typedef enum Tox_Err_Group_Invite_Accept { const char *tox_err_group_invite_accept_to_string(Tox_Err_Group_Invite_Accept value); - /** * Accept an invite to a group chat that the client previously received from a friend. The invite * is only valid while the inviter is present in the group. @@ -5060,11 +4914,11 @@ const char *tox_err_group_invite_accept_to_string(Tox_Err_Group_Invite_Accept va * @return the group_number on success, UINT32_MAX on failure. */ Tox_Group_Number tox_group_invite_accept( - Tox *tox, Tox_Friend_Number friend_number, - const uint8_t invite_data[], size_t length, - const uint8_t name[], size_t name_length, - const uint8_t password[], size_t password_length, - Tox_Err_Group_Invite_Accept *error); + Tox *tox, Tox_Friend_Number friend_number, + const uint8_t invite_data[], size_t length, + const uint8_t name[], size_t name_length, + const uint8_t password[], size_t password_length, + Tox_Err_Group_Invite_Accept *error); /** * @param friend_number The friend number of the contact who sent the invite. @@ -5072,11 +4926,10 @@ Tox_Group_Number tox_group_invite_accept( * @param length The length of invite_data. */ typedef void tox_group_invite_cb( - Tox *tox, Tox_Friend_Number friend_number, - const uint8_t invite_data[], size_t length, - const uint8_t group_name[], size_t group_name_length, - void *user_data); - + Tox *tox, Tox_Friend_Number friend_number, + const uint8_t invite_data[], size_t length, + const uint8_t group_name[], size_t group_name_length, + void *user_data); /** * Set the callback for the `group_invite` event. Pass NULL to unset. @@ -5093,7 +4946,6 @@ void tox_callback_group_invite(Tox *tox, tox_group_invite_cb *callback); */ typedef void tox_group_peer_join_cb(Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, void *user_data); - /** * Set the callback for the `group_peer_join` event. Pass NULL to unset. * @@ -5141,7 +4993,6 @@ typedef enum Tox_Group_Exit_Type { const char *tox_group_exit_type_to_string(Tox_Group_Exit_Type value); - /** * @param group_number The group number of the group in which a peer has left. * @param peer_id The ID of the peer who left the group. This ID no longer designates a valid peer @@ -5153,10 +5004,9 @@ const char *tox_group_exit_type_to_string(Tox_Group_Exit_Type value); * @param part_message_length The length of the parting message. */ typedef void tox_group_peer_exit_cb( - Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Group_Exit_Type exit_type, - const uint8_t name[], size_t name_length, - const uint8_t part_message[], size_t part_message_length, void *user_data); - + Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Group_Exit_Type exit_type, + const uint8_t name[], size_t name_length, + const uint8_t part_message[], size_t part_message_length, void *user_data); /** * Set the callback for the `group_peer_exit` event. Pass NULL to unset. @@ -5170,7 +5020,6 @@ void tox_callback_group_peer_exit(Tox *tox, tox_group_peer_exit_cb *callback); */ typedef void tox_group_self_join_cb(Tox *tox, Tox_Group_Number group_number, void *user_data); - /** * Set the callback for the `group_self_join` event. Pass NULL to unset. * @@ -5205,14 +5054,12 @@ typedef enum Tox_Group_Join_Fail { const char *tox_group_join_fail_to_string(Tox_Group_Join_Fail value); - /** * @param group_number The group number of the group for which the join has failed. * @param fail_type The type of group rejection. */ typedef void tox_group_join_fail_cb(Tox *tox, Tox_Group_Number group_number, Tox_Group_Join_Fail fail_type, void *user_data); - /** * Set the callback for the `group_join_fail` event. Pass NULL to unset. * @@ -5220,62 +5067,58 @@ typedef void tox_group_join_fail_cb(Tox *tox, Tox_Group_Number group_number, Tox */ void tox_callback_group_join_fail(Tox *tox, tox_group_join_fail_cb *callback); - /******************************************************************************* * - * :: Group chat founder controls (these only work for the group founder) + * :: Group chat Founder controls * ******************************************************************************/ - - -typedef enum Tox_Err_Group_Founder_Set_Password { +typedef enum Tox_Err_Group_Set_Password { /** * The function returned successfully. */ - TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK, + TOX_ERR_GROUP_SET_PASSWORD_OK, /** * The group number passed did not designate a valid group. */ - TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_GROUP_NOT_FOUND, + TOX_ERR_GROUP_SET_PASSWORD_GROUP_NOT_FOUND, /** * The caller does not have the required permissions to set the password. */ - TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_PERMISSIONS, + TOX_ERR_GROUP_SET_PASSWORD_PERMISSIONS, /** * Password length exceeded TOX_GROUP_MAX_PASSWORD_SIZE. */ - TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_TOO_LONG, + TOX_ERR_GROUP_SET_PASSWORD_TOO_LONG, /** * The packet failed to send. */ - TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_FAIL_SEND, + TOX_ERR_GROUP_SET_PASSWORD_FAIL_SEND, /** * The function failed to allocate enough memory for the operation. */ - TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_MALLOC, + TOX_ERR_GROUP_SET_PASSWORD_MALLOC, /** * The group is disconnected. */ - TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_DISCONNECTED, + TOX_ERR_GROUP_SET_PASSWORD_DISCONNECTED, -} Tox_Err_Group_Founder_Set_Password; - -const char *tox_err_group_founder_set_password_to_string(Tox_Err_Group_Founder_Set_Password value); +} Tox_Err_Group_Set_Password; +const char *tox_err_group_set_password_to_string(Tox_Err_Group_Set_Password value); /** * Set or unset the group password. * - * This function sets the groups password, creates a new group shared state including the change, - * and distributes it to the rest of the group. + * This function allows Founders to set or unset a group password. It will create a new + * group shared state including the change and distribute it to the rest of the group. * * @param group_number The group number of the group for which we wish to set the password. * @param password The password we want to set. Set password to NULL to unset the password. @@ -5283,59 +5126,58 @@ const char *tox_err_group_founder_set_password_to_string(Tox_Err_Group_Founder_S * * @return true on success. */ -bool tox_group_founder_set_password( - Tox *tox, Tox_Group_Number group_number, - const uint8_t password[], size_t length, - Tox_Err_Group_Founder_Set_Password *error); +bool tox_group_set_password( + Tox *tox, Tox_Group_Number group_number, + const uint8_t password[], size_t length, + Tox_Err_Group_Set_Password *error); -typedef enum Tox_Err_Group_Founder_Set_Topic_Lock { +typedef enum Tox_Err_Group_Set_Topic_Lock { /** * The function returned successfully. */ - TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, + TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, /** * The group number passed did not designate a valid group. */ - TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_GROUP_NOT_FOUND, + TOX_ERR_GROUP_SET_TOPIC_LOCK_GROUP_NOT_FOUND, /** * Tox_Group_Topic_Lock is an invalid type. */ - TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_INVALID, + TOX_ERR_GROUP_SET_TOPIC_LOCK_INVALID, /** * The caller does not have the required permissions to set the topic lock. */ - TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_PERMISSIONS, + TOX_ERR_GROUP_SET_TOPIC_LOCK_PERMISSIONS, /** * The topic lock could not be set. This may occur due to an error related to * cryptographic signing of the new shared state. */ - TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SET, + TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SET, /** * The packet failed to send. */ - TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SEND, + TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SEND, /** * The group is disconnected. */ - TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_DISCONNECTED, + TOX_ERR_GROUP_SET_TOPIC_LOCK_DISCONNECTED, -} Tox_Err_Group_Founder_Set_Topic_Lock; - -const char *tox_err_group_founder_set_topic_lock_to_string(Tox_Err_Group_Founder_Set_Topic_Lock value); +} Tox_Err_Group_Set_Topic_Lock; +const char *tox_err_group_set_topic_lock_to_string(Tox_Err_Group_Set_Topic_Lock value); /** * Set the group topic lock state. * - * This function sets the group's topic lock state to enabled or disabled, creates a new shared - * state including the change, and distributes it to the rest of the group. + * This function allows Founders to enable or disable the group's topic lock. It will create a + * new shared state including the change and distribute it to the rest of the group. * * When the topic lock is enabled, only the group founder and moderators may set the topic. * When disabled, all peers except those with the observer role may set the topic. @@ -5345,51 +5187,51 @@ const char *tox_err_group_founder_set_topic_lock_to_string(Tox_Err_Group_Founder * * @return true on success. */ -bool tox_group_founder_set_topic_lock(Tox *tox, Tox_Group_Number group_number, Tox_Group_Topic_Lock topic_lock, - Tox_Err_Group_Founder_Set_Topic_Lock *error); +bool tox_group_set_topic_lock(Tox *tox, Tox_Group_Number group_number, Tox_Group_Topic_Lock topic_lock, + Tox_Err_Group_Set_Topic_Lock *error); -typedef enum Tox_Err_Group_Founder_Set_Voice_State { +typedef enum Tox_Err_Group_Set_Voice_State { /** * The function returned successfully. */ - TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK, + TOX_ERR_GROUP_SET_VOICE_STATE_OK, /** * The group number passed did not designate a valid group. */ - TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_GROUP_NOT_FOUND, + TOX_ERR_GROUP_SET_VOICE_STATE_GROUP_NOT_FOUND, /** * The caller does not have the required permissions to set the privacy state. */ - TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_PERMISSIONS, + TOX_ERR_GROUP_SET_VOICE_STATE_PERMISSIONS, /** * The voice state could not be set. This may occur due to an error related to * cryptographic signing of the new shared state. */ - TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SET, + TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SET, /** * The packet failed to send. */ - TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SEND, + TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SEND, /** * The group is disconnected. */ - TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_DISCONNECTED, + TOX_ERR_GROUP_SET_VOICE_STATE_DISCONNECTED, -} Tox_Err_Group_Founder_Set_Voice_State; +} Tox_Err_Group_Set_Voice_State; -const char *tox_err_group_founder_set_voice_state_to_string(Tox_Err_Group_Founder_Set_Voice_State value); +const char *tox_err_group_set_voice_state_to_string(Tox_Err_Group_Set_Voice_State value); /** * Set the group voice state. * - * This function sets the group's voice state, creates a new group shared state - * including the change, and distributes it to the rest of the group. + * This function allows Founders to set the group's voice state. It will create a new group + * shared state including the change and distribute it to the rest of the group. * * If an attempt is made to set the voice state to the same state that the group is already * in, the function call will be successful and no action will be taken. @@ -5399,51 +5241,51 @@ const char *tox_err_group_founder_set_voice_state_to_string(Tox_Err_Group_Founde * * @return true on success. */ -bool tox_group_founder_set_voice_state(Tox *tox, Tox_Group_Number group_number, Tox_Group_Voice_State voice_state, - Tox_Err_Group_Founder_Set_Voice_State *error); +bool tox_group_set_voice_state(Tox *tox, Tox_Group_Number group_number, Tox_Group_Voice_State voice_state, + Tox_Err_Group_Set_Voice_State *error); -typedef enum Tox_Err_Group_Founder_Set_Privacy_State { +typedef enum Tox_Err_Group_Set_Privacy_State { /** * The function returned successfully. */ - TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK, + TOX_ERR_GROUP_SET_PRIVACY_STATE_OK, /** * The group number passed did not designate a valid group. */ - TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_GROUP_NOT_FOUND, + TOX_ERR_GROUP_SET_PRIVACY_STATE_GROUP_NOT_FOUND, /** * The caller does not have the required permissions to set the privacy state. */ - TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_PERMISSIONS, + TOX_ERR_GROUP_SET_PRIVACY_STATE_PERMISSIONS, /** * The privacy state could not be set. This may occur due to an error related to * cryptographic signing of the new shared state. */ - TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SET, + TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SET, /** * The packet failed to send. */ - TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SEND, + TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SEND, /** * The group is disconnected. */ - TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_DISCONNECTED, + TOX_ERR_GROUP_SET_PRIVACY_STATE_DISCONNECTED, -} Tox_Err_Group_Founder_Set_Privacy_State; +} Tox_Err_Group_Set_Privacy_State; -const char *tox_err_group_founder_set_privacy_state_to_string(Tox_Err_Group_Founder_Set_Privacy_State value); +const char *tox_err_group_set_privacy_state_to_string(Tox_Err_Group_Set_Privacy_State value); /** * Set the group privacy state. * - * This function sets the group's privacy state, creates a new group shared state - * including the change, and distributes it to the rest of the group. + * This function allows Founders to set the group's privacy state. It will create a new group + * shared state including the change and distribute it to the rest of the group. * * If an attempt is made to set the privacy state to the same state that the group is already * in, the function call will be successful and no action will be taken. @@ -5453,70 +5295,67 @@ const char *tox_err_group_founder_set_privacy_state_to_string(Tox_Err_Group_Foun * * @return true on success. */ -bool tox_group_founder_set_privacy_state(Tox *tox, Tox_Group_Number group_number, Tox_Group_Privacy_State privacy_state, - Tox_Err_Group_Founder_Set_Privacy_State *error); +bool tox_group_set_privacy_state(Tox *tox, Tox_Group_Number group_number, Tox_Group_Privacy_State privacy_state, + Tox_Err_Group_Set_Privacy_State *error); -typedef enum Tox_Err_Group_Founder_Set_Peer_Limit { +typedef enum Tox_Err_Group_Set_Peer_Limit { /** * The function returned successfully. */ - TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK, + TOX_ERR_GROUP_SET_PEER_LIMIT_OK, /** * The group number passed did not designate a valid group. */ - TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_GROUP_NOT_FOUND, + TOX_ERR_GROUP_SET_PEER_LIMIT_GROUP_NOT_FOUND, /** * The caller does not have the required permissions to set the peer limit. */ - TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_PERMISSIONS, + TOX_ERR_GROUP_SET_PEER_LIMIT_PERMISSIONS, /** * The peer limit could not be set. This may occur due to an error related to * cryptographic signing of the new shared state. */ - TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SET, + TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SET, /** * The packet failed to send. */ - TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SEND, + TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SEND, /** * The group is disconnected. */ - TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_DISCONNECTED, + TOX_ERR_GROUP_SET_PEER_LIMIT_DISCONNECTED, -} Tox_Err_Group_Founder_Set_Peer_Limit; - -const char *tox_err_group_founder_set_peer_limit_to_string(Tox_Err_Group_Founder_Set_Peer_Limit value); +} Tox_Err_Group_Set_Peer_Limit; +const char *tox_err_group_set_peer_limit_to_string(Tox_Err_Group_Set_Peer_Limit value); /** * Set the group peer limit. * - * This function sets a limit for the number of peers who may be in the group, creates a new - * group shared state including the change, and distributes it to the rest of the group. + * This function allows Founders to set a limit for the number of peers who may be in the + * group. It will create a new group shared state including the change and distribute it to the + * rest of the group. * * @param group_number The group number of the group for which we wish to set the peer limit. * @param peer_limit The maximum number of peers to allow in the group. * * @return true on success. */ -bool tox_group_founder_set_peer_limit(Tox *tox, Tox_Group_Number group_number, uint16_t peer_limit, - Tox_Err_Group_Founder_Set_Peer_Limit *error); - +bool tox_group_set_peer_limit(Tox *tox, Tox_Group_Number group_number, uint16_t peer_limit, + Tox_Err_Group_Set_Peer_Limit *error); /******************************************************************************* * - * :: Group chat moderation + * :: Group chat moderation controls * ******************************************************************************/ - - typedef enum Tox_Err_Group_Set_Ignore { /** @@ -5543,7 +5382,6 @@ typedef enum Tox_Err_Group_Set_Ignore { const char *tox_err_group_set_ignore_to_string(Tox_Err_Group_Set_Ignore value); - /** * Ignore or unignore a peer. * @@ -5556,56 +5394,59 @@ const char *tox_err_group_set_ignore_to_string(Tox_Err_Group_Set_Ignore value); bool tox_group_set_ignore(Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, bool ignore, Tox_Err_Group_Set_Ignore *error); -typedef enum Tox_Err_Group_Mod_Set_Role { +typedef enum Tox_Err_Group_Set_Role { /** * The function returned successfully. */ - TOX_ERR_GROUP_MOD_SET_ROLE_OK, + TOX_ERR_GROUP_SET_ROLE_OK, /** * The group number passed did not designate a valid group. */ - TOX_ERR_GROUP_MOD_SET_ROLE_GROUP_NOT_FOUND, + TOX_ERR_GROUP_SET_ROLE_GROUP_NOT_FOUND, /** * The ID passed did not designate a valid peer. Note: you cannot set your own role. */ - TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND, + TOX_ERR_GROUP_SET_ROLE_PEER_NOT_FOUND, /** * The caller does not have the required permissions for this action. */ - TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS, + TOX_ERR_GROUP_SET_ROLE_PERMISSIONS, /** * The role assignment is invalid. This will occur if you try to set a peer's role to * the role they already have. */ - TOX_ERR_GROUP_MOD_SET_ROLE_ASSIGNMENT, + TOX_ERR_GROUP_SET_ROLE_ASSIGNMENT, /** * The role was not successfully set. This may occur if the packet failed to send, or * if the role limit has been reached. */ - TOX_ERR_GROUP_MOD_SET_ROLE_FAIL_ACTION, + TOX_ERR_GROUP_SET_ROLE_FAIL_ACTION, /** * The caller attempted to set their own role. */ - TOX_ERR_GROUP_MOD_SET_ROLE_SELF, + TOX_ERR_GROUP_SET_ROLE_SELF, -} Tox_Err_Group_Mod_Set_Role; - -const char *tox_err_group_mod_set_role_to_string(Tox_Err_Group_Mod_Set_Role value); +} Tox_Err_Group_Set_Role; +const char *tox_err_group_set_role_to_string(Tox_Err_Group_Set_Role value); /** * Set a peer's role. * * This function will first remove the peer's previous role and then assign them a new role. * It will also send a packet to the rest of the group, requesting that they perform - * the role reassignment. Note: peers cannot be set to the founder role. + * the role reassignment. + * + * Only Founders may promote peers to the Moderator role, and only Founders and Moderators may + * set peers to the Observer or User role. Moderators may not set the role of other Moderators + * or the Founder. Peers may not be promoted to the Founder role. * * @param group_number The group number of the group the in which you wish set the peer's role. * @param peer_id The ID of the peer whose role you wish to set. @@ -5613,65 +5454,65 @@ const char *tox_err_group_mod_set_role_to_string(Tox_Err_Group_Mod_Set_Role valu * * @return true on success. */ -bool tox_group_mod_set_role(Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Group_Role role, - Tox_Err_Group_Mod_Set_Role *error); +bool tox_group_set_role(Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Group_Role role, + Tox_Err_Group_Set_Role *error); -typedef enum Tox_Err_Group_Mod_Kick_Peer { +typedef enum Tox_Err_Group_Kick_Peer { /** * The function returned successfully. */ - TOX_ERR_GROUP_MOD_KICK_PEER_OK, + TOX_ERR_GROUP_KICK_PEER_OK, /** * The group number passed did not designate a valid group. */ - TOX_ERR_GROUP_MOD_KICK_PEER_GROUP_NOT_FOUND, + TOX_ERR_GROUP_KICK_PEER_GROUP_NOT_FOUND, /** * The ID passed did not designate a valid peer. */ - TOX_ERR_GROUP_MOD_KICK_PEER_PEER_NOT_FOUND, + TOX_ERR_GROUP_KICK_PEER_PEER_NOT_FOUND, /** * The caller does not have the required permissions for this action. */ - TOX_ERR_GROUP_MOD_KICK_PEER_PERMISSIONS, + TOX_ERR_GROUP_KICK_PEER_PERMISSIONS, /** * The peer could not be kicked from the group. */ - TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_ACTION, + TOX_ERR_GROUP_KICK_PEER_FAIL_ACTION, /** * The packet failed to send. */ - TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_SEND, + TOX_ERR_GROUP_KICK_PEER_FAIL_SEND, /** * The caller attempted to set their own role. */ - TOX_ERR_GROUP_MOD_KICK_PEER_SELF, + TOX_ERR_GROUP_KICK_PEER_SELF, -} Tox_Err_Group_Mod_Kick_Peer; - -const char *tox_err_group_mod_kick_peer_to_string(Tox_Err_Group_Mod_Kick_Peer value); +} Tox_Err_Group_Kick_Peer; +const char *tox_err_group_kick_peer_to_string(Tox_Err_Group_Kick_Peer value); /** * Kick a peer. * - * This function will remove a peer from the caller's peer list and send a packet to all - * group members requesting them to do the same. Note: This function will not trigger - * the `group_peer_exit` event for the caller. + * This function allows peers with the Founder or Moderator role to silently instruct + * all other peers in the group to remove a particular peer from their peer list. + * + * Note: This function will not trigger the `group_peer_exit` event for the caller. * * @param group_number The group number of the group the action is intended for. * @param peer_id The ID of the peer who will be kicked. * * @return true on success. */ -bool tox_group_mod_kick_peer(const Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, - Tox_Err_Group_Mod_Kick_Peer *error); +bool tox_group_kick_peer(const Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, + Tox_Err_Group_Kick_Peer *error); /** * Represents moderation events. These should be used with the `group_moderation` event. @@ -5702,7 +5543,6 @@ typedef enum Tox_Group_Mod_Event { const char *tox_group_mod_event_to_string(Tox_Group_Mod_Event value); - /** * @param group_number The group number of the group the event is intended for. * @param source_peer_id The ID of the peer who initiated the event. @@ -5710,9 +5550,8 @@ const char *tox_group_mod_event_to_string(Tox_Group_Mod_Event value); * @param mod_type The type of event. */ typedef void tox_group_moderation_cb( - Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number source_peer_id, Tox_Group_Peer_Number target_peer_id, - Tox_Group_Mod_Event mod_type, void *user_data); - + Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number source_peer_id, Tox_Group_Peer_Number target_peer_id, + Tox_Group_Mod_Event mod_type, void *user_data); /** * Set the callback for the `group_moderation` event. Pass NULL to unset. @@ -5731,7 +5570,7 @@ void tox_callback_group_moderation(Tox *tox, tox_group_moderation_cb *callback); /** @} */ #ifdef __cplusplus -} +} /* extern "C" */ #endif //!TOKSTYLE- @@ -5780,4 +5619,4 @@ typedef enum Tox_File_Kind TOX_FILE_KIND; #endif //!TOKSTYLE+ -#endif // C_TOXCORE_TOXCORE_TOX_H +#endif /* C_TOXCORE_TOXCORE_TOX_H */ diff --git a/toxcore/tox_api.c b/toxcore/tox_api.c index bf5b4a09..5904c803 100644 --- a/toxcore/tox_api.c +++ b/toxcore/tox_api.c @@ -136,53 +136,168 @@ uint32_t tox_dht_node_public_key_size(void) return TOX_DHT_NODE_PUBLIC_KEY_SIZE; } -//!TOKSTYLE- - -#define ACCESSORS(type, name) \ -type tox_options_get_##name(const struct Tox_Options *options) \ -{ \ - return options->name; \ -} \ -void tox_options_set_##name(struct Tox_Options *options, type name) \ -{ \ - options->name = name; \ +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; +} +const Tox_System *tox_options_get_operating_system(const Tox_Options *options) +{ + return options->operating_system; +} +void tox_options_set_operating_system(Tox_Options *options, const Tox_System *operating_system) +{ + options->operating_system = operating_system; +} +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; } -ACCESSORS(bool, ipv6_enabled) -ACCESSORS(bool, udp_enabled) -ACCESSORS(Tox_Proxy_Type, proxy_type) -ACCESSORS(const char *, proxy_host) -ACCESSORS(uint16_t, proxy_port) -ACCESSORS(uint16_t, start_port) -ACCESSORS(uint16_t, end_port) -ACCESSORS(uint16_t, tcp_port) -ACCESSORS(bool, hole_punching_enabled) -ACCESSORS(Tox_Savedata_Type, savedata_type) -ACCESSORS(size_t, savedata_length) -ACCESSORS(tox_log_cb *, log_callback) -ACCESSORS(void *, log_user_data) -ACCESSORS(bool, local_discovery_enabled) -ACCESSORS(bool, dht_announcements_enabled) -ACCESSORS(bool, experimental_thread_safety) -ACCESSORS(const Tox_System *, operating_system) - -//!TOKSTYLE+ - -const uint8_t *tox_options_get_savedata_data(const struct Tox_Options *options) +const uint8_t *tox_options_get_savedata_data(const Tox_Options *options) { return options->savedata_data; } -void tox_options_set_savedata_data(struct Tox_Options *options, const uint8_t *savedata_data, size_t length) +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(struct Tox_Options *options) +void tox_options_default(Tox_Options *options) { if (options != nullptr) { - const struct Tox_Options default_options = {0}; + const Tox_Options default_options = {false}; *options = default_options; tox_options_set_ipv6_enabled(options, true); tox_options_set_udp_enabled(options, true); @@ -191,12 +306,13 @@ void tox_options_default(struct Tox_Options *options) 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); } } -struct Tox_Options *tox_options_new(Tox_Err_Options_New *error) +Tox_Options *tox_options_new(Tox_Err_Options_New *error) { - struct Tox_Options *options = (struct Tox_Options *)calloc(1, sizeof(struct Tox_Options)); + Tox_Options *options = (Tox_Options *)calloc(1, sizeof(Tox_Options)); if (options != nullptr) { tox_options_default(options); @@ -208,7 +324,7 @@ struct Tox_Options *tox_options_new(Tox_Err_Options_New *error) return nullptr; } -void tox_options_free(struct Tox_Options *options) +void tox_options_free(Tox_Options *options) { free(options); } @@ -1137,17 +1253,17 @@ const char *tox_err_group_peer_query_to_string(Tox_Err_Group_Peer_Query value) return ""; } -const char *tox_err_group_state_queries_to_string(Tox_Err_Group_State_Queries value) +const char *tox_err_group_state_query_to_string(Tox_Err_Group_State_Query value) { switch (value) { - case TOX_ERR_GROUP_STATE_QUERIES_OK: - return "TOX_ERR_GROUP_STATE_QUERIES_OK"; + case TOX_ERR_GROUP_STATE_QUERY_OK: + return "TOX_ERR_GROUP_STATE_QUERY_OK"; - case TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND: - return "TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND"; + case TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND: + return "TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND"; } - return ""; + return ""; } const char *tox_err_group_topic_set_to_string(Tox_Err_Group_Topic_Set value) { @@ -1254,9 +1370,6 @@ const char *tox_err_group_send_custom_packet_to_string(Tox_Err_Group_Send_Custom case TOX_ERR_GROUP_SEND_CUSTOM_PACKET_EMPTY: return "TOX_ERR_GROUP_SEND_CUSTOM_PACKET_EMPTY"; - case TOX_ERR_GROUP_SEND_CUSTOM_PACKET_PERMISSIONS: - return "TOX_ERR_GROUP_SEND_CUSTOM_PACKET_PERMISSIONS"; - case TOX_ERR_GROUP_SEND_CUSTOM_PACKET_DISCONNECTED: return "TOX_ERR_GROUP_SEND_CUSTOM_PACKET_DISCONNECTED"; @@ -1284,9 +1397,6 @@ const char *tox_err_group_send_custom_private_packet_to_string(Tox_Err_Group_Sen case TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_PEER_NOT_FOUND: return "TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_PEER_NOT_FOUND"; - case TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_PERMISSIONS: - return "TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_PERMISSIONS"; - case TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_FAIL_SEND: return "TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_FAIL_SEND"; @@ -1389,131 +1499,131 @@ const char *tox_group_join_fail_to_string(Tox_Group_Join_Fail value) return ""; } -const char *tox_err_group_founder_set_password_to_string(Tox_Err_Group_Founder_Set_Password value) +const char *tox_err_group_set_password_to_string(Tox_Err_Group_Set_Password value) { switch (value) { - case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK: - return "TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK"; + case TOX_ERR_GROUP_SET_PASSWORD_OK: + return "TOX_ERR_GROUP_SET_PASSWORD_OK"; - case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_GROUP_NOT_FOUND: - return "TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_GROUP_NOT_FOUND"; + case TOX_ERR_GROUP_SET_PASSWORD_GROUP_NOT_FOUND: + return "TOX_ERR_GROUP_SET_PASSWORD_GROUP_NOT_FOUND"; - case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_PERMISSIONS: - return "TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_PERMISSIONS"; + case TOX_ERR_GROUP_SET_PASSWORD_PERMISSIONS: + return "TOX_ERR_GROUP_SET_PASSWORD_PERMISSIONS"; - case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_TOO_LONG: - return "TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_TOO_LONG"; + case TOX_ERR_GROUP_SET_PASSWORD_TOO_LONG: + return "TOX_ERR_GROUP_SET_PASSWORD_TOO_LONG"; - case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_FAIL_SEND: - return "TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_FAIL_SEND"; + case TOX_ERR_GROUP_SET_PASSWORD_FAIL_SEND: + return "TOX_ERR_GROUP_SET_PASSWORD_FAIL_SEND"; - case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_MALLOC: - return "TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_MALLOC"; + case TOX_ERR_GROUP_SET_PASSWORD_MALLOC: + return "TOX_ERR_GROUP_SET_PASSWORD_MALLOC"; - case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_DISCONNECTED: - return "TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_DISCONNECTED"; + case TOX_ERR_GROUP_SET_PASSWORD_DISCONNECTED: + return "TOX_ERR_GROUP_SET_PASSWORD_DISCONNECTED"; } - return ""; + return ""; } -const char *tox_err_group_founder_set_topic_lock_to_string(Tox_Err_Group_Founder_Set_Topic_Lock value) +const char *tox_err_group_set_topic_lock_to_string(Tox_Err_Group_Set_Topic_Lock value) { switch (value) { - case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK: - return "TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK"; + case TOX_ERR_GROUP_SET_TOPIC_LOCK_OK: + return "TOX_ERR_GROUP_SET_TOPIC_LOCK_OK"; - case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_GROUP_NOT_FOUND: - return "TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_GROUP_NOT_FOUND"; + case TOX_ERR_GROUP_SET_TOPIC_LOCK_GROUP_NOT_FOUND: + return "TOX_ERR_GROUP_SET_TOPIC_LOCK_GROUP_NOT_FOUND"; - case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_INVALID: - return "TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_INVALID"; + case TOX_ERR_GROUP_SET_TOPIC_LOCK_INVALID: + return "TOX_ERR_GROUP_SET_TOPIC_LOCK_INVALID"; - case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_PERMISSIONS: - return "TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_PERMISSIONS"; + case TOX_ERR_GROUP_SET_TOPIC_LOCK_PERMISSIONS: + return "TOX_ERR_GROUP_SET_TOPIC_LOCK_PERMISSIONS"; - case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SET: - return "TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SET"; + case TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SET: + return "TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SET"; - case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SEND: - return "TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SEND"; + case TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SEND: + return "TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SEND"; - case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_DISCONNECTED: - return "TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_DISCONNECTED"; + case TOX_ERR_GROUP_SET_TOPIC_LOCK_DISCONNECTED: + return "TOX_ERR_GROUP_SET_TOPIC_LOCK_DISCONNECTED"; } - return ""; + return ""; } -const char *tox_err_group_founder_set_voice_state_to_string(Tox_Err_Group_Founder_Set_Voice_State value) +const char *tox_err_group_set_voice_state_to_string(Tox_Err_Group_Set_Voice_State value) { switch (value) { - case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK: - return "TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK"; + case TOX_ERR_GROUP_SET_VOICE_STATE_OK: + return "TOX_ERR_GROUP_SET_VOICE_STATE_OK"; - case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_GROUP_NOT_FOUND: - return "TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_GROUP_NOT_FOUND"; + case TOX_ERR_GROUP_SET_VOICE_STATE_GROUP_NOT_FOUND: + return "TOX_ERR_GROUP_SET_VOICE_STATE_GROUP_NOT_FOUND"; - case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_PERMISSIONS: - return "TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_PERMISSIONS"; + case TOX_ERR_GROUP_SET_VOICE_STATE_PERMISSIONS: + return "TOX_ERR_GROUP_SET_VOICE_STATE_PERMISSIONS"; - case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SET: - return "TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SET"; + case TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SET: + return "TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SET"; - case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SEND: - return "TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SEND"; + case TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SEND: + return "TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SEND"; - case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_DISCONNECTED: - return "TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_DISCONNECTED"; + case TOX_ERR_GROUP_SET_VOICE_STATE_DISCONNECTED: + return "TOX_ERR_GROUP_SET_VOICE_STATE_DISCONNECTED"; } - return ""; + return ""; } -const char *tox_err_group_founder_set_privacy_state_to_string(Tox_Err_Group_Founder_Set_Privacy_State value) +const char *tox_err_group_set_privacy_state_to_string(Tox_Err_Group_Set_Privacy_State value) { switch (value) { - case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK: - return "TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK"; + case TOX_ERR_GROUP_SET_PRIVACY_STATE_OK: + return "TOX_ERR_GROUP_SET_PRIVACY_STATE_OK"; - case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_GROUP_NOT_FOUND: - return "TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_GROUP_NOT_FOUND"; + case TOX_ERR_GROUP_SET_PRIVACY_STATE_GROUP_NOT_FOUND: + return "TOX_ERR_GROUP_SET_PRIVACY_STATE_GROUP_NOT_FOUND"; - case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_PERMISSIONS: - return "TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_PERMISSIONS"; + case TOX_ERR_GROUP_SET_PRIVACY_STATE_PERMISSIONS: + return "TOX_ERR_GROUP_SET_PRIVACY_STATE_PERMISSIONS"; - case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SET: - return "TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SET"; + case TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SET: + return "TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SET"; - case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SEND: - return "TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SEND"; + case TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SEND: + return "TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SEND"; - case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_DISCONNECTED: - return "TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_DISCONNECTED"; + case TOX_ERR_GROUP_SET_PRIVACY_STATE_DISCONNECTED: + return "TOX_ERR_GROUP_SET_PRIVACY_STATE_DISCONNECTED"; } - return ""; + return ""; } -const char *tox_err_group_founder_set_peer_limit_to_string(Tox_Err_Group_Founder_Set_Peer_Limit value) +const char *tox_err_group_set_peer_limit_to_string(Tox_Err_Group_Set_Peer_Limit value) { switch (value) { - case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK: - return "TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK"; + case TOX_ERR_GROUP_SET_PEER_LIMIT_OK: + return "TOX_ERR_GROUP_SET_PEER_LIMIT_OK"; - case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_GROUP_NOT_FOUND: - return "TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_GROUP_NOT_FOUND"; + case TOX_ERR_GROUP_SET_PEER_LIMIT_GROUP_NOT_FOUND: + return "TOX_ERR_GROUP_SET_PEER_LIMIT_GROUP_NOT_FOUND"; - case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_PERMISSIONS: - return "TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_PERMISSIONS"; + case TOX_ERR_GROUP_SET_PEER_LIMIT_PERMISSIONS: + return "TOX_ERR_GROUP_SET_PEER_LIMIT_PERMISSIONS"; - case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SET: - return "TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SET"; + case TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SET: + return "TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SET"; - case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SEND: - return "TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SEND"; + case TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SEND: + return "TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SEND"; - case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_DISCONNECTED: - return "TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_DISCONNECTED"; + case TOX_ERR_GROUP_SET_PEER_LIMIT_DISCONNECTED: + return "TOX_ERR_GROUP_SET_PEER_LIMIT_DISCONNECTED"; } - return ""; + return ""; } const char *tox_err_group_set_ignore_to_string(Tox_Err_Group_Set_Ignore value) { @@ -1533,59 +1643,59 @@ const char *tox_err_group_set_ignore_to_string(Tox_Err_Group_Set_Ignore value) return ""; } -const char *tox_err_group_mod_set_role_to_string(Tox_Err_Group_Mod_Set_Role value) +const char *tox_err_group_set_role_to_string(Tox_Err_Group_Set_Role value) { switch (value) { - case TOX_ERR_GROUP_MOD_SET_ROLE_OK: - return "TOX_ERR_GROUP_MOD_SET_ROLE_OK"; + case TOX_ERR_GROUP_SET_ROLE_OK: + return "TOX_ERR_GROUP_SET_ROLE_OK"; - case TOX_ERR_GROUP_MOD_SET_ROLE_GROUP_NOT_FOUND: - return "TOX_ERR_GROUP_MOD_SET_ROLE_GROUP_NOT_FOUND"; + case TOX_ERR_GROUP_SET_ROLE_GROUP_NOT_FOUND: + return "TOX_ERR_GROUP_SET_ROLE_GROUP_NOT_FOUND"; - case TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND: - return "TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND"; + case TOX_ERR_GROUP_SET_ROLE_PEER_NOT_FOUND: + return "TOX_ERR_GROUP_SET_ROLE_PEER_NOT_FOUND"; - case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: - return "TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS"; + case TOX_ERR_GROUP_SET_ROLE_PERMISSIONS: + return "TOX_ERR_GROUP_SET_ROLE_PERMISSIONS"; - case TOX_ERR_GROUP_MOD_SET_ROLE_ASSIGNMENT: - return "TOX_ERR_GROUP_MOD_SET_ROLE_ASSIGNMENT"; + case TOX_ERR_GROUP_SET_ROLE_ASSIGNMENT: + return "TOX_ERR_GROUP_SET_ROLE_ASSIGNMENT"; - case TOX_ERR_GROUP_MOD_SET_ROLE_FAIL_ACTION: - return "TOX_ERR_GROUP_MOD_SET_ROLE_FAIL_ACTION"; + case TOX_ERR_GROUP_SET_ROLE_FAIL_ACTION: + return "TOX_ERR_GROUP_SET_ROLE_FAIL_ACTION"; - case TOX_ERR_GROUP_MOD_SET_ROLE_SELF: - return "TOX_ERR_GROUP_MOD_SET_ROLE_SELF"; + case TOX_ERR_GROUP_SET_ROLE_SELF: + return "TOX_ERR_GROUP_SET_ROLE_SELF"; } - return ""; + return ""; } -const char *tox_err_group_mod_kick_peer_to_string(Tox_Err_Group_Mod_Kick_Peer value) +const char *tox_err_group_kick_peer_to_string(Tox_Err_Group_Kick_Peer value) { switch (value) { - case TOX_ERR_GROUP_MOD_KICK_PEER_OK: - return "TOX_ERR_GROUP_MOD_KICK_PEER_OK"; + case TOX_ERR_GROUP_KICK_PEER_OK: + return "TOX_ERR_GROUP_KICK_PEER_OK"; - case TOX_ERR_GROUP_MOD_KICK_PEER_GROUP_NOT_FOUND: - return "TOX_ERR_GROUP_MOD_KICK_PEER_GROUP_NOT_FOUND"; + case TOX_ERR_GROUP_KICK_PEER_GROUP_NOT_FOUND: + return "TOX_ERR_GROUP_KICK_PEER_GROUP_NOT_FOUND"; - case TOX_ERR_GROUP_MOD_KICK_PEER_PEER_NOT_FOUND: - return "TOX_ERR_GROUP_MOD_KICK_PEER_PEER_NOT_FOUND"; + case TOX_ERR_GROUP_KICK_PEER_PEER_NOT_FOUND: + return "TOX_ERR_GROUP_KICK_PEER_PEER_NOT_FOUND"; - case TOX_ERR_GROUP_MOD_KICK_PEER_PERMISSIONS: - return "TOX_ERR_GROUP_MOD_KICK_PEER_PERMISSIONS"; + case TOX_ERR_GROUP_KICK_PEER_PERMISSIONS: + return "TOX_ERR_GROUP_KICK_PEER_PERMISSIONS"; - case TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_ACTION: - return "TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_ACTION"; + case TOX_ERR_GROUP_KICK_PEER_FAIL_ACTION: + return "TOX_ERR_GROUP_KICK_PEER_FAIL_ACTION"; - case TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_SEND: - return "TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_SEND"; + case TOX_ERR_GROUP_KICK_PEER_FAIL_SEND: + return "TOX_ERR_GROUP_KICK_PEER_FAIL_SEND"; - case TOX_ERR_GROUP_MOD_KICK_PEER_SELF: - return "TOX_ERR_GROUP_MOD_KICK_PEER_SELF"; + case TOX_ERR_GROUP_KICK_PEER_SELF: + return "TOX_ERR_GROUP_KICK_PEER_SELF"; } - return ""; + return ""; } const char *tox_group_mod_event_to_string(Tox_Group_Mod_Event value) { diff --git a/toxcore/tox_dispatch.c b/toxcore/tox_dispatch.c index bbf09493..5383925b 100644 --- a/toxcore/tox_dispatch.c +++ b/toxcore/tox_dispatch.c @@ -6,6 +6,7 @@ #include +#include "attributes.h" #include "ccompat.h" #include "events/events_alloc.h" // IWYU pragma: keep #include "tox.h" @@ -52,6 +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_Dispatch *tox_dispatch_new(Tox_Err_Dispatch_New *error) @@ -277,14 +279,19 @@ 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) +{ + dispatch->dht_get_nodes_response_callback = callback; +} -non_null(1, 2) nullable(3, 4) -static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Event *event, Tox *tox, void *user_data) +non_null(1, 2) nullable(3) +static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Event *event, void *user_data) { switch (event->type) { case TOX_EVENT_CONFERENCE_CONNECTED: { if (dispatch->conference_connected_callback != nullptr) { - dispatch->conference_connected_callback(tox, event->data.conference_connected, user_data); + dispatch->conference_connected_callback(event->data.conference_connected, user_data); } break; @@ -292,7 +299,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_CONFERENCE_INVITE: { if (dispatch->conference_invite_callback != nullptr) { - dispatch->conference_invite_callback(tox, event->data.conference_invite, user_data); + dispatch->conference_invite_callback(event->data.conference_invite, user_data); } break; @@ -300,7 +307,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_CONFERENCE_MESSAGE: { if (dispatch->conference_message_callback != nullptr) { - dispatch->conference_message_callback(tox, event->data.conference_message, user_data); + dispatch->conference_message_callback(event->data.conference_message, user_data); } break; @@ -308,7 +315,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_CONFERENCE_PEER_LIST_CHANGED: { if (dispatch->conference_peer_list_changed_callback != nullptr) { - dispatch->conference_peer_list_changed_callback(tox, event->data.conference_peer_list_changed, user_data); + dispatch->conference_peer_list_changed_callback(event->data.conference_peer_list_changed, user_data); } break; @@ -316,7 +323,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_CONFERENCE_PEER_NAME: { if (dispatch->conference_peer_name_callback != nullptr) { - dispatch->conference_peer_name_callback(tox, event->data.conference_peer_name, user_data); + dispatch->conference_peer_name_callback(event->data.conference_peer_name, user_data); } break; @@ -324,7 +331,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_CONFERENCE_TITLE: { if (dispatch->conference_title_callback != nullptr) { - dispatch->conference_title_callback(tox, event->data.conference_title, user_data); + dispatch->conference_title_callback(event->data.conference_title, user_data); } break; @@ -332,7 +339,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_FILE_CHUNK_REQUEST: { if (dispatch->file_chunk_request_callback != nullptr) { - dispatch->file_chunk_request_callback(tox, event->data.file_chunk_request, user_data); + dispatch->file_chunk_request_callback(event->data.file_chunk_request, user_data); } break; @@ -340,7 +347,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_FILE_RECV_CHUNK: { if (dispatch->file_recv_chunk_callback != nullptr) { - dispatch->file_recv_chunk_callback(tox, event->data.file_recv_chunk, user_data); + dispatch->file_recv_chunk_callback(event->data.file_recv_chunk, user_data); } break; @@ -348,7 +355,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_FILE_RECV_CONTROL: { if (dispatch->file_recv_control_callback != nullptr) { - dispatch->file_recv_control_callback(tox, event->data.file_recv_control, user_data); + dispatch->file_recv_control_callback(event->data.file_recv_control, user_data); } break; @@ -356,7 +363,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_FILE_RECV: { if (dispatch->file_recv_callback != nullptr) { - dispatch->file_recv_callback(tox, event->data.file_recv, user_data); + dispatch->file_recv_callback(event->data.file_recv, user_data); } break; @@ -364,7 +371,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_FRIEND_CONNECTION_STATUS: { if (dispatch->friend_connection_status_callback != nullptr) { - dispatch->friend_connection_status_callback(tox, event->data.friend_connection_status, user_data); + dispatch->friend_connection_status_callback(event->data.friend_connection_status, user_data); } break; @@ -372,7 +379,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_FRIEND_LOSSLESS_PACKET: { if (dispatch->friend_lossless_packet_callback != nullptr) { - dispatch->friend_lossless_packet_callback(tox, event->data.friend_lossless_packet, user_data); + dispatch->friend_lossless_packet_callback(event->data.friend_lossless_packet, user_data); } break; @@ -380,7 +387,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_FRIEND_LOSSY_PACKET: { if (dispatch->friend_lossy_packet_callback != nullptr) { - dispatch->friend_lossy_packet_callback(tox, event->data.friend_lossy_packet, user_data); + dispatch->friend_lossy_packet_callback(event->data.friend_lossy_packet, user_data); } break; @@ -388,7 +395,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_FRIEND_MESSAGE: { if (dispatch->friend_message_callback != nullptr) { - dispatch->friend_message_callback(tox, event->data.friend_message, user_data); + dispatch->friend_message_callback(event->data.friend_message, user_data); } break; @@ -396,7 +403,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_FRIEND_NAME: { if (dispatch->friend_name_callback != nullptr) { - dispatch->friend_name_callback(tox, event->data.friend_name, user_data); + dispatch->friend_name_callback(event->data.friend_name, user_data); } break; @@ -404,7 +411,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_FRIEND_READ_RECEIPT: { if (dispatch->friend_read_receipt_callback != nullptr) { - dispatch->friend_read_receipt_callback(tox, event->data.friend_read_receipt, user_data); + dispatch->friend_read_receipt_callback(event->data.friend_read_receipt, user_data); } break; @@ -412,7 +419,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_FRIEND_REQUEST: { if (dispatch->friend_request_callback != nullptr) { - dispatch->friend_request_callback(tox, event->data.friend_request, user_data); + dispatch->friend_request_callback(event->data.friend_request, user_data); } break; @@ -420,7 +427,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_FRIEND_STATUS: { if (dispatch->friend_status_callback != nullptr) { - dispatch->friend_status_callback(tox, event->data.friend_status, user_data); + dispatch->friend_status_callback(event->data.friend_status, user_data); } break; @@ -428,7 +435,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_FRIEND_STATUS_MESSAGE: { if (dispatch->friend_status_message_callback != nullptr) { - dispatch->friend_status_message_callback(tox, event->data.friend_status_message, user_data); + dispatch->friend_status_message_callback(event->data.friend_status_message, user_data); } break; @@ -436,7 +443,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_FRIEND_TYPING: { if (dispatch->friend_typing_callback != nullptr) { - dispatch->friend_typing_callback(tox, event->data.friend_typing, user_data); + dispatch->friend_typing_callback(event->data.friend_typing, user_data); } break; @@ -444,7 +451,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_SELF_CONNECTION_STATUS: { if (dispatch->self_connection_status_callback != nullptr) { - dispatch->self_connection_status_callback(tox, event->data.self_connection_status, user_data); + dispatch->self_connection_status_callback(event->data.self_connection_status, user_data); } break; @@ -452,7 +459,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_PEER_NAME: { if (dispatch->group_peer_name_callback != nullptr) { - dispatch->group_peer_name_callback(tox, event->data.group_peer_name, user_data); + dispatch->group_peer_name_callback(event->data.group_peer_name, user_data); } break; @@ -460,7 +467,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_PEER_STATUS: { if (dispatch->group_peer_status_callback != nullptr) { - dispatch->group_peer_status_callback(tox, event->data.group_peer_status, user_data); + dispatch->group_peer_status_callback(event->data.group_peer_status, user_data); } break; @@ -468,7 +475,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_TOPIC: { if (dispatch->group_topic_callback != nullptr) { - dispatch->group_topic_callback(tox, event->data.group_topic, user_data); + dispatch->group_topic_callback(event->data.group_topic, user_data); } break; @@ -476,7 +483,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_PRIVACY_STATE: { if (dispatch->group_privacy_state_callback != nullptr) { - dispatch->group_privacy_state_callback(tox, event->data.group_privacy_state, user_data); + dispatch->group_privacy_state_callback(event->data.group_privacy_state, user_data); } break; @@ -484,7 +491,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_VOICE_STATE: { if (dispatch->group_voice_state_callback != nullptr) { - dispatch->group_voice_state_callback(tox, event->data.group_voice_state, user_data); + dispatch->group_voice_state_callback(event->data.group_voice_state, user_data); } break; @@ -492,7 +499,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_TOPIC_LOCK: { if (dispatch->group_topic_lock_callback != nullptr) { - dispatch->group_topic_lock_callback(tox, event->data.group_topic_lock, user_data); + dispatch->group_topic_lock_callback(event->data.group_topic_lock, user_data); } break; @@ -500,7 +507,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_PEER_LIMIT: { if (dispatch->group_peer_limit_callback != nullptr) { - dispatch->group_peer_limit_callback(tox, event->data.group_peer_limit, user_data); + dispatch->group_peer_limit_callback(event->data.group_peer_limit, user_data); } break; @@ -508,7 +515,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_PASSWORD: { if (dispatch->group_password_callback != nullptr) { - dispatch->group_password_callback(tox, event->data.group_password, user_data); + dispatch->group_password_callback(event->data.group_password, user_data); } break; @@ -516,7 +523,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_MESSAGE: { if (dispatch->group_message_callback != nullptr) { - dispatch->group_message_callback(tox, event->data.group_message, user_data); + dispatch->group_message_callback(event->data.group_message, user_data); } break; @@ -524,7 +531,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_PRIVATE_MESSAGE: { if (dispatch->group_private_message_callback != nullptr) { - dispatch->group_private_message_callback(tox, event->data.group_private_message, user_data); + dispatch->group_private_message_callback(event->data.group_private_message, user_data); } break; @@ -532,7 +539,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_CUSTOM_PACKET: { if (dispatch->group_custom_packet_callback != nullptr) { - dispatch->group_custom_packet_callback(tox, event->data.group_custom_packet, user_data); + dispatch->group_custom_packet_callback(event->data.group_custom_packet, user_data); } break; @@ -540,7 +547,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET: { if (dispatch->group_custom_private_packet_callback != nullptr) { - dispatch->group_custom_private_packet_callback(tox, event->data.group_custom_private_packet, user_data); + dispatch->group_custom_private_packet_callback(event->data.group_custom_private_packet, user_data); } break; @@ -548,7 +555,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_INVITE: { if (dispatch->group_invite_callback != nullptr) { - dispatch->group_invite_callback(tox, event->data.group_invite, user_data); + dispatch->group_invite_callback(event->data.group_invite, user_data); } break; @@ -556,7 +563,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_PEER_JOIN: { if (dispatch->group_peer_join_callback != nullptr) { - dispatch->group_peer_join_callback(tox, event->data.group_peer_join, user_data); + dispatch->group_peer_join_callback(event->data.group_peer_join, user_data); } break; @@ -564,7 +571,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_PEER_EXIT: { if (dispatch->group_peer_exit_callback != nullptr) { - dispatch->group_peer_exit_callback(tox, event->data.group_peer_exit, user_data); + dispatch->group_peer_exit_callback(event->data.group_peer_exit, user_data); } break; @@ -572,7 +579,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_SELF_JOIN: { if (dispatch->group_self_join_callback != nullptr) { - dispatch->group_self_join_callback(tox, event->data.group_self_join, user_data); + dispatch->group_self_join_callback(event->data.group_self_join, user_data); } break; @@ -580,7 +587,7 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_JOIN_FAIL: { if (dispatch->group_join_fail_callback != nullptr) { - dispatch->group_join_fail_callback(tox, event->data.group_join_fail, user_data); + dispatch->group_join_fail_callback(event->data.group_join_fail, user_data); } break; @@ -588,7 +595,15 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev case TOX_EVENT_GROUP_MODERATION: { if (dispatch->group_moderation_callback != nullptr) { - dispatch->group_moderation_callback(tox, event->data.group_moderation, user_data); + dispatch->group_moderation_callback(event->data.group_moderation, user_data); + } + + break; + } + + 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); } break; @@ -600,11 +615,11 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev } } -void tox_dispatch_invoke(const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +void tox_dispatch_invoke(const Tox_Dispatch *dispatch, const Tox_Events *events, void *user_data) { const uint32_t size = tox_events_get_size(events); for (uint32_t i = 0; i < size; ++i) { const Tox_Event *event = &events->events[i]; - tox_dispatch_invoke_event(dispatch, event, tox, user_data); + tox_dispatch_invoke_event(dispatch, event, user_data); } } diff --git a/toxcore/tox_dispatch.h b/toxcore/tox_dispatch.h index bf2df139..2588065a 100644 --- a/toxcore/tox_dispatch.h +++ b/toxcore/tox_dispatch.h @@ -5,6 +5,7 @@ #ifndef C_TOXCORE_TOXCORE_TOX_DISPATCH_H #define C_TOXCORE_TOXCORE_TOX_DISPATCH_H +#include "tox.h" #include "tox_events.h" #ifdef __cplusplus @@ -46,89 +47,90 @@ void tox_dispatch_free(Tox_Dispatch *dispatch); * * @param dispatch The events dispatch table. * @param events The events object received from @ref tox_events_iterate. - * @param tox The tox object to pass down to the callbacks. * @param user_data User data pointer to pass down to the callbacks. */ -void tox_dispatch_invoke(const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data); +void tox_dispatch_invoke(const Tox_Dispatch *dispatch, const Tox_Events *events, void *user_data); typedef void tox_events_conference_connected_cb( - Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data); + const Tox_Event_Conference_Connected *event, void *user_data); typedef void tox_events_conference_invite_cb( - Tox *tox, const Tox_Event_Conference_Invite *event, void *user_data); + const Tox_Event_Conference_Invite *event, void *user_data); typedef void tox_events_conference_message_cb( - Tox *tox, const Tox_Event_Conference_Message *event, void *user_data); + const Tox_Event_Conference_Message *event, void *user_data); typedef void tox_events_conference_peer_list_changed_cb( - Tox *tox, const Tox_Event_Conference_Peer_List_Changed *event, void *user_data); + const Tox_Event_Conference_Peer_List_Changed *event, void *user_data); typedef void tox_events_conference_peer_name_cb( - Tox *tox, const Tox_Event_Conference_Peer_Name *event, void *user_data); + const Tox_Event_Conference_Peer_Name *event, void *user_data); typedef void tox_events_conference_title_cb( - Tox *tox, const Tox_Event_Conference_Title *event, void *user_data); + const Tox_Event_Conference_Title *event, void *user_data); typedef void tox_events_file_chunk_request_cb( - Tox *tox, const Tox_Event_File_Chunk_Request *event, void *user_data); + const Tox_Event_File_Chunk_Request *event, void *user_data); typedef void tox_events_file_recv_cb( - Tox *tox, const Tox_Event_File_Recv *event, void *user_data); + const Tox_Event_File_Recv *event, void *user_data); typedef void tox_events_file_recv_chunk_cb( - Tox *tox, const Tox_Event_File_Recv_Chunk *event, void *user_data); + const Tox_Event_File_Recv_Chunk *event, void *user_data); typedef void tox_events_file_recv_control_cb( - Tox *tox, const Tox_Event_File_Recv_Control *event, void *user_data); + const Tox_Event_File_Recv_Control *event, void *user_data); typedef void tox_events_friend_connection_status_cb( - Tox *tox, const Tox_Event_Friend_Connection_Status *event, void *user_data); + const Tox_Event_Friend_Connection_Status *event, void *user_data); typedef void tox_events_friend_lossless_packet_cb( - Tox *tox, const Tox_Event_Friend_Lossless_Packet *event, void *user_data); + const Tox_Event_Friend_Lossless_Packet *event, void *user_data); typedef void tox_events_friend_lossy_packet_cb( - Tox *tox, const Tox_Event_Friend_Lossy_Packet *event, void *user_data); + const Tox_Event_Friend_Lossy_Packet *event, void *user_data); typedef void tox_events_friend_message_cb( - Tox *tox, const Tox_Event_Friend_Message *event, void *user_data); + const Tox_Event_Friend_Message *event, void *user_data); typedef void tox_events_friend_name_cb( - Tox *tox, const Tox_Event_Friend_Name *event, void *user_data); + const Tox_Event_Friend_Name *event, void *user_data); typedef void tox_events_friend_read_receipt_cb( - Tox *tox, const Tox_Event_Friend_Read_Receipt *event, void *user_data); + const Tox_Event_Friend_Read_Receipt *event, void *user_data); typedef void tox_events_friend_request_cb( - Tox *tox, const Tox_Event_Friend_Request *event, void *user_data); + const Tox_Event_Friend_Request *event, void *user_data); typedef void tox_events_friend_status_cb( - Tox *tox, const Tox_Event_Friend_Status *event, void *user_data); + const Tox_Event_Friend_Status *event, void *user_data); typedef void tox_events_friend_status_message_cb( - Tox *tox, const Tox_Event_Friend_Status_Message *event, void *user_data); + const Tox_Event_Friend_Status_Message *event, void *user_data); typedef void tox_events_friend_typing_cb( - Tox *tox, const Tox_Event_Friend_Typing *event, void *user_data); + const Tox_Event_Friend_Typing *event, void *user_data); typedef void tox_events_self_connection_status_cb( - Tox *tox, const Tox_Event_Self_Connection_Status *event, void *user_data); + const Tox_Event_Self_Connection_Status *event, void *user_data); typedef void tox_events_group_peer_name_cb( - Tox *tox, const Tox_Event_Group_Peer_Name *event, void *user_data); + const Tox_Event_Group_Peer_Name *event, void *user_data); typedef void tox_events_group_peer_status_cb( - Tox *tox, const Tox_Event_Group_Peer_Status *event, void *user_data); + const Tox_Event_Group_Peer_Status *event, void *user_data); typedef void tox_events_group_topic_cb( - Tox *tox, const Tox_Event_Group_Topic *event, void *user_data); + const Tox_Event_Group_Topic *event, void *user_data); typedef void tox_events_group_privacy_state_cb( - Tox *tox, const Tox_Event_Group_Privacy_State *event, void *user_data); + const Tox_Event_Group_Privacy_State *event, void *user_data); typedef void tox_events_group_voice_state_cb( - Tox *tox, const Tox_Event_Group_Voice_State *event, void *user_data); + const Tox_Event_Group_Voice_State *event, void *user_data); typedef void tox_events_group_topic_lock_cb( - Tox *tox, const Tox_Event_Group_Topic_Lock *event, void *user_data); + const Tox_Event_Group_Topic_Lock *event, void *user_data); typedef void tox_events_group_peer_limit_cb( - Tox *tox, const Tox_Event_Group_Peer_Limit *event, void *user_data); + const Tox_Event_Group_Peer_Limit *event, void *user_data); typedef void tox_events_group_password_cb( - Tox *tox, const Tox_Event_Group_Password *event, void *user_data); + const Tox_Event_Group_Password *event, void *user_data); typedef void tox_events_group_message_cb( - Tox *tox, const Tox_Event_Group_Message *event, void *user_data); + const Tox_Event_Group_Message *event, void *user_data); typedef void tox_events_group_private_message_cb( - Tox *tox, const Tox_Event_Group_Private_Message *event, void *user_data); + const Tox_Event_Group_Private_Message *event, void *user_data); typedef void tox_events_group_custom_packet_cb( - Tox *tox, const Tox_Event_Group_Custom_Packet *event, void *user_data); + const Tox_Event_Group_Custom_Packet *event, void *user_data); typedef void tox_events_group_custom_private_packet_cb( - Tox *tox, const Tox_Event_Group_Custom_Private_Packet *event, void *user_data); + const Tox_Event_Group_Custom_Private_Packet *event, void *user_data); typedef void tox_events_group_invite_cb( - Tox *tox, const Tox_Event_Group_Invite *event, void *user_data); + const Tox_Event_Group_Invite *event, void *user_data); typedef void tox_events_group_peer_join_cb( - Tox *tox, const Tox_Event_Group_Peer_Join *event, void *user_data); + const Tox_Event_Group_Peer_Join *event, void *user_data); typedef void tox_events_group_peer_exit_cb( - Tox *tox, const Tox_Event_Group_Peer_Exit *event, void *user_data); + const Tox_Event_Group_Peer_Exit *event, void *user_data); typedef void tox_events_group_self_join_cb( - Tox *tox, const Tox_Event_Group_Self_Join *event, void *user_data); + const Tox_Event_Group_Self_Join *event, void *user_data); typedef void tox_events_group_join_fail_cb( - Tox *tox, const Tox_Event_Group_Join_Fail *event, void *user_data); + const Tox_Event_Group_Join_Fail *event, void *user_data); typedef void tox_events_group_moderation_cb( - Tox *tox, const Tox_Event_Group_Moderation *event, void *user_data); + 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); void tox_events_callback_conference_connected( Tox_Dispatch *dispatch, tox_events_conference_connected_cb *callback); @@ -208,9 +210,11 @@ 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); #ifdef __cplusplus -} +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_TOX_DISPATCH_H +#endif /* C_TOXCORE_TOXCORE_TOX_DISPATCH_H */ diff --git a/toxcore/tox_event.c b/toxcore/tox_event.c index 9a4ee81a..b0a65503 100644 --- a/toxcore/tox_event.c +++ b/toxcore/tox_event.c @@ -6,6 +6,7 @@ #include +#include "attributes.h" #include "bin_pack.h" #include "bin_unpack.h" #include "ccompat.h" @@ -132,6 +133,9 @@ const char *tox_event_type_to_string(Tox_Event_Type type) case TOX_EVENT_GROUP_MODERATION: return "TOX_EVENT_GROUP_MODERATION"; + case TOX_EVENT_DHT_GET_NODES_RESPONSE: + return "TOX_EVENT_DHT_GET_NODES_RESPONSE"; + case TOX_EVENT_INVALID: return "TOX_EVENT_INVALID"; } @@ -346,6 +350,11 @@ bool tox_event_construct(Tox_Event *event, Tox_Event_Type type, const Memory *me break; } + case TOX_EVENT_DHT_GET_NODES_RESPONSE: { + event->data.dht_get_nodes_response = tox_event_dht_get_nodes_response_new(mem); + break; + } + case TOX_EVENT_INVALID: { return false; } @@ -556,6 +565,11 @@ void tox_event_destruct(Tox_Event *event, const Memory *mem) break; } + case TOX_EVENT_DHT_GET_NODES_RESPONSE: { + tox_event_dht_get_nodes_response_free(event->data.dht_get_nodes_response, mem); + break; + } + case TOX_EVENT_INVALID: { break; } @@ -691,6 +705,9 @@ static bool tox_event_data_pack(Tox_Event_Type type, const Tox_Event_Data *data, case TOX_EVENT_GROUP_MODERATION: 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); + case TOX_EVENT_INVALID: return false; } @@ -906,6 +923,11 @@ static bool tox_event_type_from_int(uint32_t value, Tox_Event_Type *out) return true; } + case TOX_EVENT_DHT_GET_NODES_RESPONSE: { + *out = TOX_EVENT_DHT_GET_NODES_RESPONSE; + return true; + } + case TOX_EVENT_INVALID: { *out = TOX_EVENT_INVALID; return true; @@ -919,148 +941,136 @@ static bool tox_event_type_from_int(uint32_t value, Tox_Event_Type *out) } non_null() -static bool tox_event_type_unpack(Bin_Unpack *bu, Tox_Event_Type *val) +static bool tox_event_type_unpack(Tox_Event_Type *val, Bin_Unpack *bu) { uint32_t u32; return bin_unpack_u32(bu, &u32) && tox_event_type_from_int(u32, val); } -bool tox_event_unpack_into(Tox_Event *event, Bin_Unpack *bu, const Memory *mem) +non_null() +static bool tox_event_data_unpack(Tox_Event_Type type, Tox_Event_Data *data, Bin_Unpack *bu, const Memory *mem) { - uint32_t size; - if (!bin_unpack_array(bu, &size)) { - return false; - } - - if (size != 2) { - return false; - } - - Tox_Event_Type type; - if (!tox_event_type_unpack(bu, &type)) { - return false; - } - - event->type = type; - switch (type) { case TOX_EVENT_CONFERENCE_CONNECTED: - return tox_event_conference_connected_unpack(&event->data.conference_connected, bu, mem); + return tox_event_conference_connected_unpack(&data->conference_connected, bu, mem); case TOX_EVENT_CONFERENCE_INVITE: - return tox_event_conference_invite_unpack(&event->data.conference_invite, bu, mem); + return tox_event_conference_invite_unpack(&data->conference_invite, bu, mem); case TOX_EVENT_CONFERENCE_MESSAGE: - return tox_event_conference_message_unpack(&event->data.conference_message, bu, mem); + return tox_event_conference_message_unpack(&data->conference_message, bu, mem); case TOX_EVENT_CONFERENCE_PEER_LIST_CHANGED: - return tox_event_conference_peer_list_changed_unpack(&event->data.conference_peer_list_changed, bu, mem); + return tox_event_conference_peer_list_changed_unpack(&data->conference_peer_list_changed, bu, mem); case TOX_EVENT_CONFERENCE_PEER_NAME: - return tox_event_conference_peer_name_unpack(&event->data.conference_peer_name, bu, mem); + return tox_event_conference_peer_name_unpack(&data->conference_peer_name, bu, mem); case TOX_EVENT_CONFERENCE_TITLE: - return tox_event_conference_title_unpack(&event->data.conference_title, bu, mem); + return tox_event_conference_title_unpack(&data->conference_title, bu, mem); case TOX_EVENT_FILE_CHUNK_REQUEST: - return tox_event_file_chunk_request_unpack(&event->data.file_chunk_request, bu, mem); + return tox_event_file_chunk_request_unpack(&data->file_chunk_request, bu, mem); case TOX_EVENT_FILE_RECV_CHUNK: - return tox_event_file_recv_chunk_unpack(&event->data.file_recv_chunk, bu, mem); + return tox_event_file_recv_chunk_unpack(&data->file_recv_chunk, bu, mem); case TOX_EVENT_FILE_RECV_CONTROL: - return tox_event_file_recv_control_unpack(&event->data.file_recv_control, bu, mem); + return tox_event_file_recv_control_unpack(&data->file_recv_control, bu, mem); case TOX_EVENT_FILE_RECV: - return tox_event_file_recv_unpack(&event->data.file_recv, bu, mem); + return tox_event_file_recv_unpack(&data->file_recv, bu, mem); case TOX_EVENT_FRIEND_CONNECTION_STATUS: - return tox_event_friend_connection_status_unpack(&event->data.friend_connection_status, bu, mem); + return tox_event_friend_connection_status_unpack(&data->friend_connection_status, bu, mem); case TOX_EVENT_FRIEND_LOSSLESS_PACKET: - return tox_event_friend_lossless_packet_unpack(&event->data.friend_lossless_packet, bu, mem); + return tox_event_friend_lossless_packet_unpack(&data->friend_lossless_packet, bu, mem); case TOX_EVENT_FRIEND_LOSSY_PACKET: - return tox_event_friend_lossy_packet_unpack(&event->data.friend_lossy_packet, bu, mem); + return tox_event_friend_lossy_packet_unpack(&data->friend_lossy_packet, bu, mem); case TOX_EVENT_FRIEND_MESSAGE: - return tox_event_friend_message_unpack(&event->data.friend_message, bu, mem); + return tox_event_friend_message_unpack(&data->friend_message, bu, mem); case TOX_EVENT_FRIEND_NAME: - return tox_event_friend_name_unpack(&event->data.friend_name, bu, mem); + return tox_event_friend_name_unpack(&data->friend_name, bu, mem); case TOX_EVENT_FRIEND_READ_RECEIPT: - return tox_event_friend_read_receipt_unpack(&event->data.friend_read_receipt, bu, mem); + return tox_event_friend_read_receipt_unpack(&data->friend_read_receipt, bu, mem); case TOX_EVENT_FRIEND_REQUEST: - return tox_event_friend_request_unpack(&event->data.friend_request, bu, mem); + return tox_event_friend_request_unpack(&data->friend_request, bu, mem); case TOX_EVENT_FRIEND_STATUS_MESSAGE: - return tox_event_friend_status_message_unpack(&event->data.friend_status_message, bu, mem); + return tox_event_friend_status_message_unpack(&data->friend_status_message, bu, mem); case TOX_EVENT_FRIEND_STATUS: - return tox_event_friend_status_unpack(&event->data.friend_status, bu, mem); + return tox_event_friend_status_unpack(&data->friend_status, bu, mem); case TOX_EVENT_FRIEND_TYPING: - return tox_event_friend_typing_unpack(&event->data.friend_typing, bu, mem); + return tox_event_friend_typing_unpack(&data->friend_typing, bu, mem); case TOX_EVENT_SELF_CONNECTION_STATUS: - return tox_event_self_connection_status_unpack(&event->data.self_connection_status, bu, mem); + return tox_event_self_connection_status_unpack(&data->self_connection_status, bu, mem); case TOX_EVENT_GROUP_PEER_NAME: - return tox_event_group_peer_name_unpack(&event->data.group_peer_name, bu, mem); + return tox_event_group_peer_name_unpack(&data->group_peer_name, bu, mem); case TOX_EVENT_GROUP_PEER_STATUS: - return tox_event_group_peer_status_unpack(&event->data.group_peer_status, bu, mem); + return tox_event_group_peer_status_unpack(&data->group_peer_status, bu, mem); case TOX_EVENT_GROUP_TOPIC: - return tox_event_group_topic_unpack(&event->data.group_topic, bu, mem); + return tox_event_group_topic_unpack(&data->group_topic, bu, mem); case TOX_EVENT_GROUP_PRIVACY_STATE: - return tox_event_group_privacy_state_unpack(&event->data.group_privacy_state, bu, mem); + return tox_event_group_privacy_state_unpack(&data->group_privacy_state, bu, mem); case TOX_EVENT_GROUP_VOICE_STATE: - return tox_event_group_voice_state_unpack(&event->data.group_voice_state, bu, mem); + return tox_event_group_voice_state_unpack(&data->group_voice_state, bu, mem); case TOX_EVENT_GROUP_TOPIC_LOCK: - return tox_event_group_topic_lock_unpack(&event->data.group_topic_lock, bu, mem); + return tox_event_group_topic_lock_unpack(&data->group_topic_lock, bu, mem); case TOX_EVENT_GROUP_PEER_LIMIT: - return tox_event_group_peer_limit_unpack(&event->data.group_peer_limit, bu, mem); + return tox_event_group_peer_limit_unpack(&data->group_peer_limit, bu, mem); case TOX_EVENT_GROUP_PASSWORD: - return tox_event_group_password_unpack(&event->data.group_password, bu, mem); + return tox_event_group_password_unpack(&data->group_password, bu, mem); case TOX_EVENT_GROUP_MESSAGE: - return tox_event_group_message_unpack(&event->data.group_message, bu, mem); + return tox_event_group_message_unpack(&data->group_message, bu, mem); case TOX_EVENT_GROUP_PRIVATE_MESSAGE: - return tox_event_group_private_message_unpack(&event->data.group_private_message, bu, mem); + return tox_event_group_private_message_unpack(&data->group_private_message, bu, mem); case TOX_EVENT_GROUP_CUSTOM_PACKET: - return tox_event_group_custom_packet_unpack(&event->data.group_custom_packet, bu, mem); + return tox_event_group_custom_packet_unpack(&data->group_custom_packet, bu, mem); case TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET: - return tox_event_group_custom_private_packet_unpack(&event->data.group_custom_private_packet, bu, mem); + return tox_event_group_custom_private_packet_unpack(&data->group_custom_private_packet, bu, mem); case TOX_EVENT_GROUP_INVITE: - return tox_event_group_invite_unpack(&event->data.group_invite, bu, mem); + return tox_event_group_invite_unpack(&data->group_invite, bu, mem); case TOX_EVENT_GROUP_PEER_JOIN: - return tox_event_group_peer_join_unpack(&event->data.group_peer_join, bu, mem); + return tox_event_group_peer_join_unpack(&data->group_peer_join, bu, mem); case TOX_EVENT_GROUP_PEER_EXIT: - return tox_event_group_peer_exit_unpack(&event->data.group_peer_exit, bu, mem); + return tox_event_group_peer_exit_unpack(&data->group_peer_exit, bu, mem); case TOX_EVENT_GROUP_SELF_JOIN: - return tox_event_group_self_join_unpack(&event->data.group_self_join, bu, mem); + return tox_event_group_self_join_unpack(&data->group_self_join, bu, mem); case TOX_EVENT_GROUP_JOIN_FAIL: - return tox_event_group_join_fail_unpack(&event->data.group_join_fail, bu, mem); + return tox_event_group_join_fail_unpack(&data->group_join_fail, bu, mem); case TOX_EVENT_GROUP_MODERATION: - return tox_event_group_moderation_unpack(&event->data.group_moderation, bu, mem); + 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); case TOX_EVENT_INVALID: return false; @@ -1068,3 +1078,10 @@ bool tox_event_unpack_into(Tox_Event *event, Bin_Unpack *bu, const Memory *mem) return false; } + +bool tox_event_unpack_into(Tox_Event *event, Bin_Unpack *bu, const Memory *mem) +{ + return bin_unpack_array_fixed(bu, 2, nullptr) // + && tox_event_type_unpack(&event->type, bu) // + && tox_event_data_unpack(event->type, &event->data, bu, mem); +} diff --git a/toxcore/tox_event.h b/toxcore/tox_event.h index c28ba79b..fa98aae2 100644 --- a/toxcore/tox_event.h +++ b/toxcore/tox_event.h @@ -10,6 +10,7 @@ #include "bin_unpack.h" #include "mem.h" #include "tox_events.h" +#include "tox_private.h" #ifdef __cplusplus extern "C" { @@ -60,6 +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_Data; struct Tox_Event { @@ -111,6 +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); /** * Destructor. @@ -156,6 +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); /** * Pack into msgpack. @@ -201,6 +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); /** * Unpack from msgpack. @@ -246,9 +251,10 @@ 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); #ifdef __cplusplus -} +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_TOX_EVENT_H +#endif /* C_TOXCORE_TOXCORE_TOX_EVENT_H */ diff --git a/toxcore/tox_events.c b/toxcore/tox_events.c index fea4adc5..a5d995cf 100644 --- a/toxcore/tox_events.c +++ b/toxcore/tox_events.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-3.0-or-later - * Copyright © 2022 The TokTok team. + * Copyright © 2022-2024 The TokTok team. */ #include "tox_events.h" @@ -7,6 +7,7 @@ #include #include +#include "attributes.h" #include "bin_pack.h" #include "bin_unpack.h" #include "ccompat.h" @@ -18,14 +19,12 @@ #include "tox_private.h" #include "tox_struct.h" - /***************************************************** * * :: Set up event handlers. * *****************************************************/ - void tox_events_init(Tox *tox) { tox_callback_conference_connected(tox, tox_events_handle_conference_connected); @@ -67,6 +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); } uint32_t tox_events_get_size(const Tox_Events *events) @@ -74,6 +74,12 @@ uint32_t tox_events_get_size(const Tox_Events *events) return events == nullptr ? 0 : events->events_size; } +nullable(1) +static const Tox_Event *tox_events_get_events(const Tox_Events *events) +{ + return events == nullptr ? nullptr : events->events; +} + const Tox_Event *tox_events_get(const Tox_Events *events, uint32_t index) { if (index >= tox_events_get_size(events)) { @@ -101,24 +107,36 @@ Tox_Events *tox_events_iterate(Tox *tox, bool fail_hard, Tox_Err_Events_Iterate return state.events; } -bool tox_events_pack(const Tox_Events *events, Bin_Pack *bp) +non_null() +static bool tox_event_pack_handler(const void *arr, uint32_t index, const Logger *logger, Bin_Pack *bp) { - const uint32_t size = tox_events_get_size(events); - if (!bin_pack_array(bp, size)) { - return false; - } - - for (uint32_t i = 0; i < size; ++i) { - if (!tox_event_pack(&events->events[i], bp)) { - return false; - } - } - - return true; + const Tox_Event *events = (const Tox_Event *)arr; + assert(events != nullptr); + return tox_event_pack(&events[index], bp); } -bool tox_events_unpack(Tox_Events *events, Bin_Unpack *bu, const Memory *mem) +non_null(3) nullable(1, 2) +static bool tox_events_pack_handler(const void *obj, const Logger *logger, Bin_Pack *bp) { + const Tox_Events *events = (const Tox_Events *)obj; + return bin_pack_obj_array(bp, tox_event_pack_handler, tox_events_get_events(events), tox_events_get_size(events), logger); +} + +uint32_t tox_events_bytes_size(const Tox_Events *events) +{ + return bin_pack_obj_size(tox_events_pack_handler, events, nullptr); +} + +bool tox_events_get_bytes(const Tox_Events *events, uint8_t *bytes) +{ + return bin_pack_obj(tox_events_pack_handler, events, nullptr, bytes, UINT32_MAX); +} + +non_null() +static bool tox_events_unpack_handler(void *obj, Bin_Unpack *bu) +{ + Tox_Events *events = (Tox_Events *)obj; + uint32_t size; if (!bin_unpack_array(bu, &size)) { return false; @@ -126,13 +144,13 @@ bool tox_events_unpack(Tox_Events *events, Bin_Unpack *bu, const Memory *mem) for (uint32_t i = 0; i < size; ++i) { Tox_Event event = {TOX_EVENT_INVALID}; - if (!tox_event_unpack_into(&event, bu, mem)) { - tox_event_destruct(&event, mem); + if (!tox_event_unpack_into(&event, bu, events->mem)) { + tox_event_destruct(&event, events->mem); return false; } if (!tox_events_add(events, &event)) { - tox_event_destruct(&event, mem); + tox_event_destruct(&event, events->mem); return false; } } @@ -142,35 +160,11 @@ bool tox_events_unpack(Tox_Events *events, Bin_Unpack *bu, const Memory *mem) return true; } -non_null(1) nullable(2, 3) -static bool tox_events_bin_pack_handler(Bin_Pack *bp, const Logger *logger, const void *obj) -{ - const Tox_Events *events = (const Tox_Events *)obj; - return tox_events_pack(events, bp); -} - -uint32_t tox_events_bytes_size(const Tox_Events *events) -{ - return bin_pack_obj_size(tox_events_bin_pack_handler, nullptr, events); -} - -bool tox_events_get_bytes(const Tox_Events *events, uint8_t *bytes) -{ - return bin_pack_obj(tox_events_bin_pack_handler, nullptr, events, bytes, UINT32_MAX); -} - Tox_Events *tox_events_load(const Tox_System *sys, const uint8_t *bytes, uint32_t bytes_size) { - Bin_Unpack *bu = bin_unpack_new(bytes, bytes_size); - - if (bu == nullptr) { - return nullptr; - } - Tox_Events *events = (Tox_Events *)mem_alloc(sys->mem, sizeof(Tox_Events)); if (events == nullptr) { - bin_unpack_free(bu); return nullptr; } @@ -179,13 +173,11 @@ Tox_Events *tox_events_load(const Tox_System *sys, const uint8_t *bytes, uint32_ }; events->mem = sys->mem; - if (!tox_events_unpack(events, bu, sys->mem)) { + if (!bin_unpack_obj(tox_events_unpack_handler, events, bytes, bytes_size)) { tox_events_free(events); - bin_unpack_free(bu); return nullptr; } - bin_unpack_free(bu); return events; } diff --git a/toxcore/tox_events.h b/toxcore/tox_events.h index 05edd4f4..73068829 100644 --- a/toxcore/tox_events.h +++ b/toxcore/tox_events.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-3.0-or-later - * Copyright © 2022 The TokTok team. + * Copyright © 2022-2024 The TokTok team. */ #ifndef C_TOXCORE_TOXCORE_TOX_EVENTS_H @@ -268,6 +268,8 @@ const uint8_t *tox_event_group_private_message_get_message( const Tox_Event_Group_Private_Message *group_private_message); uint32_t tox_event_group_private_message_get_message_length( const Tox_Event_Group_Private_Message *group_private_message); +uint32_t tox_event_group_private_message_get_message_id( + const Tox_Event_Group_Private_Message *group_private_message); typedef struct Tox_Event_Group_Custom_Packet Tox_Event_Group_Custom_Packet; uint32_t tox_event_group_custom_packet_get_group_number( @@ -343,6 +345,16 @@ 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 enum Tox_Event_Type { TOX_EVENT_SELF_CONNECTION_STATUS = 0, @@ -391,6 +403,8 @@ typedef enum Tox_Event_Type { TOX_EVENT_GROUP_JOIN_FAIL = 37, TOX_EVENT_GROUP_MODERATION = 38, + TOX_EVENT_DHT_GET_NODES_RESPONSE = 39, + TOX_EVENT_INVALID = 255, } Tox_Event_Type; @@ -486,6 +500,8 @@ 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 *event); /** * Container object for all Tox core events. @@ -559,7 +575,7 @@ Tox_Events *tox_events_load(const Tox_System *sys, const uint8_t *bytes, uint32_ bool tox_events_equal(const Tox_System *sys, const Tox_Events *a, const Tox_Events *b); #ifdef __cplusplus -} +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_TOX_EVENTS_H +#endif /* C_TOXCORE_TOXCORE_TOX_EVENTS_H */ diff --git a/toxcore/tox_events_fuzz_test.cc b/toxcore/tox_events_fuzz_test.cc index 480d80a4..556d78ae 100644 --- a/toxcore/tox_events_fuzz_test.cc +++ b/toxcore/tox_events_fuzz_test.cc @@ -5,7 +5,7 @@ #include #include -#include "../testing/fuzzing/fuzz_support.h" +#include "../testing/fuzzing/fuzz_support.hh" #include "tox_dispatch.h" namespace { @@ -32,7 +32,7 @@ void TestUnpack(Fuzz_Data data) Tox_Dispatch *dispatch = tox_dispatch_new(nullptr); assert(dispatch != nullptr); - auto ignore = [](Tox *tox, auto *event, void *user_data) {}; + auto ignore = [](auto *event, void *user_data) {}; tox_events_callback_conference_connected(dispatch, ignore); tox_events_callback_conference_invite(dispatch, ignore); tox_events_callback_conference_message(dispatch, ignore); @@ -78,7 +78,7 @@ void TestUnpack(Fuzz_Data data) std::vector packed(tox_events_bytes_size(events)); tox_events_get_bytes(events, packed.data()); - tox_dispatch_invoke(dispatch, events, nullptr, nullptr); + tox_dispatch_invoke(dispatch, events, nullptr); } tox_events_free(events); tox_dispatch_free(dispatch); diff --git a/toxcore/tox_pack.h b/toxcore/tox_pack.h index 4e554bce..ea8605dc 100644 --- a/toxcore/tox_pack.h +++ b/toxcore/tox_pack.h @@ -21,4 +21,4 @@ non_null() bool tox_group_join_fail_pack(Tox_Group_Join_Fail val, Bin_Pack *bp); non_null() bool tox_group_mod_event_pack(Tox_Group_Mod_Event val, Bin_Pack *bp); non_null() bool tox_group_exit_type_pack(Tox_Group_Exit_Type val, Bin_Pack *bp); -#endif // C_TOXCORE_TOXCORE_TOX_PACK_H +#endif /* C_TOXCORE_TOXCORE_TOX_PACK_H */ diff --git a/toxcore/tox_private.c b/toxcore/tox_private.c index 11526f95..7b6050a9 100644 --- a/toxcore/tox_private.c +++ b/toxcore/tox_private.c @@ -11,6 +11,7 @@ #include #include "DHT.h" +#include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "group_chats.h" @@ -33,9 +34,9 @@ Tox_System tox_default_system(void) const Tox_System sys = { nullptr, // mono_time_callback nullptr, // mono_time_user_data - system_random(), - system_network(), - system_memory(), + os_random(), + os_network(), + os_memory(), }; return sys; } @@ -156,7 +157,8 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip return true; } -uint16_t tox_dht_get_num_closelist(const Tox *tox) { +uint16_t tox_dht_get_num_closelist(const Tox *tox) +{ tox_lock(tox); const uint16_t num_total = dht_get_num_closelist(tox->m->dht); tox_unlock(tox); @@ -164,7 +166,8 @@ uint16_t tox_dht_get_num_closelist(const Tox *tox) { return num_total; } -uint16_t tox_dht_get_num_closelist_announce_capable(const Tox *tox){ +uint16_t tox_dht_get_num_closelist_announce_capable(const Tox *tox) +{ tox_lock(tox); const uint16_t num_cap = dht_get_num_closelist_announce_capable(tox->m->dht); tox_unlock(tox); @@ -173,7 +176,7 @@ uint16_t tox_dht_get_num_closelist_announce_capable(const Tox *tox){ } size_t tox_group_peer_get_ip_address_size(const Tox *tox, uint32_t group_number, uint32_t peer_id, - Tox_Err_Group_Peer_Query *error) + Tox_Err_Group_Peer_Query *error) { assert(tox != nullptr); @@ -186,7 +189,7 @@ size_t tox_group_peer_get_ip_address_size(const Tox *tox, uint32_t group_number, return -1; } - const int ret = gc_get_peer_ip_address_size(chat, peer_id); + const int ret = gc_get_peer_ip_address_size(chat, gc_peer_id_from_int(peer_id)); tox_unlock(tox); if (ret == -1) { @@ -199,7 +202,7 @@ size_t tox_group_peer_get_ip_address_size(const Tox *tox, uint32_t group_number, } bool tox_group_peer_get_ip_address(const Tox *tox, uint32_t group_number, uint32_t peer_id, uint8_t *ip_addr, - Tox_Err_Group_Peer_Query *error) + Tox_Err_Group_Peer_Query *error) { assert(tox != nullptr); @@ -212,7 +215,7 @@ bool tox_group_peer_get_ip_address(const Tox *tox, uint32_t group_number, uint32 return false; } - const int ret = gc_get_peer_ip_address(chat, peer_id, ip_addr); + const int ret = gc_get_peer_ip_address(chat, gc_peer_id_from_int(peer_id), ip_addr); tox_unlock(tox); if (ret == -1) { diff --git a/toxcore/tox_private.h b/toxcore/tox_private.h index 14b209d3..d36ab026 100644 --- a/toxcore/tox_private.h +++ b/toxcore/tox_private.h @@ -56,7 +56,6 @@ void tox_callback_friend_lossless_packet_per_pktid(Tox *tox, tox_friend_lossless void tox_set_av_object(Tox *tox, void *object); void *tox_get_av_object(const Tox *tox); - /******************************************************************************* * * :: DHT network queries. @@ -85,7 +84,6 @@ uint32_t tox_dht_node_public_key_size(void); typedef void tox_dht_get_nodes_response_cb(Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port, void *user_data); - /** * Set the callback for the `dht_get_nodes_response` event. Pass NULL to unset. * @@ -93,7 +91,6 @@ typedef void tox_dht_get_nodes_response_cb(Tox *tox, const uint8_t *public_key, */ void tox_callback_dht_get_nodes_response(Tox *tox, tox_dht_get_nodes_response_cb *callback); - typedef enum Tox_Err_Dht_Get_Nodes { /** * The function returned successfully. @@ -158,7 +155,6 @@ uint16_t tox_dht_get_num_closelist(const Tox *tox); */ uint16_t tox_dht_get_num_closelist_announce_capable(const Tox *tox); - /******************************************************************************* * * :: DHT groupchat queries. @@ -180,7 +176,7 @@ uint32_t tox_group_peer_ip_string_max_length(void); * @param peer_id The ID of the peer whose IP address length we want to retrieve. */ size_t tox_group_peer_get_ip_address_size(const Tox *tox, uint32_t group_number, uint32_t peer_id, - Tox_Err_Group_Peer_Query *error); + Tox_Err_Group_Peer_Query *error); /** * Write the IP address associated with the designated peer_id for the designated group number * to ip_addr. @@ -204,7 +200,7 @@ bool tox_group_peer_get_ip_address(const Tox *tox, uint32_t group_number, uint32 Tox_Err_Group_Peer_Query *error); #ifdef __cplusplus -} +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_TOX_PRIVATE_H +#endif /* C_TOXCORE_TOXCORE_TOX_PRIVATE_H */ diff --git a/toxcore/tox_struct.h b/toxcore/tox_struct.h index b298269a..bd42fcce 100644 --- a/toxcore/tox_struct.h +++ b/toxcore/tox_struct.h @@ -6,8 +6,11 @@ #ifndef C_TOXCORE_TOXCORE_TOX_STRUCT_H #define C_TOXCORE_TOXCORE_TOX_STRUCT_H +#include + #include "Messenger.h" #include "mem.h" +#include "mono_time.h" #include "tox.h" #include "tox_private.h" @@ -67,7 +70,7 @@ struct Tox { }; #ifdef __cplusplus -} +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_TOX_STRUCT_H +#endif /* C_TOXCORE_TOXCORE_TOX_STRUCT_H */ diff --git a/toxcore/tox_test.cc b/toxcore/tox_test.cc index 2deb961c..d3fe9bae 100644 --- a/toxcore/tox_test.cc +++ b/toxcore/tox_test.cc @@ -101,7 +101,7 @@ TEST(Tox, OneTest) Tox *tox1 = tox_new(options, nullptr); ASSERT_NE(tox1, nullptr); - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); set_random_name_and_status_message(tox1, rng, name.data(), status_message.data()); Tox *tox2 = tox_new(options, nullptr); diff --git a/toxcore/tox_unpack.c b/toxcore/tox_unpack.c index 8f30824f..b5e05da8 100644 --- a/toxcore/tox_unpack.c +++ b/toxcore/tox_unpack.c @@ -6,6 +6,7 @@ #include +#include "attributes.h" #include "bin_unpack.h" #include "tox.h" @@ -166,20 +167,20 @@ bool tox_user_status_unpack(Tox_User_Status *val, Bin_Unpack *bu) non_null() static bool tox_group_privacy_state_from_int(uint32_t value, Tox_Group_Privacy_State *out) { - switch (value) { - case TOX_GROUP_PRIVACY_STATE_PUBLIC: { - *out = TOX_GROUP_PRIVACY_STATE_PUBLIC; - return true; + switch (value) { + case TOX_GROUP_PRIVACY_STATE_PUBLIC: { + *out = TOX_GROUP_PRIVACY_STATE_PUBLIC; + return true; + } + case TOX_GROUP_PRIVACY_STATE_PRIVATE: { + *out = TOX_GROUP_PRIVACY_STATE_PRIVATE; + return true; + } + default: { + *out = TOX_GROUP_PRIVACY_STATE_PUBLIC; + return false; + } } - case TOX_GROUP_PRIVACY_STATE_PRIVATE: { - *out = TOX_GROUP_PRIVACY_STATE_PRIVATE; - return true; - } - default: { - *out = TOX_GROUP_PRIVACY_STATE_PUBLIC; - return false; - } - } } bool tox_group_privacy_state_unpack(Tox_Group_Privacy_State *val, Bin_Unpack *bu) { @@ -190,24 +191,24 @@ bool tox_group_privacy_state_unpack(Tox_Group_Privacy_State *val, Bin_Unpack *bu non_null() static bool tox_group_voice_state_from_int(uint32_t value, Tox_Group_Voice_State *out) { - switch (value) { - case TOX_GROUP_VOICE_STATE_ALL: { - *out = TOX_GROUP_VOICE_STATE_ALL; - return true; + switch (value) { + case TOX_GROUP_VOICE_STATE_ALL: { + *out = TOX_GROUP_VOICE_STATE_ALL; + return true; + } + case TOX_GROUP_VOICE_STATE_MODERATOR: { + *out = TOX_GROUP_VOICE_STATE_MODERATOR; + return true; + } + case TOX_GROUP_VOICE_STATE_FOUNDER: { + *out = TOX_GROUP_VOICE_STATE_FOUNDER; + return true; + } + default: { + *out = TOX_GROUP_VOICE_STATE_ALL; + return false; + } } - case TOX_GROUP_VOICE_STATE_MODERATOR: { - *out = TOX_GROUP_VOICE_STATE_MODERATOR; - return true; - } - case TOX_GROUP_VOICE_STATE_FOUNDER: { - *out = TOX_GROUP_VOICE_STATE_FOUNDER; - return true; - } - default: { - *out = TOX_GROUP_VOICE_STATE_ALL; - return false; - } - } } bool tox_group_voice_state_unpack(Tox_Group_Voice_State *val, Bin_Unpack *bu) { @@ -219,20 +220,20 @@ bool tox_group_voice_state_unpack(Tox_Group_Voice_State *val, Bin_Unpack *bu) non_null() static bool tox_group_topic_lock_from_int(uint32_t value, Tox_Group_Topic_Lock *out) { - switch (value) { - case TOX_GROUP_TOPIC_LOCK_ENABLED: { - *out = TOX_GROUP_TOPIC_LOCK_ENABLED; - return true; + switch (value) { + case TOX_GROUP_TOPIC_LOCK_ENABLED: { + *out = TOX_GROUP_TOPIC_LOCK_ENABLED; + return true; + } + case TOX_GROUP_TOPIC_LOCK_DISABLED: { + *out = TOX_GROUP_TOPIC_LOCK_DISABLED; + return true; + } + default: { + *out = TOX_GROUP_TOPIC_LOCK_ENABLED; + return false; + } } - case TOX_GROUP_TOPIC_LOCK_DISABLED: { - *out = TOX_GROUP_TOPIC_LOCK_DISABLED; - return true; - } - default: { - *out = TOX_GROUP_TOPIC_LOCK_ENABLED; - return false; - } - } } bool tox_group_topic_lock_unpack(Tox_Group_Topic_Lock *val, Bin_Unpack *bu) { @@ -244,24 +245,24 @@ bool tox_group_topic_lock_unpack(Tox_Group_Topic_Lock *val, Bin_Unpack *bu) non_null() static bool tox_group_join_fail_from_int(uint32_t value, Tox_Group_Join_Fail *out) { - switch (value) { - case TOX_GROUP_JOIN_FAIL_PEER_LIMIT: { - *out = TOX_GROUP_JOIN_FAIL_PEER_LIMIT; - return true; + switch (value) { + case TOX_GROUP_JOIN_FAIL_PEER_LIMIT: { + *out = TOX_GROUP_JOIN_FAIL_PEER_LIMIT; + return true; + } + case TOX_GROUP_JOIN_FAIL_INVALID_PASSWORD: { + *out = TOX_GROUP_JOIN_FAIL_INVALID_PASSWORD; + return true; + } + case TOX_GROUP_JOIN_FAIL_UNKNOWN: { + *out = TOX_GROUP_JOIN_FAIL_UNKNOWN; + return true; + } + default: { + *out = TOX_GROUP_JOIN_FAIL_PEER_LIMIT; + return false; + } } - case TOX_GROUP_JOIN_FAIL_INVALID_PASSWORD: { - *out = TOX_GROUP_JOIN_FAIL_INVALID_PASSWORD; - return true; - } - case TOX_GROUP_JOIN_FAIL_UNKNOWN: { - *out = TOX_GROUP_JOIN_FAIL_UNKNOWN; - return true; - } - default: { - *out = TOX_GROUP_JOIN_FAIL_PEER_LIMIT; - return false; - } - } } bool tox_group_join_fail_unpack(Tox_Group_Join_Fail *val, Bin_Unpack *bu) { @@ -273,28 +274,28 @@ bool tox_group_join_fail_unpack(Tox_Group_Join_Fail *val, Bin_Unpack *bu) non_null() static bool tox_group_mod_event_from_int(uint32_t value, Tox_Group_Mod_Event *out) { - switch (value) { - case TOX_GROUP_MOD_EVENT_KICK: { - *out = TOX_GROUP_MOD_EVENT_KICK; - return true; + switch (value) { + case TOX_GROUP_MOD_EVENT_KICK: { + *out = TOX_GROUP_MOD_EVENT_KICK; + return true; + } + case TOX_GROUP_MOD_EVENT_OBSERVER: { + *out = TOX_GROUP_MOD_EVENT_OBSERVER; + return true; + } + case TOX_GROUP_MOD_EVENT_USER: { + *out = TOX_GROUP_MOD_EVENT_USER; + return true; + } + case TOX_GROUP_MOD_EVENT_MODERATOR: { + *out = TOX_GROUP_MOD_EVENT_MODERATOR; + return true; + } + default: { + *out = TOX_GROUP_MOD_EVENT_KICK; + return false; + } } - case TOX_GROUP_MOD_EVENT_OBSERVER: { - *out = TOX_GROUP_MOD_EVENT_OBSERVER; - return true; - } - case TOX_GROUP_MOD_EVENT_USER: { - *out = TOX_GROUP_MOD_EVENT_USER; - return true; - } - case TOX_GROUP_MOD_EVENT_MODERATOR: { - *out = TOX_GROUP_MOD_EVENT_MODERATOR; - return true; - } - default: { - *out = TOX_GROUP_MOD_EVENT_KICK; - return false; - } - } } bool tox_group_mod_event_unpack(Tox_Group_Mod_Event *val, Bin_Unpack *bu) { @@ -306,36 +307,36 @@ bool tox_group_mod_event_unpack(Tox_Group_Mod_Event *val, Bin_Unpack *bu) non_null() static bool tox_group_exit_type_from_int(uint32_t value, Tox_Group_Exit_Type *out) { - switch (value) { - case TOX_GROUP_EXIT_TYPE_QUIT: { - *out = TOX_GROUP_EXIT_TYPE_QUIT; - return true; + switch (value) { + case TOX_GROUP_EXIT_TYPE_QUIT: { + *out = TOX_GROUP_EXIT_TYPE_QUIT; + return true; + } + case TOX_GROUP_EXIT_TYPE_TIMEOUT: { + *out = TOX_GROUP_EXIT_TYPE_TIMEOUT; + return true; + } + case TOX_GROUP_EXIT_TYPE_DISCONNECTED: { + *out = TOX_GROUP_EXIT_TYPE_DISCONNECTED; + return true; + } + case TOX_GROUP_EXIT_TYPE_SELF_DISCONNECTED: { + *out = TOX_GROUP_EXIT_TYPE_SELF_DISCONNECTED; + return true; + } + case TOX_GROUP_EXIT_TYPE_KICK: { + *out = TOX_GROUP_EXIT_TYPE_KICK; + return true; + } + case TOX_GROUP_EXIT_TYPE_SYNC_ERROR: { + *out = TOX_GROUP_EXIT_TYPE_SYNC_ERROR; + return true; + } + default: { + *out = TOX_GROUP_EXIT_TYPE_QUIT; + return false; + } } - case TOX_GROUP_EXIT_TYPE_TIMEOUT: { - *out = TOX_GROUP_EXIT_TYPE_TIMEOUT; - return true; - } - case TOX_GROUP_EXIT_TYPE_DISCONNECTED: { - *out = TOX_GROUP_EXIT_TYPE_DISCONNECTED; - return true; - } - case TOX_GROUP_EXIT_TYPE_SELF_DISCONNECTED: { - *out = TOX_GROUP_EXIT_TYPE_SELF_DISCONNECTED; - return true; - } - case TOX_GROUP_EXIT_TYPE_KICK: { - *out = TOX_GROUP_EXIT_TYPE_KICK; - return true; - } - case TOX_GROUP_EXIT_TYPE_SYNC_ERROR: { - *out = TOX_GROUP_EXIT_TYPE_SYNC_ERROR; - return true; - } - default: { - *out = TOX_GROUP_EXIT_TYPE_QUIT; - return false; - } - } } bool tox_group_exit_type_unpack(Tox_Group_Exit_Type *val, Bin_Unpack *bu) { diff --git a/toxcore/tox_unpack.h b/toxcore/tox_unpack.h index 1f2118cb..828d2947 100644 --- a/toxcore/tox_unpack.h +++ b/toxcore/tox_unpack.h @@ -21,4 +21,4 @@ non_null() bool tox_group_join_fail_unpack(Tox_Group_Join_Fail *val, Bin_Unpack non_null() bool tox_group_mod_event_unpack(Tox_Group_Mod_Event *val, Bin_Unpack *bu); non_null() bool tox_group_exit_type_unpack(Tox_Group_Exit_Type *val, Bin_Unpack *bu); -#endif // C_TOXCORE_TOXCORE_TOX_UNPACK_H +#endif /* C_TOXCORE_TOXCORE_TOX_UNPACK_H */ diff --git a/toxcore/util.c b/toxcore/util.c index 9a0a26a7..1851e58a 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -9,7 +9,7 @@ */ #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 -#endif +#endif /* _XOPEN_SOURCE */ #include "util.h" @@ -96,6 +96,15 @@ uint8_t *memdup(const uint8_t *data, size_t data_size) return copy; } +void memzero(uint8_t *data, size_t data_size) +{ + if (data == nullptr || data_size == 0) { + return; + } + + memset(data, 0, data_size); +} + int16_t max_s16(int16_t a, int16_t b) { return a > b ? a : b; @@ -152,6 +161,11 @@ uint64_t min_u64(uint64_t a, uint64_t b) return a < b ? a : b; } +int cmp_uint(uint64_t a, uint64_t b) +{ + return (a > b ? 1 : 0) - (a < b ? 1 : 0); +} + uint32_t jenkins_one_at_a_time_hash(const uint8_t *key, size_t len) { uint32_t hash = 0; diff --git a/toxcore/util.h b/toxcore/util.h index 8c212cfb..5be74a8d 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -48,6 +48,16 @@ non_null() bool memeq(const uint8_t *a, size_t a_size, const uint8_t *b, size_t */ nullable(1) uint8_t *memdup(const uint8_t *data, size_t data_size); +/** + * @brief Set all bytes in `data` to 0. + * + * NOTE: This does not securely zero out data. DO NOT USE for sensitive data. Use + * `crypto_memzero` from `crypto_core.h`, instead. This function is ok to use for + * message buffers, public keys, encrypted data, etc. It is not ok for buffers + * containing key material (secret keys, shared keys). + */ +nullable(1) void memzero(uint8_t *data, size_t data_size); + // Safe min/max functions with specific types. This forces the conversion to the // desired type before the comparison expression, giving the choice of // conversion to the caller. Use these instead of inline comparisons or MIN/MAX @@ -69,6 +79,9 @@ uint16_t min_u16(uint16_t a, uint16_t b); uint32_t min_u32(uint32_t a, uint32_t b); uint64_t min_u64(uint64_t a, uint64_t b); +// Comparison function: return -1 if ab. +int cmp_uint(uint64_t a, uint64_t b); + /** @brief Returns a 32-bit hash of key of size len */ non_null() uint32_t jenkins_one_at_a_time_hash(const uint8_t *key, size_t len); @@ -84,7 +97,7 @@ non_null() uint16_t data_checksum(const uint8_t *data, uint32_t length); #ifdef __cplusplus -} // extern "C" +} /* extern "C" */ #endif -#endif // C_TOXCORE_TOXCORE_UTIL_H +#endif /* C_TOXCORE_TOXCORE_UTIL_H */ diff --git a/toxcore/util_test.cc b/toxcore/util_test.cc index aca278e3..94e653f2 100644 --- a/toxcore/util_test.cc +++ b/toxcore/util_test.cc @@ -34,4 +34,15 @@ TEST(Util, IdCopyMakesKeysEqual) EXPECT_TRUE(pk_equal(pk1, pk2)); } +TEST(Cmp, OrdersNumbersCorrectly) +{ + EXPECT_EQ(cmp_uint(1, 2), -1); + EXPECT_EQ(cmp_uint(0, UINT32_MAX), -1); + EXPECT_EQ(cmp_uint(UINT32_MAX, 0), 1); + EXPECT_EQ(cmp_uint(UINT32_MAX, UINT32_MAX), 0); + EXPECT_EQ(cmp_uint(0, UINT64_MAX), -1); + EXPECT_EQ(cmp_uint(UINT64_MAX, 0), 1); + EXPECT_EQ(cmp_uint(UINT64_MAX, UINT64_MAX), 0); +} + } // namespace diff --git a/toxencryptsave/defines.h b/toxencryptsave/defines.h index 71c0f105..ac80cc78 100644 --- a/toxencryptsave/defines.h +++ b/toxencryptsave/defines.h @@ -9,4 +9,4 @@ #define TOX_ENC_SAVE_MAGIC_NUMBER ((const uint8_t *)"toxEsave") #define TOX_ENC_SAVE_MAGIC_LENGTH 8 -#endif +#endif /* C_TOXCORE_TOXENCRYPTSAVE_DEFINES_H */ diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c index a8110fb9..c43e3575 100644 --- a/toxencryptsave/toxencryptsave.c +++ b/toxencryptsave/toxencryptsave.c @@ -80,8 +80,8 @@ void tox_pass_key_free(Tox_Pass_Key *key) * @return true on success. */ bool tox_get_salt( - const uint8_t ciphertext[TOX_PASS_ENCRYPTION_EXTRA_LENGTH], - uint8_t salt[TOX_PASS_SALT_LENGTH], Tox_Err_Get_Salt *error) + const uint8_t ciphertext[TOX_PASS_ENCRYPTION_EXTRA_LENGTH], + uint8_t salt[TOX_PASS_SALT_LENGTH], Tox_Err_Get_Salt *error) { if (ciphertext == nullptr || salt == nullptr) { SET_ERROR_PARAMETER(error, TOX_ERR_GET_SALT_NULL); @@ -115,10 +115,10 @@ bool tox_get_salt( * @return new symmetric key on success, NULL on failure. */ Tox_Pass_Key *tox_pass_key_derive( - const uint8_t passphrase[], size_t passphrase_len, - Tox_Err_Key_Derivation *error) + const uint8_t passphrase[], size_t passphrase_len, + Tox_Err_Key_Derivation *error) { - const Random *rng = system_random(); + const Random *rng = os_random(); if (rng == nullptr) { SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_FAILED); @@ -140,8 +140,8 @@ Tox_Pass_Key *tox_pass_key_derive( * @return new symmetric key on success, NULL on failure. */ Tox_Pass_Key *tox_pass_key_derive_with_salt( - const uint8_t passphrase[], size_t passphrase_len, - const uint8_t salt[TOX_PASS_SALT_LENGTH], Tox_Err_Key_Derivation *error) + const uint8_t passphrase[], size_t passphrase_len, + const uint8_t salt[TOX_PASS_SALT_LENGTH], Tox_Err_Key_Derivation *error) { if (salt == nullptr || (passphrase == nullptr && passphrase_len != 0)) { SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_NULL); @@ -196,7 +196,7 @@ Tox_Pass_Key *tox_pass_key_derive_with_salt( bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t plaintext[], size_t plaintext_len, uint8_t ciphertext[], Tox_Err_Encryption *error) { - const Random *rng = system_random(); + const Random *rng = os_random(); if (rng == nullptr) { SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED); diff --git a/toxencryptsave/toxencryptsave.h b/toxencryptsave/toxencryptsave.h index 4bc532ad..b9691551 100644 --- a/toxencryptsave/toxencryptsave.h +++ b/toxencryptsave/toxencryptsave.h @@ -14,7 +14,6 @@ #include #include - #ifdef __cplusplus extern "C" { #endif @@ -46,8 +45,6 @@ extern "C" { * ******************************************************************************/ - - /** * The size of the salt part of a pass-key. */ @@ -91,7 +88,6 @@ typedef enum Tox_Err_Key_Derivation { } Tox_Err_Key_Derivation; - typedef enum Tox_Err_Encryption { /** @@ -118,7 +114,6 @@ typedef enum Tox_Err_Encryption { } Tox_Err_Encryption; - typedef enum Tox_Err_Decryption { /** @@ -157,8 +152,6 @@ typedef enum Tox_Err_Decryption { } Tox_Err_Decryption; - - /******************************************************************************* * * BEGIN PART 1 @@ -169,8 +162,6 @@ typedef enum Tox_Err_Decryption { * ******************************************************************************/ - - /** * Encrypts the given data with the given passphrase. * @@ -206,7 +197,6 @@ bool tox_pass_encrypt(const uint8_t plaintext[], size_t plaintext_len, const uin bool tox_pass_decrypt(const uint8_t ciphertext[], size_t ciphertext_len, const uint8_t passphrase[], size_t passphrase_len, uint8_t plaintext[/*! ciphertext_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH */], Tox_Err_Decryption *error); - /******************************************************************************* * * BEGIN PART 2 @@ -216,8 +206,6 @@ bool tox_pass_decrypt(const uint8_t ciphertext[], size_t ciphertext_len, const u * ******************************************************************************/ - - /** * This type represents a pass-key. * @@ -256,8 +244,8 @@ void tox_pass_key_free(Tox_Pass_Key *key); * @return new symmetric key on success, NULL on failure. */ Tox_Pass_Key *tox_pass_key_derive( - const uint8_t passphrase[], size_t passphrase_len, - Tox_Err_Key_Derivation *error); + const uint8_t passphrase[], size_t passphrase_len, + Tox_Err_Key_Derivation *error); /** * Same as above, except use the given salt for deterministic key derivation. @@ -269,8 +257,8 @@ Tox_Pass_Key *tox_pass_key_derive( * @return new symmetric key on success, NULL on failure. */ Tox_Pass_Key *tox_pass_key_derive_with_salt( - const uint8_t passphrase[], size_t passphrase_len, - const uint8_t salt[TOX_PASS_SALT_LENGTH], Tox_Err_Key_Derivation *error); + const uint8_t passphrase[], size_t passphrase_len, + const uint8_t salt[TOX_PASS_SALT_LENGTH], Tox_Err_Key_Derivation *error); /** * Encrypt a plain text with a key produced by tox_pass_key_derive or tox_pass_key_derive_with_salt. @@ -320,7 +308,6 @@ typedef enum Tox_Err_Get_Salt { } Tox_Err_Get_Salt; - /** * Retrieves the salt used to encrypt the given data. * @@ -341,8 +328,8 @@ typedef enum Tox_Err_Get_Salt { * @return true on success. */ bool tox_get_salt( - const uint8_t ciphertext[TOX_PASS_ENCRYPTION_EXTRA_LENGTH], - uint8_t salt[TOX_PASS_SALT_LENGTH], Tox_Err_Get_Salt *error); + const uint8_t ciphertext[TOX_PASS_ENCRYPTION_EXTRA_LENGTH], + uint8_t salt[TOX_PASS_SALT_LENGTH], Tox_Err_Get_Salt *error); /** * Determines whether or not the given data is encrypted by this module. @@ -360,9 +347,8 @@ bool tox_get_salt( */ bool tox_is_data_encrypted(const uint8_t data[TOX_PASS_ENCRYPTION_EXTRA_LENGTH]); - #ifdef __cplusplus -} +} /* extern "C" */ #endif //!TOKSTYLE- @@ -374,4 +360,4 @@ typedef Tox_Err_Get_Salt TOX_ERR_GET_SALT; //!TOKSTYLE+ -#endif // C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H +#endif /* C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H */