diff --git a/external/toxcore/c-toxcore/.circleci/config.yml b/external/toxcore/c-toxcore/.circleci/config.yml index 69811f4..2fd8c05 100644 --- a/external/toxcore/c-toxcore/.circleci/config.yml +++ b/external/toxcore/c-toxcore/.circleci/config.yml @@ -3,20 +3,15 @@ version: 2 workflows: version: 2 - program-analysis: + circleci: jobs: - # Dynamic analysis in the Bazel build - bazel-asan - bazel-msan - - bazel-tsan - # Dynamic analysis with CMake - - asan - - tsan - - ubsan - # Static analysis - clang-analyze - cpplint - static-analysis + - cimplefmt + - generate-events jobs: bazel-asan: @@ -29,20 +24,6 @@ jobs: - run: .circleci/bazel-test //c-toxcore/... - bazel-tsan: - working_directory: /tmp/cirrus-ci-build - docker: - - image: toxchat/toktok-stack:latest-tsan - - steps: - - checkout - - run: .circleci/bazel-test - //c-toxcore/... - -//c-toxcore/auto_tests:conference_av_test - -//c-toxcore/auto_tests:conference_test - -//c-toxcore/auto_tests:onion_test - -//c-toxcore/auto_tests:tox_many_test - bazel-msan: working_directory: /tmp/cirrus-ci-build docker: @@ -53,7 +34,7 @@ jobs: - run: .circleci/bazel-test //c-toxcore/auto_tests:lossless_packet_test - asan: + static-analysis: working_directory: ~/work docker: - image: ubuntu @@ -67,6 +48,7 @@ jobs: clang cmake git + libbenchmark-dev libconfig-dev libgmock-dev libgtest-dev @@ -76,39 +58,6 @@ jobs: llvm-dev ninja-build pkg-config - - checkout - - run: git submodule update --init --recursive - - run: CC=clang .circleci/cmake-asan - - tsan: - working_directory: ~/work - docker: - - image: ubuntu - - steps: - - run: *apt_install - - checkout - - run: git submodule update --init --recursive - - run: CC=clang .circleci/cmake-tsan - - ubsan: - working_directory: ~/work - docker: - - image: ubuntu - - steps: - - run: *apt_install - - checkout - - run: git submodule update --init --recursive - - run: CC=clang .circleci/cmake-ubsan - - static-analysis: - working_directory: ~/work - docker: - - image: ubuntu - - steps: - - run: *apt_install - run: apt-get install -y --no-install-recommends ca-certificates @@ -145,3 +94,22 @@ jobs: - checkout - run: git submodule update --init --recursive - run: other/analysis/run-cpplint + + cimplefmt: + working_directory: ~/work + machine: { image: ubuntu-2204:current } + + steps: + - checkout + - run: git submodule update --init --recursive + - run: other/docker/cimplefmt/run -u $(find tox* -name "*.[ch]") + + generate-events: + working_directory: ~/work + machine: { image: ubuntu-2204:current } + + steps: + - checkout + - run: git submodule update --init --recursive + - run: other/event_tooling/run + - run: git diff --exit-code diff --git a/external/toxcore/c-toxcore/.cirrus.yml b/external/toxcore/c-toxcore/.cirrus.yml index 5f7bf44..cd54173 100644 --- a/external/toxcore/c-toxcore/.cirrus.yml +++ b/external/toxcore/c-toxcore/.cirrus.yml @@ -9,7 +9,9 @@ bazel-opt_task: - git submodule update --init --recursive - /src/workspace/tools/inject-repo c-toxcore test_all_script: - - cd /src/workspace && bazel test -k + - cd /src/workspace && bazel + --max_idle_secs=5 + test -k --remote_cache=http://$CIRRUS_HTTP_CACHE_HOST --build_tag_filters=-haskell --test_tag_filters=-haskell @@ -27,7 +29,9 @@ bazel-dbg_task: - git submodule update --init --recursive - /src/workspace/tools/inject-repo c-toxcore test_all_script: - - cd /src/workspace && bazel test -k + - cd /src/workspace && bazel + --max_idle_secs=5 + test -k --remote_cache=http://$CIRRUS_HTTP_CACHE_HOST --build_tag_filters=-haskell --test_tag_filters=-haskell @@ -45,7 +49,9 @@ cimple_task: - git submodule update --init --recursive - /src/workspace/tools/inject-repo c-toxcore test_all_script: - - cd /src/workspace && bazel test -k + - cd /src/workspace && bazel + --max_idle_secs=5 + test -k --remote_cache=http://$CIRRUS_HTTP_CACHE_HOST --build_tag_filters=haskell --test_tag_filters=haskell diff --git a/external/toxcore/c-toxcore/.github/workflows/checks.yml b/external/toxcore/c-toxcore/.github/workflows/checks.yml new file mode 100644 index 0000000..f618b9e --- /dev/null +++ b/external/toxcore/c-toxcore/.github/workflows/checks.yml @@ -0,0 +1,12 @@ +name: checks + +on: + pull_request: + branches: [master] + types: [opened, reopened, synchronize, milestoned] + pull_request_target: + branches: [master] + +jobs: + checks: + uses: TokTok/ci-tools/.github/workflows/check-release.yml@master diff --git a/external/toxcore/c-toxcore/.github/workflows/ci.yml b/external/toxcore/c-toxcore/.github/workflows/ci.yml index 46aa57f..99cbe7b 100644 --- a/external/toxcore/c-toxcore/.github/workflows/ci.yml +++ b/external/toxcore/c-toxcore/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: fail-fast: false matrix: tool: [autotools, clang-tidy, compcert, cppcheck, doxygen, goblint, infer, freebsd, misra, modules, pkgsrc, rpm, slimcc, sparse, tcc, tokstyle] - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -34,8 +34,25 @@ jobs: with: file: other/docker/${{ matrix.tool }}/${{ matrix.tool }}.Dockerfile + sanitizer: + strategy: + fail-fast: false + matrix: + sanitizer: [asan, tsan, ubsan] + runs-on: ubuntu-22.04 + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver: docker + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Run sanitizer + run: other/docker/circleci/run "${{ matrix.sanitizer }}" + coverage-linux: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 with: @@ -43,28 +60,8 @@ jobs: - name: Build, test, and upload coverage run: other/docker/coverage/run - generate-events: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - name: Run generate_event_c - run: | - other/event_tooling/run - git diff --exit-code - - cimplefmt: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - name: Run cimplefmt - run: other/docker/cimplefmt/run -u $(find tox* -name "*.[ch]") - build-android: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 with: @@ -111,7 +108,7 @@ jobs: ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 --build-config Debug build-netbsd: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 with: @@ -146,7 +143,7 @@ jobs: ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 build-freebsd: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 with: @@ -183,7 +180,7 @@ jobs: ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 mypy: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 with: diff --git a/external/toxcore/c-toxcore/CHANGELOG.md b/external/toxcore/c-toxcore/CHANGELOG.md index 8bb93bc..36bfb39 100644 --- a/external/toxcore/c-toxcore/CHANGELOG.md +++ b/external/toxcore/c-toxcore/CHANGELOG.md @@ -1,5 +1,35 @@ +## v0.2.20 + +### Merged PRs: + +- [#2788](https://github.com/TokTok/c-toxcore/pull/2788) fix: Add missing free in dht_get_nodes_response event. +- [#2786](https://github.com/TokTok/c-toxcore/pull/2786) cleanup: Fix all `-Wsign-compare` warnings. +- [#2785](https://github.com/TokTok/c-toxcore/pull/2785) fix: wrong comment for closelist +- [#2784](https://github.com/TokTok/c-toxcore/pull/2784) chore: lower cirrus ci timeout drastically +- [#2783](https://github.com/TokTok/c-toxcore/pull/2783) fix: Return an error instead of crashing on nullptr args in NGC. +- [#2782](https://github.com/TokTok/c-toxcore/pull/2782) fix(toxav): pass video bit rate as kbit +- [#2780](https://github.com/TokTok/c-toxcore/pull/2780) chore: Add release-drafter github action. +- [#2779](https://github.com/TokTok/c-toxcore/pull/2779) chore: Use toktok's cmp instead of upstream. +- [#2778](https://github.com/TokTok/c-toxcore/pull/2778) cleanup: Sort apk/apt install commands in Dockerfiles. +- [#2777](https://github.com/TokTok/c-toxcore/pull/2777) chore: Upgrade to FreeBSD 14.1 in cirrus build. +- [#2772](https://github.com/TokTok/c-toxcore/pull/2772) fix: friend_connections leak on allocation failure. +- [#2771](https://github.com/TokTok/c-toxcore/pull/2771) fix: events leak that can occur if allocation fails +- [#2769](https://github.com/TokTok/c-toxcore/pull/2769) chore(ci): new minimum for all android versions is 21 +- [#2768](https://github.com/TokTok/c-toxcore/pull/2768) fix: toxav rtp temp buffer allocation size was too large +- [#2762](https://github.com/TokTok/c-toxcore/pull/2762) chore(cmake): set options changes as cache and with force +- [#2761](https://github.com/TokTok/c-toxcore/pull/2761) chore: Fix CI +- [#2757](https://github.com/TokTok/c-toxcore/pull/2757) fix: Use Opus in the CBR mode +- [#2755](https://github.com/TokTok/c-toxcore/pull/2755) chore: Fix Circle CI build failing +- [#2754](https://github.com/TokTok/c-toxcore/pull/2754) docs(toxav): fix docs of toxav.h +- [#2751](https://github.com/TokTok/c-toxcore/pull/2751) chore(deps): bump golang.org/x/net from 0.17.0 to 0.23.0 in /other/bootstrap_daemon/websocket/websockify +- [#2747](https://github.com/TokTok/c-toxcore/pull/2747) fix: Memory leak in the bootstrap daemon +- [#2745](https://github.com/TokTok/c-toxcore/pull/2745) chore: Fix GitHub actions deprecation warnings +- [#2717](https://github.com/TokTok/c-toxcore/pull/2717) cleanup: Remove useless if clause +- [#2692](https://github.com/TokTok/c-toxcore/pull/2692) refactor: Make tox-bootstrapd use bool instead of int +- [#2651](https://github.com/TokTok/c-toxcore/pull/2651) refactor: Make ToxAV independent of toxcore internals. + ## v0.2.19 ### Merged PRs: @@ -30,6 +60,7 @@ - [#2697](https://github.com/TokTok/c-toxcore/pull/2697) test: Build toxcore on NetBSD (VM). - [#2696](https://github.com/TokTok/c-toxcore/pull/2696) fix: save_compatibility_test failing on big-endian systems - [#2695](https://github.com/TokTok/c-toxcore/pull/2695) fix: Don't serve files from websockify. +- [#2691](https://github.com/TokTok/c-toxcore/pull/2691) chore: Release 0.2.19 - [#2689](https://github.com/TokTok/c-toxcore/pull/2689) fix: Correctly pass extended public keys to group moderation code. - [#2686](https://github.com/TokTok/c-toxcore/pull/2686) chore: Compile libsodium reference implementation with compcert. - [#2685](https://github.com/TokTok/c-toxcore/pull/2685) cleanup: correct a few nullable annotations @@ -252,6 +283,7 @@ - [#2739](https://github.com/TokTok/c-toxcore/issues/2739) Tox_Options.operating_system is not clear about it being an experimental option - [#2734](https://github.com/TokTok/c-toxcore/issues/2734) error compiling on fedora - [#2649](https://github.com/TokTok/c-toxcore/issues/2649) create_extended_keypair should use Random and be made deterministic for fuzzing +- [#2462](https://github.com/TokTok/c-toxcore/issues/2462) Fix code scanning alert - Uncontrolled data used in path expression - [#2358](https://github.com/TokTok/c-toxcore/issues/2358) resolve_bootstrap_node assert hit - [#2352](https://github.com/TokTok/c-toxcore/issues/2352) SEGV after infinite loop retrying proxy_socks5_read_connection_response - [#2335](https://github.com/TokTok/c-toxcore/issues/2335) ipv6 disabled on kernel cmdline disrupts Tox = most tests fail diff --git a/external/toxcore/c-toxcore/CMakeLists.txt b/external/toxcore/c-toxcore/CMakeLists.txt index 5aebd17..4d6cf22 100644 --- a/external/toxcore/c-toxcore/CMakeLists.txt +++ b/external/toxcore/c-toxcore/CMakeLists.txt @@ -44,7 +44,7 @@ set_source_files_properties( # versions in a synchronised way. set(PROJECT_VERSION_MAJOR "0") set(PROJECT_VERSION_MINOR "2") -set(PROJECT_VERSION_PATCH "19") +set(PROJECT_VERSION_PATCH "20") set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") # set .so library version / following libtool scheme @@ -323,6 +323,8 @@ set(toxcore_SOURCES toxcore/ping.h toxcore/shared_key_cache.c toxcore/shared_key_cache.h + toxcore/sort.c + toxcore/sort.h toxcore/state.c toxcore/state.h toxcore/TCP_client.c @@ -352,7 +354,9 @@ set(toxcore_SOURCES toxcore/tox_unpack.h toxcore/util.c toxcore/util.h) -if(TARGET unofficial-sodium::sodium) +if(TARGET libsodium::libsodium) + set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} libsodium::libsodium) +elseif(TARGET unofficial-sodium::sodium) set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} unofficial-sodium::sodium) else() set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} ${LIBSODIUM_LIBRARIES}) @@ -399,7 +403,9 @@ if(BUILD_TOXAV) set(toxcore_API_HEADERS ${toxcore_API_HEADERS} ${toxcore_SOURCE_DIR}/toxav/toxav.h^toxav) - if(MSVC) + if(TARGET Opus::opus AND TARGET libvpx::libvpx) + set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} Opus::opus libvpx::libvpx) + elseif(TARGET PkgConfig::OPUS AND TARGET PkgConfig::VPX) set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} PkgConfig::OPUS PkgConfig::VPX) else() set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} ${OPUS_LIBRARIES} ${VPX_LIBRARIES}) @@ -452,7 +458,9 @@ if(SOCKET_LIBRARIES) set(toxcore_PKGCONFIG_LIBS ${toxcore_PKGCONFIG_LIBS} -lsocket) endif() -if(TARGET PThreads4W::PThreads4W) +if(TARGET pthreads4w::pthreads4w) + set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} pthreads4w::pthreads4w) +elseif(TARGET PThreads4W::PThreads4W) set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} PThreads4W::PThreads4W) elseif(TARGET Threads::Threads) set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} Threads::Threads) @@ -510,17 +518,19 @@ install_module(toxcore DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/tox) # ################################################################################ -add_library(test_util STATIC - toxcore/DHT_test_util.cc - toxcore/DHT_test_util.hh - toxcore/crypto_core_test_util.cc - toxcore/crypto_core_test_util.hh - toxcore/mem_test_util.cc - toxcore/mem_test_util.hh - toxcore/network_test_util.cc - toxcore/network_test_util.hh - toxcore/test_util.cc - toxcore/test_util.hh) +if(UNITTEST) + add_library(test_util STATIC + toxcore/DHT_test_util.cc + toxcore/DHT_test_util.hh + toxcore/crypto_core_test_util.cc + toxcore/crypto_core_test_util.hh + toxcore/mem_test_util.cc + toxcore/mem_test_util.hh + toxcore/network_test_util.cc + toxcore/network_test_util.hh + toxcore/test_util.cc + toxcore/test_util.hh) +endif() function(unit_test subdir target) add_executable(unit_${target}_test ${subdir}/${target}_test.cc) @@ -530,6 +540,13 @@ function(unit_test subdir target) else() target_link_libraries(unit_${target}_test PRIVATE toxcore_shared) endif() + if(TARGET pthreads4w::pthreads4w) + target_link_libraries(unit_${target}_test PRIVATE pthreads4w::pthreads4w) + elseif(TARGET PThreads4W::PThreads4W) + target_link_libraries(unit_${target}_test PRIVATE PThreads4W::PThreads4W) + elseif(TARGET Threads::Threads) + target_link_libraries(unit_${target}_test PRIVATE Threads::Threads) + endif() target_link_libraries(unit_${target}_test PRIVATE GTest::gtest GTest::gtest_main GTest::gmock) set_target_properties(unit_${target}_test PROPERTIES COMPILE_FLAGS "${TEST_CXX_FLAGS}") add_test(NAME ${target} COMMAND ${CROSSCOMPILING_EMULATOR} unit_${target}_test) @@ -583,10 +600,14 @@ if(DHT_BOOTSTRAP) target_link_libraries(DHT_bootstrap PRIVATE toxcore_shared) endif() target_link_libraries(DHT_bootstrap PRIVATE misc_tools) - if(TARGET unofficial-sodium::sodium) + if(TARGET libsodium::libsodium) + target_link_libraries(DHT_bootstrap PRIVATE libsodium::libsodium) + elseif(TARGET unofficial-sodium::sodium) target_link_libraries(DHT_bootstrap PRIVATE unofficial-sodium::sodium) endif() - if(TARGET PThreads4W::PThreads4W) + if(TARGET pthreads4w::pthreads4w) + target_link_libraries(DHT_bootstrap PRIVATE pthreads4w::pthreads4w) + elseif(TARGET PThreads4W::PThreads4W) target_link_libraries(DHT_bootstrap PRIVATE PThreads4W::PThreads4W) elseif(TARGET Threads::Threads) target_link_libraries(DHT_bootstrap PRIVATE Threads::Threads) diff --git a/external/toxcore/c-toxcore/CMakePresets.json b/external/toxcore/c-toxcore/CMakePresets.json index 45caa10..2a8ebf9 100644 --- a/external/toxcore/c-toxcore/CMakePresets.json +++ b/external/toxcore/c-toxcore/CMakePresets.json @@ -7,6 +7,7 @@ "cacheVariables": { "ENABLE_SHARED": true, "ENABLE_STATIC": true, + "FLAT_OUTPUT_STRUCTURE": true, "AUTOTEST": true, "BUILD_MISC_TESTS": true, "BOOTSTRAP_DAEMON": false, @@ -17,5 +18,19 @@ "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" } } + ], + "buildPresets": [ + { + "name": "windows-default", + "configurePreset": "windows-default", + "description": "Build for Windows using default settings" + } + ], + "testPresets": [ + { + "name": "windows-default", + "configurePreset": "windows-default", + "description": "Run tests for Windows using default settings" + } ] } diff --git a/external/toxcore/c-toxcore/auto_tests/BUILD.bazel b/external/toxcore/c-toxcore/auto_tests/BUILD.bazel index 17606ca..24a3add 100644 --- a/external/toxcore/c-toxcore/auto_tests/BUILD.bazel +++ b/external/toxcore/c-toxcore/auto_tests/BUILD.bazel @@ -78,6 +78,7 @@ extra_data = { "//c-toxcore/toxcore:tox", "//c-toxcore/toxcore:tox_dispatch", "//c-toxcore/toxcore:tox_events", + "//c-toxcore/toxcore:tox_unpack", "//c-toxcore/toxcore:util", "//c-toxcore/toxencryptsave", "@libsodium", diff --git a/external/toxcore/c-toxcore/auto_tests/CMakeLists.txt b/external/toxcore/c-toxcore/auto_tests/CMakeLists.txt index d891ba1..8413e1d 100644 --- a/external/toxcore/c-toxcore/auto_tests/CMakeLists.txt +++ b/external/toxcore/c-toxcore/auto_tests/CMakeLists.txt @@ -9,7 +9,9 @@ if(TARGET toxcore_static) else() target_link_libraries(auto_test_support PRIVATE toxcore_shared) endif() -if(TARGET PThreads4W::PThreads4W) +if(TARGET pthreads4w::pthreads4w) + target_link_libraries(auto_test_support PRIVATE pthreads4w::pthreads4w) +elseif(TARGET PThreads4W::PThreads4W) target_link_libraries(auto_test_support PRIVATE PThreads4W::PThreads4W) elseif(TARGET Threads::Threads) target_link_libraries(auto_test_support PRIVATE Threads::Threads) @@ -23,7 +25,9 @@ function(auto_test target) else() target_link_libraries(auto_${target}_test PRIVATE toxcore_shared) endif() - if(TARGET PThreads4W::PThreads4W) + if(TARGET pthreads4w::pthreads4w) + target_link_libraries(auto_${target}_test PRIVATE pthreads4w::pthreads4w) + elseif(TARGET PThreads4W::PThreads4W) target_link_libraries(auto_${target}_test PRIVATE PThreads4W::PThreads4W) elseif(TARGET Threads::Threads) target_link_libraries(auto_${target}_test PRIVATE Threads::Threads) @@ -98,7 +102,10 @@ if(BUILD_TOXAV) auto_test(toxav_basic) auto_test(toxav_many) - if(MSVC) + if(TARGET libvpx::libvpx) + target_link_libraries(auto_toxav_basic_test PRIVATE libvpx::libvpx) + target_link_libraries(auto_toxav_many_test PRIVATE libvpx::libvpx) + elseif(TARGET PkgConfig::VPX) target_link_libraries(auto_toxav_basic_test PRIVATE PkgConfig::VPX) target_link_libraries(auto_toxav_many_test PRIVATE PkgConfig::VPX) else() diff --git a/external/toxcore/c-toxcore/auto_tests/TCP_test.c b/external/toxcore/c-toxcore/auto_tests/TCP_test.c index c4ea79b..b59fa94 100644 --- a/external/toxcore/c-toxcore/auto_tests/TCP_test.c +++ b/external/toxcore/c-toxcore/auto_tests/TCP_test.c @@ -53,7 +53,7 @@ static void test_basic(void) ck_assert(mem != nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); - Logger *logger = logger_new(); + Logger *logger = logger_new(mem); logger_callback_log(logger, print_debug_logger, nullptr, nullptr); // Attempt to create a new TCP_Server instance. @@ -74,7 +74,7 @@ static void test_basic(void) for (uint8_t i = 0; i < NUM_PORTS; i++) { sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP); localhost.port = net_htons(ports[i]); - bool ret = net_connect(mem, logger, sock, &localhost); + bool ret = net_connect(ns, mem, logger, sock, &localhost); ck_assert_msg(ret, "Failed to connect to created TCP relay server on port %d (%d).", ports[i], errno); // Leave open one connection for the next test. @@ -102,7 +102,7 @@ static void test_basic(void) random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE); // Encrypting handshake - int ret = encrypt_data(self_public_key, f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain, + int ret = encrypt_data(mem, self_public_key, f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain, TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); ck_assert_msg(ret == TCP_CLIENT_HANDSHAKE_SIZE - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), "encrypt_data() call failed."); @@ -128,7 +128,7 @@ static void test_basic(void) uint8_t response_plain[TCP_HANDSHAKE_PLAIN_SIZE]; ck_assert_msg(net_recv(ns, logger, sock, response, TCP_SERVER_HANDSHAKE_SIZE, &localhost) == TCP_SERVER_HANDSHAKE_SIZE, "Could/did not receive a server response to the initial handshake."); - ret = decrypt_data(self_public_key, f_secret_key, response, response + CRYPTO_NONCE_SIZE, + ret = decrypt_data(mem, self_public_key, f_secret_key, response, response + CRYPTO_NONCE_SIZE, TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, response_plain); ck_assert_msg(ret == TCP_HANDSHAKE_PLAIN_SIZE, "Failed to decrypt handshake response."); uint8_t f_nonce_r[CRYPTO_NONCE_SIZE]; @@ -143,7 +143,7 @@ static void test_basic(void) uint8_t r_req[2 + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE]; uint16_t size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE; size = net_htons(size); - encrypt_data_symmetric(f_shared_key, f_nonce, r_req_p, 1 + CRYPTO_PUBLIC_KEY_SIZE, r_req + 2); + encrypt_data_symmetric(mem, f_shared_key, f_nonce, r_req_p, 1 + CRYPTO_PUBLIC_KEY_SIZE, r_req + 2); increment_nonce(f_nonce); memcpy(r_req, &size, 2); @@ -174,7 +174,7 @@ static void test_basic(void) "Wrong packet size for request response."); uint8_t packet_resp_plain[4096]; - ret = decrypt_data_symmetric(f_shared_key, f_nonce_r, packet_resp + 2, recv_data_len - 2, packet_resp_plain); + ret = decrypt_data_symmetric(mem, f_shared_key, f_nonce_r, packet_resp + 2, recv_data_len - 2, packet_resp_plain); ck_assert_msg(ret != -1, "Failed to decrypt the TCP server's response."); increment_nonce(f_nonce_r); @@ -213,7 +213,7 @@ static struct sec_TCP_con *new_tcp_con(const Logger *logger, const Memory *mem, localhost.ip = get_loopback(); localhost.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); - bool ok = net_connect(mem, logger, sock, &localhost); + bool ok = net_connect(ns, mem, logger, sock, &localhost); ck_assert_msg(ok, "Failed to connect to the test TCP relay server."); uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; @@ -228,7 +228,7 @@ static struct sec_TCP_con *new_tcp_con(const Logger *logger, const Memory *mem, memcpy(handshake, sec_c->public_key, CRYPTO_PUBLIC_KEY_SIZE); random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE); - int ret = encrypt_data(tcp_server_public_key(tcp_s), f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain, + int ret = encrypt_data(mem, tcp_server_public_key(tcp_s), f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain, TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); ck_assert_msg(ret == TCP_CLIENT_HANDSHAKE_SIZE - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), "Failed to encrypt the outgoing handshake."); @@ -248,7 +248,7 @@ static struct sec_TCP_con *new_tcp_con(const Logger *logger, const Memory *mem, uint8_t response_plain[TCP_HANDSHAKE_PLAIN_SIZE]; ck_assert_msg(net_recv(sec_c->ns, logger, sock, response, TCP_SERVER_HANDSHAKE_SIZE, &localhost) == TCP_SERVER_HANDSHAKE_SIZE, "Failed to receive server handshake response."); - ret = decrypt_data(tcp_server_public_key(tcp_s), f_secret_key, response, response + CRYPTO_NONCE_SIZE, + ret = decrypt_data(mem, tcp_server_public_key(tcp_s), f_secret_key, response, response + CRYPTO_NONCE_SIZE, TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, response_plain); ck_assert_msg(ret == TCP_HANDSHAKE_PLAIN_SIZE, "Failed to decrypt server handshake response."); encrypt_precompute(response_plain, t_secret_key, sec_c->shared_key); @@ -271,7 +271,7 @@ static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE); memcpy(packet, &c_length, sizeof(uint16_t)); - int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); + int len = encrypt_data_symmetric(con->mem, con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); if ((unsigned int)len != (packet_size - sizeof(uint16_t))) { return -1; @@ -296,7 +296,7 @@ static int read_packet_sec_tcp(const Logger *logger, struct sec_TCP_con *con, ui int rlen = net_recv(con->ns, logger, con->sock, data, length, &localhost); ck_assert_msg(rlen == length, "Did not receive packet of correct length. Wanted %i, instead got %i", length, rlen); - rlen = decrypt_data_symmetric(con->shared_key, con->recv_nonce, data + 2, length - 2, data); + rlen = decrypt_data_symmetric(con->mem, con->shared_key, con->recv_nonce, data + 2, length - 2, data); ck_assert_msg(rlen != -1, "Failed to decrypt a received packet from the Relay server."); increment_nonce(con->recv_nonce); return rlen; @@ -312,7 +312,7 @@ static void test_some(void) ck_assert(mem != nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); - Logger *logger = logger_new(); + Logger *logger = logger_new(mem); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; @@ -506,7 +506,7 @@ static void test_client(void) const Memory *mem = os_memory(); ck_assert(mem != nullptr); - Logger *logger = logger_new(); + Logger *logger = logger_new(mem); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -643,7 +643,7 @@ static void test_client_invalid(void) ck_assert(mem != nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); - Logger *logger = logger_new(); + Logger *logger = logger_new(mem); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; @@ -721,7 +721,7 @@ static void test_tcp_connection(void) ck_assert(mem != nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); - Logger *logger = logger_new(); + Logger *logger = logger_new(mem); tcp_data_callback_called = 0; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -834,7 +834,7 @@ static void test_tcp_connection2(void) ck_assert(mem != nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); - Logger *logger = logger_new(); + Logger *logger = logger_new(mem); tcp_oobdata_callback_called = 0; tcp_data_callback_called = 0; diff --git a/external/toxcore/c-toxcore/auto_tests/announce_test.c b/external/toxcore/c-toxcore/auto_tests/announce_test.c index c4f080d..ef93095 100644 --- a/external/toxcore/c-toxcore/auto_tests/announce_test.c +++ b/external/toxcore/c-toxcore/auto_tests/announce_test.c @@ -57,7 +57,7 @@ static void test_store_data(void) const Memory *mem = os_memory(); ck_assert(mem != nullptr); - Logger *log = logger_new(); + Logger *log = logger_new(mem); ck_assert(log != nullptr); logger_callback_log(log, print_debug_logger, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); diff --git a/external/toxcore/c-toxcore/auto_tests/crypto_test.c b/external/toxcore/c-toxcore/auto_tests/crypto_test.c index 83f8c52..75d94ea 100644 --- a/external/toxcore/c-toxcore/auto_tests/crypto_test.c +++ b/external/toxcore/c-toxcore/auto_tests/crypto_test.c @@ -80,6 +80,9 @@ static const uint8_t test_c[147] = { static void test_known(void) { + const Memory *mem = os_memory(); + ck_assert(mem != nullptr); + uint8_t c[147]; uint8_t m[131]; @@ -88,12 +91,12 @@ static void test_known(void) ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - const uint16_t clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); + const uint16_t clen = encrypt_data(mem, bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - const uint16_t mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); + const uint16_t mlen = decrypt_data(mem, bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); @@ -101,6 +104,9 @@ static void test_known(void) static void test_fast_known(void) { + const Memory *mem = os_memory(); + ck_assert(mem != nullptr); + uint8_t k[CRYPTO_SHARED_KEY_SIZE]; uint8_t c[147]; uint8_t m[131]; @@ -112,12 +118,12 @@ static void test_fast_known(void) ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - const uint16_t clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); + const uint16_t clen = encrypt_data_symmetric(mem, k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - const uint16_t mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); + const uint16_t mlen = decrypt_data_symmetric(mem, k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); @@ -125,6 +131,8 @@ static void test_fast_known(void) static void test_endtoend(void) { + const Memory *mem = os_memory(); + ck_assert(mem != nullptr); const Random *rng = os_random(); ck_assert(rng != nullptr); @@ -166,10 +174,10 @@ static void test_endtoend(void) ck_assert_msg(memcmp(k1, k2, CRYPTO_SHARED_KEY_SIZE) == 0, "encrypt_precompute: bad"); //Encrypt all four ways - const uint16_t c1len = encrypt_data(pk2, sk1, n, m, mlen, c1); - const uint16_t c2len = encrypt_data(pk1, sk2, n, m, mlen, c2); - const uint16_t c3len = encrypt_data_symmetric(k1, n, m, mlen, c3); - const uint16_t c4len = encrypt_data_symmetric(k2, n, m, mlen, c4); + const uint16_t c1len = encrypt_data(mem, pk2, sk1, n, m, mlen, c1); + const uint16_t c2len = encrypt_data(mem, pk1, sk2, n, m, mlen, c2); + const uint16_t c3len = encrypt_data_symmetric(mem, k1, n, m, mlen, c3); + const uint16_t c4len = encrypt_data_symmetric(mem, k2, n, m, mlen, c4); ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ"); ck_assert_msg(c1len == mlen + (uint16_t)CRYPTO_MAC_SIZE, "wrong cyphertext length"); @@ -177,10 +185,10 @@ static void test_endtoend(void) && memcmp(c1, c4, c1len) == 0, "crypertexts differ"); //Decrypt all four ways - const uint16_t m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1); - const uint16_t m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2); - const uint16_t m3len = decrypt_data_symmetric(k1, n, c1, c1len, m3); - const uint16_t m4len = decrypt_data_symmetric(k2, n, c1, c1len, m4); + const uint16_t m1len = decrypt_data(mem, pk2, sk1, n, c1, c1len, m1); + const uint16_t m2len = decrypt_data(mem, pk1, sk2, n, c1, c1len, m2); + const uint16_t m3len = decrypt_data_symmetric(mem, k1, n, c1, c1len, m3); + const uint16_t m4len = decrypt_data_symmetric(mem, k2, n, c1, c1len, m4); ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ"); ck_assert_msg(m1len == mlen, "wrong decrypted text length"); @@ -192,6 +200,8 @@ static void test_endtoend(void) static void test_large_data(void) { + const Memory *mem = os_memory(); + ck_assert(mem != nullptr); const Random *rng = os_random(); ck_assert(rng != nullptr); uint8_t k[CRYPTO_SHARED_KEY_SIZE]; @@ -216,13 +226,13 @@ static void test_large_data(void) //Generate key rand_bytes(rng, k, CRYPTO_SHARED_KEY_SIZE); - const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1); - const uint16_t c2len = encrypt_data_symmetric(k, n, m2, m2_size, c2); + const uint16_t c1len = encrypt_data_symmetric(mem, k, n, m1, m1_size, c1); + const uint16_t c2len = encrypt_data_symmetric(mem, k, n, m2, m2_size, c2); ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt"); ck_assert_msg(c2len == m2_size + CRYPTO_MAC_SIZE, "could not encrypt"); - const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); + const uint16_t m1plen = decrypt_data_symmetric(mem, k, n, c1, c1len, m1prime); ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); @@ -236,6 +246,8 @@ static void test_large_data(void) static void test_large_data_symmetric(void) { + const Memory *mem = os_memory(); + ck_assert(mem != nullptr); const Random *rng = os_random(); ck_assert(rng != nullptr); uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE]; @@ -256,10 +268,10 @@ static void test_large_data_symmetric(void) //Generate key new_symmetric_key(rng, k); - const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1); + const uint16_t c1len = encrypt_data_symmetric(mem, k, n, m1, m1_size, c1); ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt data"); - const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); + const uint16_t m1plen = decrypt_data_symmetric(mem, k, n, c1, c1len, m1prime); ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); @@ -271,6 +283,8 @@ static void test_large_data_symmetric(void) static void test_very_large_data(void) { + const Memory *mem = os_memory(); + ck_assert(mem != nullptr); const Random *rng = os_random(); ck_assert(rng != nullptr); @@ -287,7 +301,9 @@ static void test_very_large_data(void) ck_assert(plain != nullptr); ck_assert(encrypted != nullptr); - encrypt_data(pk, sk, nonce, plain, plain_size, encrypted); + memset(plain, 0, plain_size); + + encrypt_data(mem, pk, sk, nonce, plain, plain_size, encrypted); free(encrypted); free(plain); diff --git a/external/toxcore/c-toxcore/auto_tests/encryptsave_test.c b/external/toxcore/c-toxcore/auto_tests/encryptsave_test.c index e433e41..3573337 100644 --- a/external/toxcore/c-toxcore/auto_tests/encryptsave_test.c +++ b/external/toxcore/c-toxcore/auto_tests/encryptsave_test.c @@ -3,8 +3,6 @@ #include #include -#include - #include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" #include "../toxcore/crypto_core.h" @@ -14,13 +12,10 @@ #include "check_compat.h" static unsigned char test_salt[TOX_PASS_SALT_LENGTH] = {0xB1, 0xC2, 0x09, 0xEE, 0x50, 0x6C, 0xF0, 0x20, 0xC4, 0xD6, 0xEB, 0xC0, 0x44, 0x51, 0x3B, 0x60, 0x4B, 0x39, 0x4A, 0xCF, 0x09, 0x53, 0x4F, 0xEA, 0x08, 0x41, 0xFA, 0xCA, 0x66, 0xD2, 0x68, 0x7F}; -static unsigned char known_key[TOX_PASS_KEY_LENGTH] = {0x29, 0x36, 0x1c, 0x9e, 0x65, 0xbb, 0x46, 0x8b, 0xde, 0xa1, 0xac, 0xf, 0xd5, 0x11, 0x81, 0xc8, 0x29, 0x28, 0x17, 0x23, 0xa6, 0xc3, 0x6b, 0x77, 0x2e, 0xd7, 0xd3, 0x10, 0xeb, 0xd2, 0xf7, 0xc8}; +static unsigned char known_key[CRYPTO_SHARED_KEY_SIZE] = {0x7a, 0xfa, 0x95, 0x45, 0x36, 0x8a, 0xa2, 0x5c, 0x40, 0xfd, 0xc0, 0xe2, 0x35, 0x8, 0x7, 0x88, 0xfa, 0xf9, 0x37, 0x86, 0xeb, 0xff, 0x50, 0x4f, 0x3, 0xe2, 0xf6, 0xd9, 0xef, 0x9, 0x17, 0x1}; static const char *pw = "hunter2"; static unsigned int pwlen = 7; -static unsigned char known_key2[CRYPTO_SHARED_KEY_SIZE] = {0x7a, 0xfa, 0x95, 0x45, 0x36, 0x8a, 0xa2, 0x5c, 0x40, 0xfd, 0xc0, 0xe2, 0x35, 0x8, 0x7, 0x88, 0xfa, 0xf9, 0x37, 0x86, 0xeb, 0xff, 0x50, 0x4f, 0x3, 0xe2, 0xf6, 0xd9, 0xef, 0x9, 0x17, 0x1}; -// same as above, except standard opslimit instead of extra ops limit for test_known_kdf, and hash pw before kdf for compat - /* cause I'm shameless */ static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) { @@ -33,20 +28,6 @@ static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8 } } -static void test_known_kdf(void) -{ - unsigned char out[CRYPTO_SHARED_KEY_SIZE]; - int16_t res = crypto_pwhash_scryptsalsa208sha256(out, - CRYPTO_SHARED_KEY_SIZE, - pw, - pwlen, - test_salt, - crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 8, - crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE); - ck_assert_msg(res != -1, "crypto function failed"); - ck_assert_msg(memcmp(out, known_key, CRYPTO_SHARED_KEY_SIZE) == 0, "derived key is wrong"); -} - static void test_save_friend(void) { Tox *tox1 = tox_new_log(nullptr, nullptr, nullptr); @@ -101,7 +82,7 @@ static void test_save_friend(void) Tox_Pass_Key *key = tox_pass_key_derive((const uint8_t *)"123qweasdzxc", 12, &keyerr); ck_assert_msg(key != nullptr, "pass key allocation failure"); memcpy((uint8_t *)key, test_salt, TOX_PASS_SALT_LENGTH); - memcpy((uint8_t *)key + TOX_PASS_SALT_LENGTH, known_key2, TOX_PASS_KEY_LENGTH); + memcpy((uint8_t *)key + TOX_PASS_SALT_LENGTH, known_key, TOX_PASS_KEY_LENGTH); size2 = size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH; uint8_t *encdata2 = (uint8_t *)malloc(size2); ck_assert(encdata2 != nullptr); @@ -224,7 +205,6 @@ static void test_keys(void) int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); - test_known_kdf(); test_save_friend(); test_keys(); diff --git a/external/toxcore/c-toxcore/auto_tests/forwarding_test.c b/external/toxcore/c-toxcore/auto_tests/forwarding_test.c index 75e330a..3ba85ed 100644 --- a/external/toxcore/c-toxcore/auto_tests/forwarding_test.c +++ b/external/toxcore/c-toxcore/auto_tests/forwarding_test.c @@ -112,7 +112,7 @@ static Forwarding_Subtox *new_forwarding_subtox(const Memory *mem, bool no_udp, Forwarding_Subtox *subtox = (Forwarding_Subtox *)calloc(1, sizeof(Forwarding_Subtox)); ck_assert(subtox != nullptr); - subtox->log = logger_new(); + subtox->log = logger_new(mem); ck_assert(subtox->log != nullptr); logger_callback_log(subtox->log, print_debug_logger, nullptr, index); subtox->mono_time = mono_time_new(mem, nullptr, nullptr); diff --git a/external/toxcore/c-toxcore/auto_tests/friend_request_test.c b/external/toxcore/c-toxcore/auto_tests/friend_request_test.c index 7dfc5bf..18bc5d6 100644 --- a/external/toxcore/c-toxcore/auto_tests/friend_request_test.c +++ b/external/toxcore/c-toxcore/auto_tests/friend_request_test.c @@ -10,44 +10,57 @@ #include "../toxcore/tox.h" #include "../toxcore/util.h" #include "../testing/misc_tools.h" + #include "auto_test_support.h" #include "check_compat.h" -#define FR_MESSAGE "Gentoo" +#define REQUEST_MESSAGE "Hello, I would like to be your friend. Please respond." -static void accept_friend_request(const Tox_Event_Friend_Request *event, - void *userdata) +typedef struct Callback_Data { + Tox *tox1; // request sender + Tox *tox2; // request receiver + uint8_t message[TOX_MAX_FRIEND_REQUEST_LENGTH]; + uint16_t length; +} Callback_Data; + +static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata) { - Tox *state_tox = (Tox *)userdata; + Callback_Data *cb_data = (Callback_Data *)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, + ck_assert_msg(length == cb_data->length && memcmp(cb_data->message, data, cb_data->length) == 0, "unexpected friend request message"); - tox_friend_add_norequest(state_tox, public_key, nullptr); + + fprintf(stderr, "Tox2 accepts friend request.\n"); + + Tox_Err_Friend_Add err; + tox_friend_add_norequest(cb_data->tox2, public_key, &err); + + ck_assert_msg(err == TOX_ERR_FRIEND_ADD_OK, "tox_friend_add_norequest failed: %d", err); } -static void iterate2_wait(const Tox_Dispatch *dispatch, Tox *tox1, Tox *tox2) +static void iterate2_wait(const Tox_Dispatch *dispatch, Callback_Data *cb_data) { Tox_Err_Events_Iterate err; Tox_Events *events; - events = tox_events_iterate(tox1, true, &err); + events = tox_events_iterate(cb_data->tox1, true, &err); ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); - tox_dispatch_invoke(dispatch, events, tox1); + tox_dispatch_invoke(dispatch, events, cb_data); tox_events_free(events); - events = tox_events_iterate(tox2, true, &err); + events = tox_events_iterate(cb_data->tox2, true, &err); ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); - tox_dispatch_invoke(dispatch, events, tox2); + tox_dispatch_invoke(dispatch, events, cb_data); tox_events_free(events); c_sleep(ITERATION_INTERVAL); } -static void test_friend_request(void) +static void test_friend_request(const uint8_t *message, uint16_t length) { printf("Initialising 2 toxes.\n"); uint32_t index[] = { 1, 2 }; @@ -60,7 +73,7 @@ static void test_friend_request(void) tox_events_init(tox1); tox_events_init(tox2); - printf("Bootstrapping tox2 off tox1.\n"); + printf("Bootstrapping Tox2 off Tox1.\n"); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(tox1, dht_key); const uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr); @@ -70,25 +83,36 @@ static void test_friend_request(void) Tox_Dispatch *dispatch = tox_dispatch_new(nullptr); ck_assert(dispatch != nullptr); + Callback_Data cb_data = {nullptr}; + cb_data.tox1 = tox1; + cb_data.tox2 = tox2; + + ck_assert(length <= sizeof(cb_data.message)); + memcpy(cb_data.message, message, length); + cb_data.length = length; + do { - iterate2_wait(dispatch, tox1, tox2); + iterate2_wait(dispatch, &cb_data); } while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE || tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE); printf("Toxes are online, took %lu seconds.\n", (unsigned long)(time(nullptr) - cur_time)); const time_t con_time = time(nullptr); - printf("Tox1 adds tox2 as friend, tox2 accepts.\n"); + printf("Tox1 adds Tox2 as friend. Waiting for Tox2 to accept.\n"); tox_events_callback_friend_request(dispatch, accept_friend_request); uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(tox2, address); - const uint32_t test = tox_friend_add(tox1, address, (const uint8_t *)FR_MESSAGE, sizeof(FR_MESSAGE), nullptr); + Tox_Err_Friend_Add err; + const uint32_t test = tox_friend_add(tox1, address, message, length, &err); + + ck_assert_msg(err == TOX_ERR_FRIEND_ADD_OK, "tox_friend_add failed: %d", err); ck_assert_msg(test == 0, "failed to add friend error code: %u", test); do { - iterate2_wait(dispatch, tox1, tox2); + iterate2_wait(dispatch, &cb_data); } while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP || tox_friend_get_connection_status(tox2, 0, nullptr) != TOX_CONNECTION_UDP); @@ -104,6 +128,20 @@ int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); - test_friend_request(); + fprintf(stderr, "Testing friend request with the smallest allowed message length.\n"); + test_friend_request((const uint8_t *)"a", 1); + + fprintf(stderr, "Testing friend request with an average sized message length.\n"); + test_friend_request((const uint8_t *)REQUEST_MESSAGE, sizeof(REQUEST_MESSAGE) - 1); + + uint8_t long_message[TOX_MAX_FRIEND_REQUEST_LENGTH]; + + for (uint16_t i = 0; i < sizeof(long_message); ++i) { + long_message[i] = 'a'; + } + + fprintf(stderr, "Testing friend request with the largest allowed message length.\n"); + test_friend_request(long_message, sizeof(long_message)); + return 0; } diff --git a/external/toxcore/c-toxcore/auto_tests/network_test.c b/external/toxcore/c-toxcore/auto_tests/network_test.c index 76cb94a..a2bc301 100644 --- a/external/toxcore/c-toxcore/auto_tests/network_test.c +++ b/external/toxcore/c-toxcore/auto_tests/network_test.c @@ -23,12 +23,15 @@ static void test_addr_resolv_localhost(void) const Network *ns = os_network(); ck_assert(ns != nullptr); + const Memory *mem = os_memory(); + ck_assert(mem != nullptr); + const char localhost[] = "localhost"; IP ip; ip_init(&ip, 0); // ipv6enabled = 0 - bool res = addr_resolve_or_parse_ip(ns, localhost, &ip, nullptr); + bool res = addr_resolve_or_parse_ip(ns, mem, localhost, &ip, nullptr, true); int error = net_error(); char *strerror = net_new_strerror(error); @@ -42,14 +45,14 @@ static void test_addr_resolv_localhost(void) net_ip_ntoa(&ip, &ip_str)); ip_init(&ip, 1); // ipv6enabled = 1 - res = addr_resolve_or_parse_ip(ns, localhost, &ip, nullptr); + res = addr_resolve_or_parse_ip(ns, mem, localhost, &ip, nullptr, true); #if USE_IPV6 int localhost_split = 0; if (!net_family_is_ipv6(ip.family)) { - res = addr_resolve_or_parse_ip(ns, "ip6-localhost", &ip, nullptr); + res = addr_resolve_or_parse_ip(ns, mem, "ip6-localhost", &ip, nullptr, true); localhost_split = 1; } @@ -75,7 +78,7 @@ static void test_addr_resolv_localhost(void) ip.family = net_family_unspec(); IP extra; ip_reset(&extra); - res = addr_resolve_or_parse_ip(ns, localhost, &ip, &extra); + res = addr_resolve_or_parse_ip(ns, mem, localhost, &ip, &extra, true); error = net_error(); strerror = net_new_strerror(error); ck_assert_msg(res, "Resolver failed: %d, %s", error, strerror); diff --git a/external/toxcore/c-toxcore/auto_tests/onion_test.c b/external/toxcore/c-toxcore/auto_tests/onion_test.c index 3a81df4..b73ffbd 100644 --- a/external/toxcore/c-toxcore/auto_tests/onion_test.c +++ b/external/toxcore/c-toxcore/auto_tests/onion_test.c @@ -109,7 +109,7 @@ static int handle_test_3(void *object, const IP_Port *source, const uint8_t *pac #if 0 print_client_id(packet, length); #endif - int len = decrypt_data(test_3_pub_key, dht_get_self_secret_key(onion->dht), + int len = decrypt_data(onion->mem, test_3_pub_key, dht_get_self_secret_key(onion->dht), packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE, 2 + CRYPTO_SHA256_SIZE + CRYPTO_MAC_SIZE, plain); @@ -144,7 +144,7 @@ static int handle_test_3_old(void *object, const IP_Port *source, const uint8_t #if 0 print_client_id(packet, length); #endif - int len = decrypt_data(test_3_pub_key, dht_get_self_secret_key(onion->dht), + int len = decrypt_data(onion->mem, test_3_pub_key, dht_get_self_secret_key(onion->dht), packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE, 1 + CRYPTO_SHA256_SIZE + CRYPTO_MAC_SIZE, plain); @@ -182,7 +182,7 @@ static int handle_test_4(void *object, const IP_Port *source, const uint8_t *pac return 1; } - int len = decrypt_data(packet + 1 + CRYPTO_NONCE_SIZE, dht_get_self_secret_key(onion->dht), packet + 1, + int len = decrypt_data(onion->mem, packet + 1 + CRYPTO_NONCE_SIZE, dht_get_self_secret_key(onion->dht), packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, sizeof("Install gentoo") + CRYPTO_MAC_SIZE, plain); if (len == -1) { @@ -202,10 +202,10 @@ static int handle_test_4(void *object, const IP_Port *source, const uint8_t *pac * Use Onion_Path path to send data of length to dest. * Maximum length of data is ONION_MAX_DATA_SIZE. */ -static void send_onion_packet(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length) +static void send_onion_packet(const Networking_Core *net, const Memory *mem, const Random *rng, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length) { uint8_t packet[ONION_MAX_PACKET_SIZE]; - const int len = create_onion_packet(rng, packet, sizeof(packet), path, dest, data, length); + const int len = create_onion_packet(mem, rng, packet, sizeof(packet), path, dest, data, length); ck_assert_msg(len != -1, "failed to create onion packet"); ck_assert_msg(sendpacket(net, &path->ip_port1, packet, len) == len, "failed to send onion packet"); } @@ -228,9 +228,9 @@ static void test_basic(void) const Random *rng = os_random(); ck_assert(rng != nullptr); - Logger *log1 = logger_new(); + Logger *log1 = logger_new(mem); logger_callback_log(log1, print_debug_logger, nullptr, &index[0]); - Logger *log2 = logger_new(); + Logger *log2 = logger_new(mem); logger_callback_log(log2, print_debug_logger, nullptr, &index[1]); Mono_Time *mono_time1 = mono_time_new(mem, nullptr, nullptr); @@ -264,7 +264,7 @@ static void test_basic(void) nodes[3] = n2; Onion_Path path; create_onion_path(rng, onion1->dht, &path, nodes); - send_onion_packet(onion1->net, rng, &path, &nodes[3].ip_port, req_packet, sizeof(req_packet)); + send_onion_packet(onion1->net, onion1->mem, rng, &path, &nodes[3].ip_port, req_packet, sizeof(req_packet)); handled_test_1 = 0; @@ -291,7 +291,7 @@ static void test_basic(void) uint64_t s; memcpy(&s, sb_data, sizeof(uint64_t)); memcpy(test_3_pub_key, nodes[3].public_key, CRYPTO_PUBLIC_KEY_SIZE); - int ret = send_announce_request(log1, onion1->net, rng, &path, &nodes[3], + int ret = send_announce_request(log1, onion1->mem, onion1->net, rng, &path, &nodes[3], dht_get_self_public_key(onion1->dht), dht_get_self_secret_key(onion1->dht), zeroes, @@ -313,7 +313,7 @@ static void test_basic(void) memcpy(onion_announce_entry_public_key(onion2_a, 1), dht_get_self_public_key(onion2->dht), CRYPTO_PUBLIC_KEY_SIZE); onion_announce_entry_set_time(onion2_a, 1, mono_time_get(mono_time2)); networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1); - send_announce_request(log1, onion1->net, rng, &path, &nodes[3], + send_announce_request(log1, onion1->mem, onion1->net, rng, &path, &nodes[3], dht_get_self_public_key(onion1->dht), dht_get_self_secret_key(onion1->dht), test_3_ping_id, @@ -329,7 +329,7 @@ static void test_basic(void) CRYPTO_PUBLIC_KEY_SIZE) != 0); c_sleep(1000); - Logger *log3 = logger_new(); + Logger *log3 = logger_new(mem); logger_callback_log(log3, print_debug_logger, nullptr, &index[2]); Mono_Time *mono_time3 = mono_time_new(mem, nullptr, nullptr); @@ -338,7 +338,7 @@ static void test_basic(void) ck_assert_msg((onion3 != nullptr), "Onion failed initializing."); random_nonce(rng, nonce); - ret = send_data_request(log3, onion3->net, rng, &path, &nodes[3].ip_port, + ret = send_data_request(log3, onion3->mem, onion3->net, rng, &path, &nodes[3].ip_port, dht_get_self_public_key(onion1->dht), dht_get_self_public_key(onion1->dht), nonce, (const uint8_t *)"Install gentoo", sizeof("Install gentoo")); @@ -412,7 +412,7 @@ static Onions *new_onions(const Memory *mem, const Random *rng, uint16_t port, u return nullptr; } - on->log = logger_new(); + on->log = logger_new(mem); if (!on->log) { free(on); diff --git a/external/toxcore/c-toxcore/azure-pipelines.yml b/external/toxcore/c-toxcore/azure-pipelines.yml index 941bc33..9313566 100644 --- a/external/toxcore/c-toxcore/azure-pipelines.yml +++ b/external/toxcore/c-toxcore/azure-pipelines.yml @@ -1,15 +1,25 @@ pool: vmImage: "windows-2019" jobs: - - job: "windows_msvc_conan" + - job: "vcpkg" strategy: matrix: static: - conan.shared: "False" + ENABLE_STATIC: "ON" + ENABLE_SHARED: "OFF" shared: - conan.shared: "True" + ENABLE_STATIC: "OFF" + ENABLE_SHARED: "ON" steps: - - bash: python -m pip install conan==1.59.0 + - task: Cache@2 + inputs: + key: "vcpkg" + path: "_build/vcpkg_installed" - bash: git submodule update --init --recursive - - bash: conan install -if _build -o with_tests=True -o shared=$(conan.shared) . - - bash: CONAN_CPU_COUNT=50 CTEST_OUTPUT_ON_FAILURE=1 conan build -bf _build -if _build . || true + - bash: cmake --preset windows-default -DENABLE_STATIC=$(ENABLE_STATIC) -DENABLE_SHARED=$(ENABLE_SHARED) + env: + VCPKG_ROOT: "C:/vcpkg" + VCPKG_DEFAULT_TRIPLET: "x64-windows" + - bash: cmake --build _build --config Release + - bash: ctest --preset windows-default -C Release --parallel 50 || + ctest --preset windows-default -C Release --rerun-failed --output-on-failure diff --git a/external/toxcore/c-toxcore/cmake/Dependencies.cmake b/external/toxcore/c-toxcore/cmake/Dependencies.cmake index 900e9b1..fb30fdc 100644 --- a/external/toxcore/c-toxcore/cmake/Dependencies.cmake +++ b/external/toxcore/c-toxcore/cmake/Dependencies.cmake @@ -12,14 +12,20 @@ find_library(SOCKET_LIBRARIES socket) find_package(pthreads QUIET) if(NOT TARGET PThreads4W::PThreads4W) + find_package(pthreads4w QUIET) +endif() +if(NOT TARGET pthreads4w::pthreads4w) set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) endif() # For toxcore. -pkg_search_module(LIBSODIUM libsodium IMPORTED_TARGET REQUIRED) +pkg_search_module(LIBSODIUM libsodium IMPORTED_TARGET) if(MSVC) - find_package(unofficial-sodium REQUIRED) + find_package(libsodium) + if(NOT TARGET libsodium::libsodium) + find_package(unofficial-sodium REQUIRED) + endif() endif() # For toxav. @@ -27,10 +33,23 @@ pkg_search_module(OPUS opus IMPORTED_TARGET) if(NOT OPUS_FOUND) pkg_search_module(OPUS Opus IMPORTED_TARGET) endif() +if(NOT OPUS_FOUND) + find_package(Opus) + if(TARGET Opus::opus) + set(OPUS_FOUND TRUE) + endif() +endif() + pkg_search_module(VPX vpx IMPORTED_TARGET) if(NOT VPX_FOUND) pkg_search_module(VPX libvpx IMPORTED_TARGET) endif() +if(NOT VPX_FOUND) + find_package(libvpx) + if(TARGET libvpx::libvpx) + set(VPX_FOUND TRUE) + endif() +endif() # For tox-bootstrapd. pkg_search_module(LIBCONFIG libconfig IMPORTED_TARGET) diff --git a/external/toxcore/c-toxcore/conanfile.py b/external/toxcore/c-toxcore/conanfile.py deleted file mode 100644 index e9af70b..0000000 --- a/external/toxcore/c-toxcore/conanfile.py +++ /dev/null @@ -1,87 +0,0 @@ -# pylint: disable=not-callable -import os -import re - -from conans import CMake -from conans import ConanFile -from conans.tools import collect_libs -from conans.tools import load - - -class ToxConan(ConanFile): - name = "c-toxcore" - url = "https://tox.chat" - description = "The future of online communications." - license = "GPL-3.0-only" - settings = "os", "compiler", "build_type", "arch" - requires = "libsodium/1.0.18", "opus/1.3.1", "libvpx/1.9.0" - generators = "cmake_find_package" - scm = {"type": "git", "url": "auto", "revision": "auto"} - - options = { - "shared": [True, False], - "with_tests": [True, False], - } - default_options = { - "shared": False, - "with_tests": False, - } - - _cmake = None - - def _create_cmake(self): - if self._cmake is not None: - return self._cmake - - self._cmake = CMake(self) - self._cmake.definitions["AUTOTEST"] = self.options.with_tests - self._cmake.definitions["BUILD_MISC_TESTS"] = self.options.with_tests - self._cmake.definitions["TEST_TIMEOUT_SECONDS"] = "300" - - self._cmake.definitions[ - "CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS"] = self.options.shared - self._cmake.definitions["ENABLE_SHARED"] = self.options.shared - self._cmake.definitions["ENABLE_STATIC"] = not self.options.shared - self._cmake.definitions["MUST_BUILD_TOXAV"] = True - if self.settings.compiler == "Visual Studio": - self._cmake.definitions["MSVC_STATIC_SODIUM"] = True - self._cmake.definitions[ - "FLAT_OUTPUT_STRUCTURE"] = self.options.shared - - self._cmake.configure() - return self._cmake - - def set_version(self): - content = load(os.path.join(self.recipe_folder, "CMakeLists.txt")) - version_major = re.search(r"set\(PROJECT_VERSION_MAJOR \"(.*)\"\)", - content).group(1) - version_minor = re.search(r"set\(PROJECT_VERSION_MINOR \"(.*)\"\)", - content).group(1) - version_patch = re.search(r"set\(PROJECT_VERSION_PATCH \"(.*)\"\)", - content).group(1) - self.version = "%s.%s.%s" % ( - version_major.strip(), - version_minor.strip(), - version_patch.strip(), - ) - - def requirements(self): - if self.settings.os == "Windows": - self.requires("pthreads4w/3.0.0") - - def build(self): - cmake = self._create_cmake() - cmake.build() - - if self.options.with_tests: - cmake.test(output_on_failure=True) - - def package(self): - cmake = self._create_cmake() - cmake.install() - - def package_info(self): - self.cpp_info.libs = collect_libs(self) - - if self.settings.os == "Windows": - self.cpp_info.system_libs = ["Ws2_32", "Iphlpapi"] diff --git a/external/toxcore/c-toxcore/configure.ac b/external/toxcore/c-toxcore/configure.ac index 76eca6b..b2869a9 100644 --- a/external/toxcore/c-toxcore/configure.ac +++ b/external/toxcore/c-toxcore/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.65]) -AC_INIT([tox], [0.2.19]) +AC_INIT([tox], [0.2.20]) AC_CONFIG_AUX_DIR(configure_aux) AC_CONFIG_SRCDIR([toxcore/net_crypto.c]) AM_INIT_AUTOMAKE([foreign 1.10 -Wall -Werror subdir-objects tar-ustar]) diff --git a/external/toxcore/c-toxcore/other/BUILD.bazel b/external/toxcore/c-toxcore/other/BUILD.bazel index 50693bd..3239c5c 100644 --- a/external/toxcore/c-toxcore/other/BUILD.bazel +++ b/external/toxcore/c-toxcore/other/BUILD.bazel @@ -21,10 +21,15 @@ cc_binary( "//c-toxcore/toxcore:Messenger", "//c-toxcore/toxcore:TCP_server", "//c-toxcore/toxcore:ccompat", + "//c-toxcore/toxcore:crypto_core", + "//c-toxcore/toxcore:forwarding", + "//c-toxcore/toxcore:group_announce", "//c-toxcore/toxcore:group_onion_announce", "//c-toxcore/toxcore:logger", + "//c-toxcore/toxcore:mem", "//c-toxcore/toxcore:mono_time", "//c-toxcore/toxcore:network", + "//c-toxcore/toxcore:onion", "//c-toxcore/toxcore:onion_announce", "//c-toxcore/toxcore:tox", ], diff --git a/external/toxcore/c-toxcore/other/DHT_bootstrap.c b/external/toxcore/c-toxcore/other/DHT_bootstrap.c index 8a15fb5..c4511aa 100644 --- a/external/toxcore/c-toxcore/other/DHT_bootstrap.c +++ b/external/toxcore/c-toxcore/other/DHT_bootstrap.c @@ -144,16 +144,16 @@ int main(int argc, char *argv[]) IP ip; ip_init(&ip, ipv6enabled); - Logger *logger = logger_new(); + const Random *rng = os_random(); + const Network *ns = os_network(); + const Memory *mem = os_memory(); + + Logger *logger = logger_new(mem); if (MIN_LOGGER_LEVEL <= LOGGER_LEVEL_DEBUG) { logger_callback_log(logger, print_log, nullptr, nullptr); } - 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; const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM); @@ -228,9 +228,12 @@ int main(int argc, char *argv[]) const uint16_t port = net_htons((uint16_t)port_conv); + // TODO(iphydf): Maybe disable and only use IP addresses? + const bool dns_enabled = true; + uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]); const bool res = dht_bootstrap_from_address(dht, argv[argvoffset + 1], - ipv6enabled, port, bootstrap_key); + ipv6enabled, dns_enabled, port, bootstrap_key); free(bootstrap_key); if (!res) { diff --git a/external/toxcore/c-toxcore/other/analysis/gen-file.sh b/external/toxcore/c-toxcore/other/analysis/gen-file.sh index 10edd0b..6af978c 100644 --- a/external/toxcore/c-toxcore/other/analysis/gen-file.sh +++ b/external/toxcore/c-toxcore/other/analysis/gen-file.sh @@ -15,7 +15,7 @@ CPPFLAGS+=("-Itoxav") CPPFLAGS+=("-Itoxencryptsave") CPPFLAGS+=("-Ithird_party/cmp") -LDFLAGS=("-lopus" "-lsodium" "-lvpx" "-lpthread" "-lconfig" "-lgmock" "-lgtest") +LDFLAGS=("-lopus" "-lsodium" "-lvpx" "-lpthread" "-lconfig" "-lgmock" "-lgtest" "-lbenchmark") LDFLAGS+=("-fuse-ld=gold") LDFLAGS+=("-Wl,--detect-odr-violations") LDFLAGS+=("-Wl,--warn-common") @@ -27,7 +27,7 @@ put() { if [ "$SKIP_LINES" = "" ]; then echo "#line 1 \"$1\"" >>amalgamation.cc fi - cat "$1" >>amalgamation.cc + grep -v '^BENCHMARK_MAIN' "$1" >>amalgamation.cc } putmain() { diff --git a/external/toxcore/c-toxcore/other/bootstrap_daemon/BUILD.bazel b/external/toxcore/c-toxcore/other/bootstrap_daemon/BUILD.bazel index 6d4b157..4c65660 100644 --- a/external/toxcore/c-toxcore/other/bootstrap_daemon/BUILD.bazel +++ b/external/toxcore/c-toxcore/other/bootstrap_daemon/BUILD.bazel @@ -6,16 +6,24 @@ cc_binary( "src/*.c", "src/*.h", ]), + tags = ["no-windows"], deps = [ "//c-toxcore/other:bootstrap_node_packets", "//c-toxcore/toxcore:DHT", "//c-toxcore/toxcore:LAN_discovery", "//c-toxcore/toxcore:TCP_server", "//c-toxcore/toxcore:announce", + "//c-toxcore/toxcore:attributes", "//c-toxcore/toxcore:ccompat", + "//c-toxcore/toxcore:crypto_core", + "//c-toxcore/toxcore:forwarding", + "//c-toxcore/toxcore:group_announce", "//c-toxcore/toxcore:group_onion_announce", "//c-toxcore/toxcore:logger", + "//c-toxcore/toxcore:mem", "//c-toxcore/toxcore:mono_time", + "//c-toxcore/toxcore:network", + "//c-toxcore/toxcore:onion", "//c-toxcore/toxcore:onion_announce", "//c-toxcore/toxcore:tox", "@libconfig", diff --git a/external/toxcore/c-toxcore/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 b/external/toxcore/c-toxcore/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 index c726f00..33ace21 100644 --- a/external/toxcore/c-toxcore/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 +++ b/external/toxcore/c-toxcore/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 @@ -1 +1 @@ -e96f03a89051c5df12c28d0d6941184da2b92742d248bd4c57d31189a0052844 /usr/local/bin/tox-bootstrapd +9ec2993a28988bd147bf8f4f21a824c2fc5dbf7255e391b3ce517d337ebce5c1 /usr/local/bin/tox-bootstrapd diff --git a/external/toxcore/c-toxcore/other/bootstrap_daemon/src/config.c b/external/toxcore/c-toxcore/other/bootstrap_daemon/src/config.c index ba9efa2..19779c5 100644 --- a/external/toxcore/c-toxcore/other/bootstrap_daemon/src/config.c +++ b/external/toxcore/c-toxcore/other/bootstrap_daemon/src/config.c @@ -390,6 +390,9 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6 bool address_resolved; uint8_t *bs_public_key_bin; + // TODO(iphydf): Maybe disable it and only use IP addresses? + const bool dns_enabled = true; + node = config_setting_get_elem(node_list, 0); if (node == nullptr) { @@ -429,7 +432,7 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6 } bs_public_key_bin = bootstrap_hex_string_to_bin(bs_public_key); - address_resolved = dht_bootstrap_from_address(dht, bs_address, enable_ipv6, net_htons(bs_port), + address_resolved = dht_bootstrap_from_address(dht, bs_address, enable_ipv6, dns_enabled, net_htons(bs_port), bs_public_key_bin); free(bs_public_key_bin); diff --git a/external/toxcore/c-toxcore/other/bootstrap_daemon/src/tox-bootstrapd.c b/external/toxcore/c-toxcore/other/bootstrap_daemon/src/tox-bootstrapd.c index 60e14c0..e29afe5 100644 --- a/external/toxcore/c-toxcore/other/bootstrap_daemon/src/tox-bootstrapd.c +++ b/external/toxcore/c-toxcore/other/bootstrap_daemon/src/tox-bootstrapd.c @@ -283,16 +283,17 @@ int main(int argc, char *argv[]) IP ip; ip_init(&ip, enable_ipv6); - Logger *logger = logger_new(); + const Memory *mem = os_memory(); + const Random *rng = os_random(); + const Network *ns = os_network(); + + Logger *logger = logger_new(mem); if (MIN_LOGGER_LEVEL <= LOGGER_LEVEL_DEBUG) { logger_callback_log(logger, toxcore_logger_callback, nullptr, nullptr); } const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM); - 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) { diff --git a/external/toxcore/c-toxcore/other/docker/circleci/Dockerfile b/external/toxcore/c-toxcore/other/docker/circleci/Dockerfile index 3b23eed..cb431c3 100644 --- a/external/toxcore/c-toxcore/other/docker/circleci/Dockerfile +++ b/external/toxcore/c-toxcore/other/docker/circleci/Dockerfile @@ -1,18 +1,18 @@ ################################################ # cmake-asan -FROM ubuntu:20.04 +FROM ubuntu:24.04 RUN apt-get update && \ DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \ clang \ cmake \ + libclang-rt-dev \ libconfig-dev \ libgmock-dev \ libgtest-dev \ libopus-dev \ libsodium-dev \ libvpx-dev \ - llvm-dev \ ninja-build \ pkg-config \ && apt-get clean \ @@ -22,8 +22,8 @@ COPY entrypoint.sh / RUN ["chmod", "755", "/entrypoint.sh"] WORKDIR /home/builder -RUN groupadd -r -g 1000 builder \ - && useradd --no-log-init -r -g builder -u 1000 builder \ +RUN groupadd -r -g 987 builder \ + && useradd --no-log-init -r -g builder -u 987 builder \ && chown builder:builder /home/builder USER builder diff --git a/external/toxcore/c-toxcore/other/docker/circleci/entrypoint.sh b/external/toxcore/c-toxcore/other/docker/circleci/entrypoint.sh index 9717592..0788e71 100755 --- a/external/toxcore/c-toxcore/other/docker/circleci/entrypoint.sh +++ b/external/toxcore/c-toxcore/other/docker/circleci/entrypoint.sh @@ -1,9 +1,9 @@ #!/bin/sh -set -eu +set -eux SANITIZER="${1:-asan}" cp -a /c-toxcore . cd c-toxcore -.circleci/cmake-"$SANITIZER" +.circleci/cmake-"$SANITIZER" || (cat /home/builder/c-toxcore/_build/CMakeFiles/CMakeError.log && false) diff --git a/external/toxcore/c-toxcore/other/docker/circleci/run b/external/toxcore/c-toxcore/other/docker/circleci/run index 668e0fc..4b20807 100755 --- a/external/toxcore/c-toxcore/other/docker/circleci/run +++ b/external/toxcore/c-toxcore/other/docker/circleci/run @@ -1,6 +1,14 @@ #!/bin/sh +set -eux + SANITIZER="${1:-asan}" +if [ -t 0 ]; then + TTY=true +else + TTY=false +fi + docker build -t toxchat/c-toxcore:circleci other/docker/circleci -docker run --name toxcore-circleci --rm -it -v "$PWD:/c-toxcore" toxchat/c-toxcore:circleci "$SANITIZER" +docker run --name toxcore-circleci --rm --interactive="$TTY" --tty="$TTY" --volume "$PWD:/c-toxcore" toxchat/c-toxcore:circleci "$SANITIZER" diff --git a/external/toxcore/c-toxcore/other/docker/esp32/BUILD.bazel b/external/toxcore/c-toxcore/other/docker/esp32/BUILD.bazel index 5a4009e..cee11db 100644 --- a/external/toxcore/c-toxcore/other/docker/esp32/BUILD.bazel +++ b/external/toxcore/c-toxcore/other/docker/esp32/BUILD.bazel @@ -9,6 +9,7 @@ cc_binary( "main/tox_main.h", ], deps = [ + "//c-toxcore/toxcore:ccompat", "//c-toxcore/toxcore:tox", "//c-toxcore/toxcore:tox_events", ], diff --git a/external/toxcore/c-toxcore/other/docker/modules/check b/external/toxcore/c-toxcore/other/docker/modules/check index 0249efe..e62be62 100755 --- a/external/toxcore/c-toxcore/other/docker/modules/check +++ b/external/toxcore/c-toxcore/other/docker/modules/check @@ -50,6 +50,10 @@ module "//c-toxcore/third_party:cmp" { module "//c-toxcore/toxencryptsave:defines" { header "toxencryptsave/defines.h" } +module "@benchmark" { + textual header "/usr/include/benchmark/benchmark.h" + use std +} module "@com_google_googletest//:gtest" { textual header "/usr/include/gmock/gmock.h" textual header "/usr/include/gtest/gtest.h" @@ -83,9 +87,9 @@ class Context: pass def bzl_exports_files( - self, - srcs: list[str], - visibility: Optional[list[str]] = None, + self, + srcs: list[str], + visibility: Optional[list[str]] = None, ) -> None: pass @@ -110,7 +114,7 @@ class Context: hdrs, } - def bzl_cc_test( + def bzl_cc_binary( self, name: str, srcs: Iterable[str] = tuple(), @@ -161,7 +165,8 @@ def main() -> None: "load": ctx.bzl_load, "exports_files": ctx.bzl_exports_files, "cc_library": ctx.bzl_cc_library, - "cc_test": ctx.bzl_cc_test, + "cc_binary": ctx.bzl_cc_binary, + "cc_test": ctx.bzl_cc_binary, "cc_fuzz_test": ctx.bzl_cc_fuzz_test, "select": ctx.bzl_select, "glob": ctx.bzl_glob, diff --git a/external/toxcore/c-toxcore/other/docker/modules/modules.Dockerfile b/external/toxcore/c-toxcore/other/docker/modules/modules.Dockerfile index 5fb03a2..ca4a705 100644 --- a/external/toxcore/c-toxcore/other/docker/modules/modules.Dockerfile +++ b/external/toxcore/c-toxcore/other/docker/modules/modules.Dockerfile @@ -3,6 +3,7 @@ FROM alpine:3.19.0 RUN ["apk", "add", "--no-cache", \ "bash", \ + "benchmark-dev", \ "clang", \ "gtest-dev", \ "libconfig-dev", \ diff --git a/external/toxcore/c-toxcore/other/docker/pkgsrc/pkgsrc.Dockerfile b/external/toxcore/c-toxcore/other/docker/pkgsrc/pkgsrc.Dockerfile index c27ed7c..3483bdf 100644 --- a/external/toxcore/c-toxcore/other/docker/pkgsrc/pkgsrc.Dockerfile +++ b/external/toxcore/c-toxcore/other/docker/pkgsrc/pkgsrc.Dockerfile @@ -5,7 +5,7 @@ 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 ["sed", "-i", "-e", "s/libtoxcore.so.2.18.0/libtoxcore.so.2.19.0/g", "PLIST"] +RUN ["sed", "-i", "-e", "s/libtoxcore.so.2.18.0/libtoxcore.so.2.20.0/g", "PLIST"] RUN ["bmake", "clean"] RUN ["bmake", "DISTFILES=c-toxcore.tar.gz", "DISTDIR=/work", "NO_CHECKSUM=yes"] RUN ["bmake", "install"] diff --git a/external/toxcore/c-toxcore/so.version b/external/toxcore/c-toxcore/so.version index 26514bc..3415d97 100644 --- a/external/toxcore/c-toxcore/so.version +++ b/external/toxcore/c-toxcore/so.version @@ -11,6 +11,6 @@ # For a full reference see: # https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info -CURRENT=21 +CURRENT=22 REVISION=0 -AGE=19 +AGE=20 diff --git a/external/toxcore/c-toxcore/super_donators/BUILD.bazel b/external/toxcore/c-toxcore/super_donators/BUILD.bazel index f268d5d..46fc8f6 100644 --- a/external/toxcore/c-toxcore/super_donators/BUILD.bazel +++ b/external/toxcore/c-toxcore/super_donators/BUILD.bazel @@ -4,4 +4,5 @@ cc_binary( name = "grencez_tok5", srcs = ["grencez_tok5.c"], copts = ["-Wno-unused-result"], + tags = ["no-windows"], ) diff --git a/external/toxcore/c-toxcore/testing/BUILD.bazel b/external/toxcore/c-toxcore/testing/BUILD.bazel index 4427347..d907be3 100644 --- a/external/toxcore/c-toxcore/testing/BUILD.bazel +++ b/external/toxcore/c-toxcore/testing/BUILD.bazel @@ -75,7 +75,6 @@ cc_library( deps = [ "//c-toxcore/toxcore:ccompat", "//c-toxcore/toxcore:tox", - "@libsodium", ], ) diff --git a/external/toxcore/c-toxcore/testing/CMakeLists.txt b/external/toxcore/c-toxcore/testing/CMakeLists.txt index d664c0f..3c2bea1 100644 --- a/external/toxcore/c-toxcore/testing/CMakeLists.txt +++ b/external/toxcore/c-toxcore/testing/CMakeLists.txt @@ -8,15 +8,9 @@ if(TARGET toxcore_static) else() target_link_libraries(misc_tools PRIVATE toxcore_shared) endif() -if(TARGET unofficial-sodium::sodium) - target_link_libraries(misc_tools PRIVATE unofficial-sodium::sodium) -else() - target_link_libraries(misc_tools PRIVATE ${LIBSODIUM_LIBRARIES}) - target_link_directories(misc_tools PUBLIC ${LIBSODIUM_LIBRARY_DIRS}) - target_include_directories(misc_tools SYSTEM PRIVATE ${LIBSODIUM_INCLUDE_DIRS}) - target_compile_options(misc_tools PRIVATE ${LIBSODIUM_CFLAGS_OTHER}) -endif() -if(TARGET PThreads4W::PThreads4W) +if(TARGET pthreads4w::pthreads4w) + target_link_libraries(misc_tools PRIVATE pthreads4w::pthreads4w) +elseif(TARGET PThreads4W::PThreads4W) target_link_libraries(misc_tools PRIVATE PThreads4W::PThreads4W) elseif(TARGET Threads::Threads) target_link_libraries(misc_tools PRIVATE Threads::Threads) @@ -36,7 +30,9 @@ if(BUILD_MISC_TESTS) else() target_link_libraries(Messenger_test PRIVATE toxcore_shared) endif() - if(TARGET PThreads4W::PThreads4W) + if(TARGET pthreads4w::pthreads4w) + target_link_libraries(Messenger_test PRIVATE pthreads4w::pthreads4w) + elseif(TARGET PThreads4W::PThreads4W) target_link_libraries(Messenger_test PRIVATE PThreads4W::PThreads4W) elseif(TARGET Threads::Threads) target_link_libraries(Messenger_test PRIVATE Threads::Threads) diff --git a/external/toxcore/c-toxcore/testing/Makefile.inc b/external/toxcore/c-toxcore/testing/Makefile.inc index 223ebdc..7d5f24b 100644 --- a/external/toxcore/c-toxcore/testing/Makefile.inc +++ b/external/toxcore/c-toxcore/testing/Makefile.inc @@ -8,10 +8,6 @@ endif noinst_LTLIBRARIES += libmisc_tools.la libmisc_tools_la_SOURCES = ../testing/misc_tools.c ../testing/misc_tools.h -libmisc_tools_la_CFLAGS = $(LIBSODIUM_CFLAGS) - -libmisc_tools_la_LIBADD = $(LIBSODIUM_LDFLAGS) - if BUILD_TESTING noinst_PROGRAMS += Messenger_test diff --git a/external/toxcore/c-toxcore/testing/Messenger_test.c b/external/toxcore/c-toxcore/testing/Messenger_test.c index 65ea8a9..18d7347 100644 --- a/external/toxcore/c-toxcore/testing/Messenger_test.c +++ b/external/toxcore/c-toxcore/testing/Messenger_test.c @@ -118,10 +118,13 @@ int main(int argc, char *argv[]) exit(1); } + // TODO(iphydf): Maybe disable. + const bool dns_enabled = true; + const uint16_t port = net_htons((uint16_t)port_conv); uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]); bool res = dht_bootstrap_from_address(m->dht, argv[argvoffset + 1], - ipv6enabled, port, bootstrap_key); + ipv6enabled, dns_enabled, port, bootstrap_key); free(bootstrap_key); if (!res) { diff --git a/external/toxcore/c-toxcore/testing/fuzzing/BUILD.bazel b/external/toxcore/c-toxcore/testing/fuzzing/BUILD.bazel index ce23b79..4c9c0a1 100644 --- a/external/toxcore/c-toxcore/testing/fuzzing/BUILD.bazel +++ b/external/toxcore/c-toxcore/testing/fuzzing/BUILD.bazel @@ -48,6 +48,7 @@ cc_fuzz_test( deps = [ ":fuzz_support", ":fuzz_tox", + "//c-toxcore/toxcore:crypto_core", "//c-toxcore/toxcore:tox", "//c-toxcore/toxcore:tox_dispatch", "//c-toxcore/toxcore:tox_events", @@ -102,6 +103,7 @@ cc_test( deps = [ ":fuzz_support", ":fuzz_tox", + "//c-toxcore/toxcore:crypto_core", "//c-toxcore/toxcore:tox", "//c-toxcore/toxcore:tox_dispatch", "//c-toxcore/toxcore:tox_events", @@ -117,6 +119,7 @@ cc_fuzz_test( deps = [ ":fuzz_support", ":fuzz_tox", + "//c-toxcore/toxcore:crypto_core", "//c-toxcore/toxcore:tox", "//c-toxcore/toxcore:tox_dispatch", "//c-toxcore/toxcore:tox_events", diff --git a/external/toxcore/c-toxcore/testing/fuzzing/fuzz_support.cc b/external/toxcore/c-toxcore/testing/fuzzing/fuzz_support.cc index fe760f9..a98967a 100644 --- a/external/toxcore/c-toxcore/testing/fuzzing/fuzz_support.cc +++ b/external/toxcore/c-toxcore/testing/fuzzing/fuzz_support.cc @@ -4,8 +4,15 @@ #include "fuzz_support.hh" +#ifdef _WIN32 +#include +// Comment line here to avoid reordering by source code formatters. +#include +#include +#else #include #include +#endif #include #include @@ -111,6 +118,7 @@ static constexpr Network_Funcs fuzz_network_funcs = { /* .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; }, + /* .connect = */ ![](Fuzz_System *self, Socket sock, const Network_Addr *addr) { return 0; }, /* .recvbuf = */ ![](Fuzz_System *self, Socket sock) { assert(sock.value == 42 || sock.value == 1337); @@ -225,6 +233,7 @@ static constexpr Network_Funcs null_network_funcs = { /* .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; }, + /* .connect = */ ![](Null_System *self, Socket sock, const Network_Addr *addr) { return 0; }, /* .recvbuf = */ ![](Null_System *self, Socket sock) { return 0; }, /* .recv = */ ![](Null_System *self, Socket sock, uint8_t *buf, size_t len) { @@ -341,6 +350,7 @@ static constexpr Network_Funcs record_network_funcs = { return 0; }, /* .listen = */ ![](Record_System *self, Socket sock, int backlog) { return 0; }, + /* .connect = */ ![](Record_System *self, Socket sock, const Network_Addr *addr) { return 0; }, /* .recvbuf = */ ![](Record_System *self, Socket sock) { return 0; }, /* .recv = */ ![](Record_System *self, Socket sock, uint8_t *buf, size_t len) { diff --git a/external/toxcore/c-toxcore/testing/misc_tools.c b/external/toxcore/c-toxcore/testing/misc_tools.c index a2b950c..6352f47 100644 --- a/external/toxcore/c-toxcore/testing/misc_tools.c +++ b/external/toxcore/c-toxcore/testing/misc_tools.c @@ -20,8 +20,6 @@ #include #include -#include - #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) #include #else @@ -137,60 +135,3 @@ int cmdline_parsefor_ipv46(int argc, char **argv, bool *ipv6enabled) return argvoffset; } - -static const char *test_rng_name(void) -{ - return "test_rng"; -} - -static uint32_t rng_state; - -static uint32_t test_rng_random(void) -{ - rng_state = 2624534371 * rng_state + 1; - return rng_state; -} - -static void test_rng_buf(void *const buf, const size_t size) -{ - uint8_t *p = (uint8_t *)buf; - uint32_t r = 0; - - for (size_t i = 0; i < size; i++) { - if ((i % 4) == 0) { - r = test_rng_random(); - } - - *p = (r >> ((i % 4) * 8)) & 0xff; - ++p; - } -} - -static uint32_t test_rng_uniform(const uint32_t upper_bound) -{ - // XXX: Not uniform! But that's ok for testing purposes. - return test_rng_random() % upper_bound; -} - -static void test_rng_stir(void) { } -static int test_rng_close(void) -{ - return 0; -} - -static randombytes_implementation test_rng = { - test_rng_name, - test_rng_random, - test_rng_stir, - test_rng_uniform, - test_rng_buf, - test_rng_close -}; - -/* Simple insecure PRNG for testing purposes */ -int use_test_rng(uint32_t seed) -{ - rng_state = seed; - - return randombytes_set_implementation(&test_rng); -} diff --git a/external/toxcore/c-toxcore/third_party/cmp b/external/toxcore/c-toxcore/third_party/cmp index 2ac6bca..52bfcfa 160000 --- a/external/toxcore/c-toxcore/third_party/cmp +++ b/external/toxcore/c-toxcore/third_party/cmp @@ -1 +1 @@ -Subproject commit 2ac6bca152987c805c04423ebbba4b750585337f +Subproject commit 52bfcfa17d2eb4322da2037ad625f5575129cece diff --git a/external/toxcore/c-toxcore/toxcore/BUILD.bazel b/external/toxcore/c-toxcore/toxcore/BUILD.bazel index 916c622..63cc08a 100644 --- a/external/toxcore/c-toxcore/toxcore/BUILD.bazel +++ b/external/toxcore/c-toxcore/toxcore/BUILD.bazel @@ -1,4 +1,4 @@ -load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") +load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") load("@rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test") exports_files( @@ -100,14 +100,58 @@ cc_test( size = "small", srcs = ["util_test.cc"], deps = [ - ":crypto_core", - ":crypto_core_test_util", ":util", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], ) +cc_library( + name = "sort", + srcs = ["sort.c"], + hdrs = ["sort.h"], + deps = [ + ":attributes", + ":ccompat", + ":util", + ], +) + +cc_library( + name = "sort_test_util", + testonly = True, + srcs = ["sort_test_util.cc"], + hdrs = ["sort_test_util.hh"], + deps = [ + ":sort", + ":util", + ], +) + +cc_test( + name = "sort_test", + size = "small", + srcs = ["sort_test.cc"], + deps = [ + ":sort", + ":sort_test_util", + "@com_google_googletest//:gtest", + "@com_google_googletest//:gtest_main", + ], +) + +cc_binary( + name = "sort_bench", + testonly = True, + srcs = ["sort_bench.cc"], + deps = [ + ":mem", + ":sort", + ":sort_test_util", + "@benchmark", + ], +) + cc_library( name = "logger", srcs = ["logger.c"], @@ -121,6 +165,7 @@ cc_library( deps = [ ":attributes", ":ccompat", + ":mem", ], ) @@ -170,6 +215,7 @@ cc_library( deps = [ ":attributes", ":ccompat", + ":mem", ":util", "@libsodium", ], @@ -208,6 +254,7 @@ cc_test( deps = [ ":crypto_core", ":crypto_core_test_util", + ":mem_test_util", ":util", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", @@ -332,6 +379,7 @@ cc_library( hdrs = ["network_test_util.hh"], deps = [ ":crypto_core", + ":mem", ":network", ":test_util", ], @@ -435,6 +483,7 @@ cc_library( ":network", ":ping_array", ":shared_key_cache", + ":sort", ":state", ":util", ], @@ -478,10 +527,12 @@ cc_test( cc_fuzz_test( name = "DHT_fuzz_test", size = "small", + testonly = True, srcs = ["DHT_fuzz_test.cc"], corpus = ["//tools/toktok-fuzzer/corpus:DHT_fuzz_test"], deps = [ ":DHT", + ":mem_test_util", "//c-toxcore/testing/fuzzing:fuzz_support", ], ) @@ -490,7 +541,11 @@ cc_library( name = "onion", srcs = ["onion.c"], hdrs = ["onion.h"], - visibility = ["//c-toxcore/auto_tests:__pkg__"], + visibility = [ + "//c-toxcore/auto_tests:__pkg__", + "//c-toxcore/other:__pkg__", + "//c-toxcore/other/bootstrap_daemon:__pkg__", + ], deps = [ ":DHT", ":attributes", @@ -509,7 +564,11 @@ cc_library( name = "forwarding", srcs = ["forwarding.c"], hdrs = ["forwarding.h"], - visibility = ["//c-toxcore/auto_tests:__pkg__"], + visibility = [ + "//c-toxcore/auto_tests:__pkg__", + "//c-toxcore/other:__pkg__", + "//c-toxcore/other/bootstrap_daemon:__pkg__", + ], deps = [ ":DHT", ":attributes", @@ -704,6 +763,7 @@ cc_library( ":network", ":onion", ":shared_key_cache", + ":sort", ":timed_auth", ":util", ], @@ -777,6 +837,7 @@ cc_library( ":crypto_core", ":group_announce", ":logger", + ":mem", ":mono_time", ":network", ":onion_announce", @@ -806,6 +867,7 @@ cc_library( ":onion", ":onion_announce", ":ping_array", + ":sort", ":timed_auth", ":util", ], @@ -971,9 +1033,11 @@ cc_library( ":crypto_core", ":friend_connection", ":logger", + ":mem", ":mono_time", ":net_crypto", ":network", + ":sort", ":state", ":util", ], diff --git a/external/toxcore/c-toxcore/toxcore/DHT.c b/external/toxcore/c-toxcore/toxcore/DHT.c index 89c85c3..da4ab11 100644 --- a/external/toxcore/c-toxcore/toxcore/DHT.c +++ b/external/toxcore/c-toxcore/toxcore/DHT.c @@ -9,7 +9,6 @@ #include "DHT.h" #include -#include #include #include "LAN_discovery.h" @@ -24,7 +23,9 @@ #include "ping.h" #include "ping_array.h" #include "shared_key_cache.h" +#include "sort.h" #include "state.h" +#include "util.h" /** The timeout after which a node is discarded completely. */ #define KILL_NODE_TIMEOUT (BAD_NODE_TIMEOUT + PING_INTERVAL) @@ -279,7 +280,7 @@ const uint8_t *dht_get_shared_key_sent(DHT *dht, const uint8_t *public_key) #define CRYPTO_SIZE (1 + CRYPTO_PUBLIC_KEY_SIZE * 2 + CRYPTO_NONCE_SIZE) -int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key, +int create_request(const Memory *mem, const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key, uint8_t *packet, const uint8_t *recv_public_key, const uint8_t *data, uint32_t data_length, uint8_t request_id) { @@ -296,7 +297,7 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint uint8_t temp[MAX_CRYPTO_REQUEST_SIZE] = {0}; temp[0] = request_id; memcpy(temp + 1, data, data_length); - const int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, data_length + 1, + const int len = encrypt_data(mem, recv_public_key, send_secret_key, nonce, temp, data_length + 1, packet + CRYPTO_SIZE); if (len == -1) { @@ -312,7 +313,7 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint return len + CRYPTO_SIZE; } -int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, +int handle_request(const Memory *mem, const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, uint8_t *request_id, const uint8_t *packet, uint16_t packet_length) { if (self_public_key == nullptr || public_key == nullptr || data == nullptr || request_id == nullptr @@ -331,7 +332,7 @@ int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_ke memcpy(public_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); const uint8_t *const nonce = packet + 1 + CRYPTO_PUBLIC_KEY_SIZE * 2; uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; - int32_t len1 = decrypt_data(public_key, self_secret_key, nonce, + int32_t len1 = decrypt_data(mem, public_key, self_secret_key, nonce, packet + CRYPTO_SIZE, packet_length - CRYPTO_SIZE, temp); if (len1 == -1 || len1 == 0) { @@ -378,7 +379,7 @@ int dht_create_packet(const Memory *mem, const Random *rng, random_nonce(rng, nonce); - const int encrypted_length = encrypt_data_symmetric(shared_key, nonce, plain, plain_length, encrypted); + const int encrypted_length = encrypt_data_symmetric(mem, shared_key, nonce, plain, plain_length, encrypted); if (encrypted_length < 0) { mem_delete(mem, encrypted); @@ -755,49 +756,6 @@ int get_close_nodes( is_lan, want_announce); } -typedef struct DHT_Cmp_Data { - uint64_t cur_time; - const uint8_t *base_public_key; - Client_data entry; -} DHT_Cmp_Data; - -non_null() -static int dht_cmp_entry(const void *a, const void *b) -{ - const DHT_Cmp_Data *cmp1 = (const DHT_Cmp_Data *)a; - const DHT_Cmp_Data *cmp2 = (const DHT_Cmp_Data *)b; - const Client_data entry1 = cmp1->entry; - const Client_data entry2 = cmp2->entry; - const uint8_t *cmp_public_key = cmp1->base_public_key; - - const bool t1 = assoc_timeout(cmp1->cur_time, &entry1.assoc4) && assoc_timeout(cmp1->cur_time, &entry1.assoc6); - const bool t2 = assoc_timeout(cmp2->cur_time, &entry2.assoc4) && assoc_timeout(cmp2->cur_time, &entry2.assoc6); - - if (t1 && t2) { - return 0; - } - - if (t1) { - return -1; - } - - if (t2) { - return 1; - } - - const int closest = id_closest(cmp_public_key, entry1.public_key, entry2.public_key); - - if (closest == 1) { - return 1; - } - - if (closest == 2) { - return -1; - } - - return 0; -} - #ifdef CHECK_ANNOUNCE_NODE non_null() static void set_announce_node_in_list(Client_data *list, uint32_t list_len, const uint8_t *public_key) @@ -870,7 +828,7 @@ static int handle_data_search_response(void *object, const IP_Port *source, const uint8_t *public_key = packet + 1; const uint8_t *shared_key = dht_get_shared_key_recv(dht, public_key); - if (decrypt_data_symmetric(shared_key, + if (decrypt_data_symmetric(dht->mem, shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, plain_len + CRYPTO_MAC_SIZE, @@ -914,31 +872,117 @@ static bool store_node_ok(const Client_data *client, uint64_t cur_time, const ui || id_closest(comp_public_key, client->public_key, public_key) == 2; } +typedef struct Client_data_Cmp { + const Memory *mem; + uint64_t cur_time; + const uint8_t *comp_public_key; +} Client_data_Cmp; + +non_null() +static int client_data_cmp(const Client_data_Cmp *cmp, const Client_data *entry1, const Client_data *entry2) +{ + const bool t1 = assoc_timeout(cmp->cur_time, &entry1->assoc4) && assoc_timeout(cmp->cur_time, &entry1->assoc6); + const bool t2 = assoc_timeout(cmp->cur_time, &entry2->assoc4) && assoc_timeout(cmp->cur_time, &entry2->assoc6); + + if (t1 && t2) { + return 0; + } + + if (t1) { + return -1; + } + + if (t2) { + return 1; + } + + const int closest = id_closest(cmp->comp_public_key, entry1->public_key, entry2->public_key); + + if (closest == 1) { + return 1; + } + + if (closest == 2) { + return -1; + } + + return 0; +} + +non_null() +static bool client_data_less_handler(const void *object, const void *a, const void *b) +{ + const Client_data_Cmp *cmp = (const Client_data_Cmp *)object; + const Client_data *entry1 = (const Client_data *)a; + const Client_data *entry2 = (const Client_data *)b; + + return client_data_cmp(cmp, entry1, entry2) < 0; +} + +non_null() +static const void *client_data_get_handler(const void *arr, uint32_t index) +{ + const Client_data *entries = (const Client_data *)arr; + return &entries[index]; +} + +non_null() +static void client_data_set_handler(void *arr, uint32_t index, const void *val) +{ + Client_data *entries = (Client_data *)arr; + const Client_data *entry = (const Client_data *)val; + entries[index] = *entry; +} + +non_null() +static void *client_data_subarr_handler(void *arr, uint32_t index, uint32_t size) +{ + Client_data *entries = (Client_data *)arr; + return &entries[index]; +} + +non_null() +static void *client_data_alloc_handler(const void *object, uint32_t size) +{ + const Client_data_Cmp *cmp = (const Client_data_Cmp *)object; + Client_data *tmp = (Client_data *)mem_valloc(cmp->mem, size, sizeof(Client_data)); + + if (tmp == nullptr) { + return nullptr; + } + + return tmp; +} + +non_null() +static void client_data_delete_handler(const void *object, void *arr, uint32_t size) +{ + const Client_data_Cmp *cmp = (const Client_data_Cmp *)object; + mem_delete(cmp->mem, arr); +} + +static const Sort_Funcs client_data_cmp_funcs = { + client_data_less_handler, + client_data_get_handler, + client_data_set_handler, + client_data_subarr_handler, + client_data_alloc_handler, + client_data_delete_handler, +}; + non_null() static void sort_client_list(const Memory *mem, Client_data *list, uint64_t cur_time, unsigned int length, const uint8_t *comp_public_key) { - // Pass comp_public_key to qsort with each Client_data entry, so the + // Pass comp_public_key to merge_sort with each Client_data entry, so the // comparison function can use it as the base of comparison. - DHT_Cmp_Data *cmp_list = (DHT_Cmp_Data *)mem_valloc(mem, length, sizeof(DHT_Cmp_Data)); + const Client_data_Cmp cmp = { + mem, + cur_time, + comp_public_key, + }; - if (cmp_list == nullptr) { - return; - } - - for (uint32_t i = 0; i < length; ++i) { - cmp_list[i].cur_time = cur_time; - cmp_list[i].base_public_key = comp_public_key; - cmp_list[i].entry = list[i]; - } - - qsort(cmp_list, length, sizeof(DHT_Cmp_Data), dht_cmp_entry); - - for (uint32_t i = 0; i < length; ++i) { - list[i] = cmp_list[i].entry; - } - - mem_delete(mem, cmp_list); + merge_sort(list, length, &cmp, &client_data_cmp_funcs); } non_null() @@ -1381,6 +1425,7 @@ static int handle_getnodes(void *object, const IP_Port *source, const uint8_t *p uint8_t plain[CRYPTO_NODE_SIZE]; const uint8_t *shared_key = dht_get_shared_key_recv(dht, packet + 1); const int len = decrypt_data_symmetric( + dht->mem, shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, @@ -1442,6 +1487,7 @@ static bool handle_sendnodes_core(void *object, const IP_Port *source, const uin VLA(uint8_t, plain, plain_size); const uint8_t *shared_key = dht_get_shared_key_sent(dht, packet + 1); const int len = decrypt_data_symmetric( + dht->mem, shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, @@ -1840,7 +1886,7 @@ 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); } -bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, +bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dns_enabled, uint16_t port, const uint8_t *public_key) { IP_Port ip_port_v64; @@ -1855,7 +1901,7 @@ bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, ip_extra = &ip_port_v4.ip; } - if (addr_resolve_or_parse_ip(dht->ns, address, &ip_port_v64.ip, ip_extra)) { + if (addr_resolve_or_parse_ip(dht->ns, dht->mem, address, &ip_port_v64.ip, ip_extra, dns_enabled)) { ip_port_v64.port = port; dht_bootstrap(dht, &ip_port_v64, public_key); @@ -2123,7 +2169,7 @@ static int send_nat_ping(const DHT *dht, const uint8_t *public_key, uint64_t pin memcpy(data + 1, &ping_id, sizeof(uint64_t)); /* 254 is NAT ping request packet id */ const int len = create_request( - dht->rng, dht->self_public_key, dht->self_secret_key, packet_data, public_key, + dht->mem, dht->rng, dht->self_public_key, dht->self_secret_key, packet_data, public_key, data, sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING); if (len == -1) { @@ -2458,7 +2504,7 @@ static int cryptopacket_handle(void *object, const IP_Port *source, const uint8_ uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t data[MAX_CRYPTO_REQUEST_SIZE]; uint8_t number; - const int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key, + const int len = handle_request(dht->mem, dht->self_public_key, dht->self_secret_key, public_key, data, &number, packet, length); if (len == -1 || len == 0) { diff --git a/external/toxcore/c-toxcore/toxcore/DHT.h b/external/toxcore/c-toxcore/toxcore/DHT.h index 19a9e1d..f42670b 100644 --- a/external/toxcore/c-toxcore/toxcore/DHT.h +++ b/external/toxcore/c-toxcore/toxcore/DHT.h @@ -99,7 +99,7 @@ extern "C" { * @return the length of the created packet on success. */ non_null() -int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key, +int create_request(const Memory *mem, const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key, uint8_t *packet, const uint8_t *recv_public_key, const uint8_t *data, uint32_t data_length, uint8_t request_id); @@ -127,7 +127,7 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint */ non_null() int handle_request( - const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, + const Memory *mem, const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, uint8_t *request_id, const uint8_t *packet, uint16_t packet_length); typedef struct IPPTs { @@ -404,12 +404,13 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key); * @param address can be a hostname or an IP address (IPv4 or IPv6). * @param ipv6enabled if false, the resolving sticks STRICTLY to IPv4 addresses. * Otherwise, the resolving looks for IPv6 addresses first, then IPv4 addresses. + * @param dns_enabled if false, the resolving does not use DNS, only IP addresses are supported. * * @retval true if the address could be converted into an IP address * @retval false otherwise */ non_null() -bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, +bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dns_enabled, uint16_t port, const uint8_t *public_key); /** @brief Start sending packets after DHT loaded_friends_list and loaded_clients_list are set. diff --git a/external/toxcore/c-toxcore/toxcore/DHT_fuzz_test.cc b/external/toxcore/c-toxcore/toxcore/DHT_fuzz_test.cc index 868aede..cedec78 100644 --- a/external/toxcore/c-toxcore/toxcore/DHT_fuzz_test.cc +++ b/external/toxcore/c-toxcore/toxcore/DHT_fuzz_test.cc @@ -6,19 +6,22 @@ #include #include "../testing/fuzzing/fuzz_support.hh" +#include "mem_test_util.hh" namespace { void TestHandleRequest(Fuzz_Data &input) { + const Test_Memory mem; + CONSUME_OR_RETURN(const uint8_t *self_public_key, input, CRYPTO_PUBLIC_KEY_SIZE); CONSUME_OR_RETURN(const uint8_t *self_secret_key, input, CRYPTO_SECRET_KEY_SIZE); uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t request[MAX_CRYPTO_REQUEST_SIZE]; uint8_t request_id; - handle_request(self_public_key, self_secret_key, public_key, request, &request_id, input.data(), - input.size()); + handle_request(mem, self_public_key, self_secret_key, public_key, request, &request_id, + input.data(), input.size()); } void TestUnpackNodes(Fuzz_Data &input) @@ -31,7 +34,8 @@ void TestUnpackNodes(Fuzz_Data &input) const int packed_count = unpack_nodes( nodes, node_count, &processed_data_len, input.data(), input.size(), tcp_enabled); if (packed_count > 0) { - Logger *logger = logger_new(); + const Memory *mem = os_memory(); + Logger *logger = logger_new(mem); std::vector packed(packed_count * PACKED_NODE_SIZE_IP6); const int packed_size = pack_nodes(logger, packed.data(), packed.size(), nodes, packed_count); diff --git a/external/toxcore/c-toxcore/toxcore/DHT_test.cc b/external/toxcore/c-toxcore/toxcore/DHT_test.cc index 1028fc7..f817efe 100644 --- a/external/toxcore/c-toxcore/toxcore/DHT_test.cc +++ b/external/toxcore/c-toxcore/toxcore/DHT_test.cc @@ -274,6 +274,7 @@ TEST(AddToList, KeepsKeysInOrder) TEST(Request, CreateAndParse) { + Test_Memory mem; Test_Random rng; // Peers. @@ -293,32 +294,32 @@ TEST(Request, CreateAndParse) std::vector outgoing(919); random_bytes(rng, outgoing.data(), outgoing.size()); - EXPECT_LT(create_request(rng, sender.pk.data(), sender.sk.data(), packet.data(), + EXPECT_LT(create_request(mem, rng, sender.pk.data(), sender.sk.data(), packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id), 0); // Pop one element so the payload is 918 bytes. Packing should now succeed. outgoing.pop_back(); - const int max_sent_length = create_request(rng, sender.pk.data(), sender.sk.data(), + const int max_sent_length = create_request(mem, rng, sender.pk.data(), sender.sk.data(), packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id); ASSERT_GT(max_sent_length, 0); // success. // Check that handle_request rejects packets larger than the maximum created packet size. - EXPECT_LT(handle_request(receiver.pk.data(), receiver.sk.data(), pk.data(), incoming.data(), - &recvd_pkt_id, packet.data(), max_sent_length + 1), + EXPECT_LT(handle_request(mem, receiver.pk.data(), receiver.sk.data(), pk.data(), + incoming.data(), &recvd_pkt_id, packet.data(), max_sent_length + 1), 0); // Now try all possible packet sizes from max (918) to 0. while (!outgoing.empty()) { // Pack: - const int sent_length = create_request(rng, sender.pk.data(), sender.sk.data(), + const int sent_length = create_request(mem, rng, sender.pk.data(), sender.sk.data(), packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id); ASSERT_GT(sent_length, 0); // Unpack: - const int recvd_length = handle_request(receiver.pk.data(), receiver.sk.data(), pk.data(), - incoming.data(), &recvd_pkt_id, packet.data(), sent_length); + const int recvd_length = handle_request(mem, receiver.pk.data(), receiver.sk.data(), + pk.data(), incoming.data(), &recvd_pkt_id, packet.data(), sent_length); ASSERT_GE(recvd_length, 0); EXPECT_EQ( @@ -334,7 +335,7 @@ TEST(AnnounceNodes, SetAndTest) Test_Memory mem; Test_Network ns; - Logger *log = logger_new(); + Logger *log = logger_new(mem); ASSERT_NE(log, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); ASSERT_NE(mono_time, nullptr); diff --git a/external/toxcore/c-toxcore/toxcore/Makefile.inc b/external/toxcore/c-toxcore/toxcore/Makefile.inc index db3e193..d4d64bc 100644 --- a/external/toxcore/c-toxcore/toxcore/Makefile.inc +++ b/external/toxcore/c-toxcore/toxcore/Makefile.inc @@ -86,6 +86,8 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \ ../toxcore/ping.c \ ../toxcore/shared_key_cache.h \ ../toxcore/shared_key_cache.c \ + ../toxcore/sort.h \ + ../toxcore/sort.c \ ../toxcore/state.h \ ../toxcore/state.c \ ../toxcore/tox.h \ diff --git a/external/toxcore/c-toxcore/toxcore/Messenger.c b/external/toxcore/c-toxcore/toxcore/Messenger.c index 7c9730b..d2a8449 100644 --- a/external/toxcore/c-toxcore/toxcore/Messenger.c +++ b/external/toxcore/c-toxcore/toxcore/Messenger.c @@ -3482,7 +3482,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * return nullptr; } - m->log = logger_new(); + m->log = logger_new(mem); if (m->log == nullptr) { friendreq_kill(m->fr); diff --git a/external/toxcore/c-toxcore/toxcore/Messenger.h b/external/toxcore/c-toxcore/toxcore/Messenger.h index 998a009..be6fb5f 100644 --- a/external/toxcore/c-toxcore/toxcore/Messenger.h +++ b/external/toxcore/c-toxcore/toxcore/Messenger.h @@ -86,6 +86,8 @@ typedef struct Messenger_Options { Messenger_State_Plugin *state_plugins; uint8_t state_plugins_length; + + bool dns_enabled; } Messenger_Options; struct Receipts { diff --git a/external/toxcore/c-toxcore/toxcore/TCP_client.c b/external/toxcore/c-toxcore/toxcore/TCP_client.c index 2b8c6e4..de857bf 100644 --- a/external/toxcore/c-toxcore/toxcore/TCP_client.c +++ b/external/toxcore/c-toxcore/toxcore/TCP_client.c @@ -107,12 +107,12 @@ void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value) * @retval false on failure */ non_null() -static bool connect_sock_to(const Logger *logger, const Memory *mem, Socket sock, const IP_Port *ip_port, const TCP_Proxy_Info *proxy_info) +static bool connect_sock_to(const Network *ns, const Logger *logger, const Memory *mem, Socket sock, const IP_Port *ip_port, const TCP_Proxy_Info *proxy_info) { if (proxy_info->proxy_type != TCP_PROXY_NONE) { - return net_connect(mem, logger, sock, &proxy_info->ip_port); + return net_connect(ns, mem, logger, sock, &proxy_info->ip_port); } else { - return net_connect(mem, logger, sock, ip_port); + return net_connect(ns, mem, logger, sock, ip_port); } } @@ -312,7 +312,7 @@ static int generate_handshake(TCP_Client_Connection *tcp_conn) memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, tcp_conn->con.sent_nonce, CRYPTO_NONCE_SIZE); memcpy(tcp_conn->con.last_packet, tcp_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); random_nonce(tcp_conn->con.rng, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE); - const int len = encrypt_data_symmetric(tcp_conn->con.shared_key, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain, + const int len = encrypt_data_symmetric(tcp_conn->con.mem, tcp_conn->con.shared_key, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain, sizeof(plain), tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); if (len != sizeof(plain) + CRYPTO_MAC_SIZE) { @@ -334,7 +334,7 @@ non_null() static int handle_handshake(TCP_Client_Connection *tcp_conn, const uint8_t *data) { uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE]; - const int len = decrypt_data_symmetric(tcp_conn->con.shared_key, data, data + CRYPTO_NONCE_SIZE, + const int len = decrypt_data_symmetric(tcp_conn->con.mem, tcp_conn->con.shared_key, data, data + CRYPTO_NONCE_SIZE, TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain); if (len != sizeof(plain)) { @@ -617,7 +617,7 @@ TCP_Client_Connection *new_tcp_connection( return nullptr; } - if (!(set_socket_nonblock(ns, sock) && connect_sock_to(logger, mem, sock, ip_port, proxy_info))) { + if (!(set_socket_nonblock(ns, sock) && connect_sock_to(ns, logger, mem, sock, ip_port, proxy_info))) { kill_sock(ns, sock); return nullptr; } diff --git a/external/toxcore/c-toxcore/toxcore/TCP_common.c b/external/toxcore/c-toxcore/toxcore/TCP_common.c index bd3b7ca..6e0ac42 100644 --- a/external/toxcore/c-toxcore/toxcore/TCP_common.c +++ b/external/toxcore/c-toxcore/toxcore/TCP_common.c @@ -157,7 +157,7 @@ int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE); memcpy(packet, &c_length, sizeof(uint16_t)); - int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); + int len = encrypt_data_symmetric(con->mem, con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); if ((unsigned int)len != (packet_size - sizeof(uint16_t))) { return -1; @@ -305,7 +305,7 @@ int read_packet_tcp_secure_connection( *next_packet_length = 0; - const int len = decrypt_data_symmetric(shared_key, recv_nonce, data_encrypted, len_packet, data); + const int len = decrypt_data_symmetric(mem, shared_key, recv_nonce, data_encrypted, len_packet, data); if (len + CRYPTO_MAC_SIZE != len_packet) { LOGGER_ERROR(logger, "decrypted length %d does not match expected length %d", len + CRYPTO_MAC_SIZE, len_packet); diff --git a/external/toxcore/c-toxcore/toxcore/TCP_server.c b/external/toxcore/c-toxcore/toxcore/TCP_server.c index 1363d90..ec686f8 100644 --- a/external/toxcore/c-toxcore/toxcore/TCP_server.c +++ b/external/toxcore/c-toxcore/toxcore/TCP_server.c @@ -327,7 +327,7 @@ static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; encrypt_precompute(data, self_secret_key, shared_key); uint8_t plain[TCP_HANDSHAKE_PLAIN_SIZE]; - int len = decrypt_data_symmetric(shared_key, data + CRYPTO_PUBLIC_KEY_SIZE, + int len = decrypt_data_symmetric(con->con.mem, shared_key, data + CRYPTO_PUBLIC_KEY_SIZE, data + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE, plain); if (len != TCP_HANDSHAKE_PLAIN_SIZE) { @@ -347,7 +347,7 @@ static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con uint8_t response[TCP_SERVER_HANDSHAKE_SIZE]; random_nonce(con->con.rng, response); - len = encrypt_data_symmetric(shared_key, response, resp_plain, TCP_HANDSHAKE_PLAIN_SIZE, + len = encrypt_data_symmetric(con->con.mem, shared_key, response, resp_plain, TCP_HANDSHAKE_PLAIN_SIZE, response + CRYPTO_NONCE_SIZE); if (len != TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE) { diff --git a/external/toxcore/c-toxcore/toxcore/announce.c b/external/toxcore/c-toxcore/toxcore/announce.c index 7bda993..02a378f 100644 --- a/external/toxcore/c-toxcore/toxcore/announce.c +++ b/external/toxcore/c-toxcore/toxcore/announce.c @@ -451,7 +451,7 @@ static int create_reply_plain_store_announce_request(Announcements *announce, return -1; } - if (decrypt_data_symmetric(shared_key, + if (decrypt_data_symmetric(announce->mem, shared_key, data + CRYPTO_PUBLIC_KEY_SIZE, data + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, plain_len + CRYPTO_MAC_SIZE, @@ -568,7 +568,7 @@ static int create_reply(Announcements *announce, const IP_Port *source, VLA(uint8_t, plain, plain_len); const uint8_t *shared_key = dht_get_shared_key_recv(announce->dht, data + 1); - if (decrypt_data_symmetric(shared_key, + if (decrypt_data_symmetric(announce->mem, shared_key, data + 1 + CRYPTO_PUBLIC_KEY_SIZE, data + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, plain_len + CRYPTO_MAC_SIZE, diff --git a/external/toxcore/c-toxcore/toxcore/crypto_core.c b/external/toxcore/c-toxcore/toxcore/crypto_core.c index 7bb5bb9..9a460a2 100644 --- a/external/toxcore/c-toxcore/toxcore/crypto_core.c +++ b/external/toxcore/c-toxcore/toxcore/crypto_core.c @@ -13,6 +13,7 @@ #include "attributes.h" #include "ccompat.h" +#include "mem.h" #include "util.h" static_assert(CRYPTO_PUBLIC_KEY_SIZE == crypto_box_PUBLICKEYBYTES, @@ -88,9 +89,10 @@ const uint8_t *get_chat_id(const Extended_Public_Key *key) } #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) -static uint8_t *crypto_malloc(size_t bytes) +non_null() +static uint8_t *crypto_malloc(const Memory *mem, size_t bytes) { - uint8_t *ptr = (uint8_t *)malloc(bytes); + uint8_t *ptr = (uint8_t *)mem_balloc(mem, bytes); if (ptr != nullptr) { crypto_memlock(ptr, bytes); @@ -99,15 +101,15 @@ static uint8_t *crypto_malloc(size_t bytes) return ptr; } -nullable(1) -static void crypto_free(uint8_t *ptr, size_t bytes) +non_null(1) nullable(2) +static void crypto_free(const Memory *mem, uint8_t *ptr, size_t bytes) { if (ptr != nullptr) { crypto_memzero(ptr, bytes); crypto_memunlock(ptr, bytes); } - free(ptr); + mem_delete(mem, ptr); } #endif /* !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) */ @@ -240,7 +242,8 @@ int32_t encrypt_precompute(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], #endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ } -int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], +int32_t encrypt_data_symmetric(const Memory *mem, + const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *plain, size_t length, uint8_t *encrypted) { @@ -258,12 +261,12 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const size_t size_temp_plain = length + crypto_box_ZEROBYTES; const size_t size_temp_encrypted = length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES; - uint8_t *temp_plain = crypto_malloc(size_temp_plain); - uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted); + uint8_t *temp_plain = crypto_malloc(mem, size_temp_plain); + uint8_t *temp_encrypted = crypto_malloc(mem, size_temp_encrypted); if (temp_plain == nullptr || temp_encrypted == nullptr) { - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); + crypto_free(mem, temp_plain, size_temp_plain); + crypto_free(mem, temp_encrypted, size_temp_encrypted); return -1; } @@ -278,22 +281,23 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, shared_key) != 0) { - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); + crypto_free(mem, temp_plain, size_temp_plain); + crypto_free(mem, temp_encrypted, size_temp_encrypted); return -1; } // Unpad the encrypted message. memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES); - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); + crypto_free(mem, temp_plain, size_temp_plain); + crypto_free(mem, temp_encrypted, size_temp_encrypted); #endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ assert(length < INT32_MAX - crypto_box_MACBYTES); return (int32_t)(length + crypto_box_MACBYTES); } -int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], +int32_t decrypt_data_symmetric(const Memory *mem, + const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t length, uint8_t *plain) { @@ -310,12 +314,12 @@ int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const size_t size_temp_plain = length + crypto_box_ZEROBYTES; const size_t size_temp_encrypted = length + crypto_box_BOXZEROBYTES; - uint8_t *temp_plain = crypto_malloc(size_temp_plain); - uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted); + uint8_t *temp_plain = crypto_malloc(mem, size_temp_plain); + uint8_t *temp_encrypted = crypto_malloc(mem, size_temp_encrypted); if (temp_plain == nullptr || temp_encrypted == nullptr) { - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); + crypto_free(mem, temp_plain, size_temp_plain); + crypto_free(mem, temp_encrypted, size_temp_encrypted); return -1; } @@ -330,22 +334,23 @@ int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce, shared_key) != 0) { - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); + crypto_free(mem, temp_plain, size_temp_plain); + crypto_free(mem, temp_encrypted, size_temp_encrypted); return -1; } memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES); - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); + crypto_free(mem, temp_plain, size_temp_plain); + crypto_free(mem, temp_encrypted, size_temp_encrypted); #endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ assert(length > crypto_box_MACBYTES); assert(length < INT32_MAX); return (int32_t)(length - crypto_box_MACBYTES); } -int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], +int32_t encrypt_data(const Memory *mem, + const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *plain, size_t length, uint8_t *encrypted) @@ -356,12 +361,13 @@ int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], uint8_t k[crypto_box_BEFORENMBYTES]; encrypt_precompute(public_key, secret_key, k); - const int ret = encrypt_data_symmetric(k, nonce, plain, length, encrypted); + const int ret = encrypt_data_symmetric(mem, k, nonce, plain, length, encrypted); crypto_memzero(k, sizeof(k)); return ret; } -int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], +int32_t decrypt_data(const Memory *mem, + const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t length, uint8_t *plain) @@ -372,7 +378,7 @@ int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], uint8_t k[crypto_box_BEFORENMBYTES]; encrypt_precompute(public_key, secret_key, k); - const int ret = decrypt_data_symmetric(k, nonce, encrypted, length, plain); + const int ret = decrypt_data_symmetric(mem, k, nonce, encrypted, length, plain); crypto_memzero(k, sizeof(k)); return ret; } diff --git a/external/toxcore/c-toxcore/toxcore/crypto_core.h b/external/toxcore/c-toxcore/toxcore/crypto_core.h index 979791b..3d405ed 100644 --- a/external/toxcore/c-toxcore/toxcore/crypto_core.h +++ b/external/toxcore/c-toxcore/toxcore/crypto_core.h @@ -16,6 +16,7 @@ #include #include "attributes.h" +#include "mem.h" #ifdef __cplusplus extern "C" { @@ -386,7 +387,8 @@ void crypto_derive_public_key(uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], * @return length of encrypted data if everything was fine. */ non_null() -int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], +int32_t encrypt_data(const Memory *mem, + const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *plain, size_t length, uint8_t *encrypted); @@ -403,7 +405,8 @@ int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], * @return length of plain text data if everything was fine. */ non_null() -int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], +int32_t decrypt_data(const Memory *mem, + const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t length, uint8_t *plain); @@ -431,7 +434,8 @@ int32_t encrypt_precompute(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], * @return length of encrypted data if everything was fine. */ non_null() -int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], +int32_t encrypt_data_symmetric(const Memory *mem, + const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *plain, size_t length, uint8_t *encrypted); @@ -446,7 +450,8 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], * @return length of plain data if everything was fine. */ non_null() -int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], +int32_t decrypt_data_symmetric(const Memory *mem, + const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], const uint8_t *encrypted, size_t length, uint8_t *plain); diff --git a/external/toxcore/c-toxcore/toxcore/crypto_core_test.cc b/external/toxcore/c-toxcore/toxcore/crypto_core_test.cc index d18ae2d..6203afb 100644 --- a/external/toxcore/c-toxcore/toxcore/crypto_core_test.cc +++ b/external/toxcore/c-toxcore/toxcore/crypto_core_test.cc @@ -7,6 +7,7 @@ #include #include "crypto_core_test_util.hh" +#include "mem_test_util.hh" #include "util.h" namespace { @@ -17,8 +18,38 @@ using SecretKey = std::array; using Signature = std::array; using Nonce = std::array; +TEST(PkEqual, TwoRandomIdsAreNotEqual) +{ + std::mt19937 rng; + std::uniform_int_distribution dist{0, UINT8_MAX}; + + uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE]; + + std::generate(std::begin(pk1), std::end(pk1), [&]() { return dist(rng); }); + std::generate(std::begin(pk2), std::end(pk2), [&]() { return dist(rng); }); + + EXPECT_FALSE(pk_equal(pk1, pk2)); +} + +TEST(PkEqual, IdCopyMakesKeysEqual) +{ + std::mt19937 rng; + std::uniform_int_distribution dist{0, UINT8_MAX}; + + uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE]; + uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0}; + + std::generate(std::begin(pk1), std::end(pk1), [&]() { return dist(rng); }); + + pk_copy(pk2, pk1); + + EXPECT_TRUE(pk_equal(pk1, pk2)); +} + TEST(CryptoCore, EncryptLargeData) { + Test_Memory mem; Test_Random rng; Nonce nonce{}; @@ -30,7 +61,8 @@ TEST(CryptoCore, EncryptLargeData) std::vector plain(100 * 1024 * 1024); std::vector encrypted(plain.size() + CRYPTO_MAC_SIZE); - encrypt_data(pk.data(), sk.data(), nonce.data(), plain.data(), plain.size(), encrypted.data()); + encrypt_data( + mem, pk.data(), sk.data(), nonce.data(), plain.data(), plain.size(), encrypted.data()); } TEST(CryptoCore, IncrementNonce) diff --git a/external/toxcore/c-toxcore/toxcore/events/dht_get_nodes_response.c b/external/toxcore/c-toxcore/toxcore/events/dht_get_nodes_response.c index 6e03b73..f637b9c 100644 --- a/external/toxcore/c-toxcore/toxcore/events/dht_get_nodes_response.c +++ b/external/toxcore/c-toxcore/toxcore/events/dht_get_nodes_response.c @@ -158,7 +158,10 @@ static Tox_Event_Dht_Get_Nodes_Response *tox_events_add_dht_get_nodes_response(T event.type = TOX_EVENT_DHT_GET_NODES_RESPONSE; event.data.dht_get_nodes_response = dht_get_nodes_response; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_dht_get_nodes_response_free(dht_get_nodes_response, mem); + return nullptr; + } return dht_get_nodes_response; } diff --git a/external/toxcore/c-toxcore/toxcore/forwarding_fuzz_test.cc b/external/toxcore/c-toxcore/toxcore/forwarding_fuzz_test.cc index da772a1..4b8521a 100644 --- a/external/toxcore/c-toxcore/toxcore/forwarding_fuzz_test.cc +++ b/external/toxcore/c-toxcore/toxcore/forwarding_fuzz_test.cc @@ -46,7 +46,10 @@ void TestSendForwardRequest(Fuzz_Data &input) // rest of the fuzz data is input for malloc and network Fuzz_System sys(input); - Ptr logger(logger_new(), logger_kill); + Ptr logger(logger_new(sys.mem.get()), logger_kill); + if (logger == nullptr) { + return; + } Ptr net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(), &ipp.ip, ipp.port, ipp.port + 100, nullptr), @@ -72,7 +75,10 @@ void TestForwardReply(Fuzz_Data &input) // rest of the fuzz data is input for malloc and network Fuzz_System sys(input); - Ptr logger(logger_new(), logger_kill); + Ptr logger(logger_new(sys.mem.get()), logger_kill); + if (logger == nullptr) { + return; + } Ptr net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(), &ipp.ip, ipp.port, ipp.port + 100, nullptr), diff --git a/external/toxcore/c-toxcore/toxcore/friend_connection.c b/external/toxcore/c-toxcore/toxcore/friend_connection.c index f017b08..9c44288 100644 --- a/external/toxcore/c-toxcore/toxcore/friend_connection.c +++ b/external/toxcore/c-toxcore/toxcore/friend_connection.c @@ -875,6 +875,10 @@ void set_friend_request_callback(Friend_Connections *fr_c, fr_request_cb *fr_req int send_friend_request_packet(Friend_Connections *fr_c, int friendcon_id, uint32_t nospam_num, const uint8_t *data, uint16_t length) { + // TODO(Jfreegman): This max packet size is too large to be handled by receiving clients + // when sent via the onion. We currently limit the length at a higher level, but + // this bounds check should be fixed to represent the max size of a packet that + // the onion client can handle. if (1 + sizeof(nospam_num) + length > ONION_CLIENT_MAX_DATA_SIZE || length == 0) { return -1; } diff --git a/external/toxcore/c-toxcore/toxcore/friend_requests.h b/external/toxcore/c-toxcore/toxcore/friend_requests.h index a78a570..4f3ed0a 100644 --- a/external/toxcore/c-toxcore/toxcore/friend_requests.h +++ b/external/toxcore/c-toxcore/toxcore/friend_requests.h @@ -14,7 +14,8 @@ #include "attributes.h" #include "friend_connection.h" -#define MAX_FRIEND_REQUEST_DATA_SIZE (ONION_CLIENT_MAX_DATA_SIZE - (1 + sizeof(uint32_t))) +// TODO(Jfreegman): This should be the maximum size that an onion client can handle. +#define MAX_FRIEND_REQUEST_DATA_SIZE (ONION_CLIENT_MAX_DATA_SIZE - 100) typedef struct Friend_Requests Friend_Requests; diff --git a/external/toxcore/c-toxcore/toxcore/group.c b/external/toxcore/c-toxcore/toxcore/group.c index 3d96b96..9d2783d 100644 --- a/external/toxcore/c-toxcore/toxcore/group.c +++ b/external/toxcore/c-toxcore/toxcore/group.c @@ -9,7 +9,7 @@ #include "group.h" #include -#include +#include // calloc, free #include #include "DHT.h" @@ -20,9 +20,11 @@ #include "friend_connection.h" #include "group_common.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "net_crypto.h" #include "network.h" +#include "sort.h" #include "state.h" #include "util.h" @@ -957,24 +959,75 @@ static bool delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void /** Order peers with friends first and with more recently active earlier */ non_null() -static int cmp_frozen(const void *a, const void *b) +static bool group_peer_less_handler(const void *object, const void *a, const void *b) { const Group_Peer *pa = (const Group_Peer *)a; const Group_Peer *pb = (const Group_Peer *)b; - if (pa->is_friend ^ pb->is_friend) { - return pa->is_friend ? -1 : 1; + if (((pa->is_friend ? 1 : 0) ^ (pb->is_friend ? 1 : 0)) != 0) { + return pa->is_friend; } - return cmp_uint(pb->last_active, pa->last_active); + return cmp_uint(pb->last_active, pa->last_active) < 0; } +non_null() +static const void *group_peer_get_handler(const void *arr, uint32_t index) +{ + const Group_Peer *entries = (const Group_Peer *)arr; + return &entries[index]; +} + +non_null() +static void group_peer_set_handler(void *arr, uint32_t index, const void *val) +{ + Group_Peer *entries = (Group_Peer *)arr; + const Group_Peer *entry = (const Group_Peer *)val; + entries[index] = *entry; +} + +non_null() +static void *group_peer_subarr_handler(void *arr, uint32_t index, uint32_t size) +{ + Group_Peer *entries = (Group_Peer *)arr; + return &entries[index]; +} + +non_null() +static void *group_peer_alloc_handler(const void *object, uint32_t size) +{ + const Memory *mem = (const Memory *)object; + Group_Peer *tmp = (Group_Peer *)mem_valloc(mem, size, sizeof(Group_Peer)); + + if (tmp == nullptr) { + return nullptr; + } + + return tmp; +} + +non_null() +static void group_peer_delete_handler(const void *object, void *arr, uint32_t size) +{ + const Memory *mem = (const Memory *)object; + mem_delete(mem, arr); +} + +static const Sort_Funcs group_peer_cmp_funcs = { + group_peer_less_handler, + group_peer_get_handler, + group_peer_set_handler, + group_peer_subarr_handler, + group_peer_alloc_handler, + group_peer_delete_handler, +}; + /** @brief Delete frozen peers as necessary to ensure at most `g->maxfrozen` remain. * * @retval true if any frozen peers are removed. */ non_null() -static bool delete_old_frozen(Group_c *g) +static bool delete_old_frozen(Group_c *g, const Memory *mem) { if (g->numfrozen <= g->maxfrozen) { return false; @@ -987,7 +1040,7 @@ static bool delete_old_frozen(Group_c *g) return true; } - qsort(g->frozen, g->numfrozen, sizeof(Group_Peer), cmp_frozen); + merge_sort(g->frozen, g->numfrozen, mem, &group_peer_cmp_funcs); Group_Peer *temp = (Group_Peer *)realloc(g->frozen, g->maxfrozen * sizeof(Group_Peer)); @@ -1032,7 +1085,7 @@ static bool freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, ++g->numfrozen; - delete_old_frozen(g); + delete_old_frozen(g, g_c->m->mem); return true; } @@ -1519,7 +1572,7 @@ int group_set_max_frozen(const Group_Chats *g_c, uint32_t groupnumber, uint32_t } g->maxfrozen = maxfrozen; - delete_old_frozen(g); + delete_old_frozen(g, g_c->m->mem); return 0; } diff --git a/external/toxcore/c-toxcore/toxcore/group_announce_fuzz_test.cc b/external/toxcore/c-toxcore/toxcore/group_announce_fuzz_test.cc index eb0dfb6..9f5655a 100644 --- a/external/toxcore/c-toxcore/toxcore/group_announce_fuzz_test.cc +++ b/external/toxcore/c-toxcore/toxcore/group_announce_fuzz_test.cc @@ -19,7 +19,8 @@ void TestUnpackAnnouncesList(Fuzz_Data &input) // TODO(iphydf): How do we know the packed size? CONSUME1_OR_RETURN(const uint16_t, packed_size, input); - Logger *logger = logger_new(); + Test_Memory mem; + Logger *logger = logger_new(mem); if (gca_unpack_announces_list(logger, input.data(), input.size(), announces.data(), max_count) != -1) { // Always allocate at least something to avoid passing nullptr to functions below. @@ -38,7 +39,8 @@ void TestUnpackPublicAnnounce(Fuzz_Data &input) // TODO(iphydf): How do we know the packed size? CONSUME1_OR_RETURN(const uint16_t, packed_size, input); - Logger *logger = logger_new(); + Test_Memory mem; + Logger *logger = logger_new(mem); if (gca_unpack_public_announce(logger, input.data(), input.size(), &public_announce) != -1) { // Always allocate at least something to avoid passing nullptr to functions below. std::vector packed(packed_size + 1); @@ -50,7 +52,7 @@ void TestUnpackPublicAnnounce(Fuzz_Data &input) void TestDoGca(Fuzz_Data &input) { Test_Memory mem; - std::unique_ptr logger(logger_new(), logger_kill); + std::unique_ptr logger(logger_new(mem), logger_kill); uint64_t clock = 1; std::unique_ptr> mono_time( diff --git a/external/toxcore/c-toxcore/toxcore/group_announce_test.cc b/external/toxcore/c-toxcore/toxcore/group_announce_test.cc index 2918dc7..f1027f3 100644 --- a/external/toxcore/c-toxcore/toxcore/group_announce_test.cc +++ b/external/toxcore/c-toxcore/toxcore/group_announce_test.cc @@ -118,11 +118,12 @@ TEST_F(Announces, AnnouncesGetAndCleanup) struct AnnouncesPack : ::testing::Test { protected: std::vector announces_; + Test_Memory mem_; Logger *logger_ = nullptr; void SetUp() override { - logger_ = logger_new(); + logger_ = logger_new(mem_); ASSERT_NE(logger_, nullptr); // Add an announce without TCP relay. diff --git a/external/toxcore/c-toxcore/toxcore/group_chats.c b/external/toxcore/c-toxcore/toxcore/group_chats.c index 2d64ae6..5e0b788 100644 --- a/external/toxcore/c-toxcore/toxcore/group_chats.c +++ b/external/toxcore/c-toxcore/toxcore/group_chats.c @@ -30,6 +30,7 @@ #include "group_moderation.h" #include "group_pack.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "net_crypto.h" #include "network.h" @@ -1473,8 +1474,8 @@ static bool sign_gc_shared_state(GC_Chat *chat) * Return -2 on decryption failure. * Return -3 if plaintext payload length is invalid. */ -non_null(1, 2, 3, 5, 6) nullable(4) -static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, uint8_t *data, uint64_t *message_id, +non_null(1, 2, 3, 4, 6, 7) nullable(5) +static int group_packet_unwrap(const Logger *log, const Memory *mem, const GC_Connection *gconn, uint8_t *data, uint64_t *message_id, uint8_t *packet_type, const uint8_t *packet, uint16_t length) { assert(data != nullptr); @@ -1492,7 +1493,7 @@ static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, ui return -1; } - int plain_len = decrypt_data_symmetric(gconn->session_shared_key, packet, packet + CRYPTO_NONCE_SIZE, + int plain_len = decrypt_data_symmetric(mem, gconn->session_shared_key, packet, packet + CRYPTO_NONCE_SIZE, length - CRYPTO_NONCE_SIZE, plain); if (plain_len <= 0) { @@ -1533,7 +1534,7 @@ static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, ui } int group_packet_wrap( - const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet, + const Logger *log, const Memory *mem, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet, uint16_t packet_size, const uint8_t *data, uint16_t length, uint64_t message_id, uint8_t gp_packet_type, Net_Packet_Type net_packet_type) { @@ -1588,7 +1589,7 @@ int group_packet_wrap( return -2; } - const int enc_len = encrypt_data_symmetric(shared_key, nonce, plain, plain_len, encrypt); + const int enc_len = encrypt_data_symmetric(mem, shared_key, nonce, plain, plain_len, encrypt); free(plain); @@ -1634,7 +1635,7 @@ static bool send_lossy_group_packet(const GC_Chat *chat, const GC_Connection *gc } const int len = group_packet_wrap( - chat->log, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet, + chat->log, chat->mem, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet, packet_size, data, length, 0, packet_type, NET_PACKET_GC_LOSSY); if (len < 0) { @@ -5508,7 +5509,7 @@ static int handle_gc_broadcast(const GC_Session *c, GC_Chat *chat, uint32_t peer * Return -2 if decryption fails. */ non_null() -static int unwrap_group_handshake_packet(const Logger *log, const uint8_t *self_sk, const uint8_t *sender_pk, +static int unwrap_group_handshake_packet(const Logger *log, const Memory *mem, const uint8_t *self_sk, const uint8_t *sender_pk, uint8_t *plain, size_t plain_size, const uint8_t *packet, uint16_t length) { if (length <= CRYPTO_NONCE_SIZE) { @@ -5516,7 +5517,7 @@ static int unwrap_group_handshake_packet(const Logger *log, const uint8_t *self_ return -1; } - const int plain_len = decrypt_data(sender_pk, self_sk, packet, packet + CRYPTO_NONCE_SIZE, + const int plain_len = decrypt_data(mem, sender_pk, self_sk, packet, packet + CRYPTO_NONCE_SIZE, length - CRYPTO_NONCE_SIZE, plain); if (plain_len < 0 || (uint32_t)plain_len != plain_size) { @@ -5539,7 +5540,7 @@ static int unwrap_group_handshake_packet(const Logger *log, const uint8_t *self_ */ non_null() static int wrap_group_handshake_packet( - const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *self_sk, + const Logger *log, const Memory *mem, const Random *rng, const uint8_t *self_pk, const uint8_t *self_sk, const uint8_t *target_pk, uint8_t *packet, uint32_t packet_size, const uint8_t *data, uint16_t length) { @@ -5558,7 +5559,7 @@ static int wrap_group_handshake_packet( return -2; } - const int enc_len = encrypt_data(target_pk, self_sk, nonce, data, length, encrypt); + const int enc_len = encrypt_data(mem, target_pk, self_sk, nonce, data, length, encrypt); if (enc_len < 0 || (size_t)enc_len != encrypt_buf_size) { LOGGER_ERROR(log, "Failed to encrypt group handshake packet (len: %d)", enc_len); @@ -5622,7 +5623,7 @@ static int make_gc_handshake_packet(const GC_Chat *chat, const GC_Connection *gc } const int enc_len = wrap_group_handshake_packet( - chat->log, chat->rng, chat->self_public_key.enc, chat->self_secret_key.enc, + chat->log, chat->mem, chat->rng, chat->self_public_key.enc, chat->self_secret_key.enc, gconn->addr.public_key.enc, packet, (uint16_t)packet_size, data, length); if (enc_len != GC_MIN_ENCRYPTED_HS_PAYLOAD_SIZE + nodes_size) { @@ -5951,7 +5952,7 @@ static int handle_gc_handshake_packet(GC_Chat *chat, const uint8_t *sender_pk, c return -1; } - const int plain_len = unwrap_group_handshake_packet(chat->log, chat->self_secret_key.enc, sender_pk, data, + const int plain_len = unwrap_group_handshake_packet(chat->log, chat->mem, chat->self_secret_key.enc, sender_pk, data, data_buf_size, packet, length); if (plain_len < GC_MIN_HS_PACKET_PAYLOAD_SIZE) { @@ -6181,7 +6182,7 @@ static bool handle_gc_lossless_packet(const GC_Session *c, GC_Chat *chat, const uint8_t packet_type; uint64_t message_id; - const int len = group_packet_unwrap(chat->log, gconn, data, &message_id, &packet_type, packet, length); + const int len = group_packet_unwrap(chat->log, chat->mem, gconn, data, &message_id, &packet_type, packet, length); if (len < 0) { Ip_Ntoa ip_str; @@ -6334,7 +6335,7 @@ static bool handle_gc_lossy_packet(const GC_Session *c, GC_Chat *chat, const uin uint8_t packet_type; - const int len = group_packet_unwrap(chat->log, gconn, data, nullptr, &packet_type, packet, length); + const int len = group_packet_unwrap(chat->log, chat->mem, gconn, data, nullptr, &packet_type, packet, length); if (len <= 0) { Ip_Ntoa ip_str; diff --git a/external/toxcore/c-toxcore/toxcore/group_chats.h b/external/toxcore/c-toxcore/toxcore/group_chats.h index d22ce40..dfd2bd1 100644 --- a/external/toxcore/c-toxcore/toxcore/group_chats.h +++ b/external/toxcore/c-toxcore/toxcore/group_chats.h @@ -22,6 +22,7 @@ #include "group_common.h" #include "group_connection.h" #include "logger.h" +#include "mem.h" #include "network.h" #define GC_PING_TIMEOUT 12 @@ -141,9 +142,9 @@ int get_peer_number_of_enc_pk(const GC_Chat *chat, const uint8_t *public_enc_key * Return -2 if malloc fails. * Return -3 if encryption fails. */ -non_null(1, 2, 3, 4, 5) nullable(7) +non_null(1, 2, 3, 4, 5, 6) nullable(8) int group_packet_wrap( - const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet, + const Logger *log, const Memory *mem, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet, uint16_t packet_size, const uint8_t *data, uint16_t length, uint64_t message_id, uint8_t gp_packet_type, Net_Packet_Type net_packet_type); diff --git a/external/toxcore/c-toxcore/toxcore/group_common.h b/external/toxcore/c-toxcore/toxcore/group_common.h index daa8fe1..0e965bb 100644 --- a/external/toxcore/c-toxcore/toxcore/group_common.h +++ b/external/toxcore/c-toxcore/toxcore/group_common.h @@ -52,7 +52,7 @@ #define MAX_GC_PACKET_SIZE (MAX_GC_PACKET_CHUNK_SIZE * 100) /* Max number of messages to store in the send/recv arrays */ -#define GCC_BUFFER_SIZE 8192 +#define GCC_BUFFER_SIZE 2048 /** Self UDP status. Must correspond to return values from `ipport_self_copy()`. */ typedef enum Self_UDP_Status { diff --git a/external/toxcore/c-toxcore/toxcore/group_connection.c b/external/toxcore/c-toxcore/toxcore/group_connection.c index 1c2d1ec..6a2fedb 100644 --- a/external/toxcore/c-toxcore/toxcore/group_connection.c +++ b/external/toxcore/c-toxcore/toxcore/group_connection.c @@ -629,7 +629,7 @@ int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connectio } const int enc_len = group_packet_wrap( - chat->log, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet, + chat->log, chat->mem, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet, packet_size, data, length, message_id, packet_type, NET_PACKET_GC_LOSSLESS); if (enc_len < 0) { diff --git a/external/toxcore/c-toxcore/toxcore/group_moderation_test.cc b/external/toxcore/c-toxcore/toxcore/group_moderation_test.cc index ea72023..89555b9 100644 --- a/external/toxcore/c-toxcore/toxcore/group_moderation_test.cc +++ b/external/toxcore/c-toxcore/toxcore/group_moderation_test.cc @@ -191,9 +191,9 @@ struct SanctionsListMod : ::testing::Test { protected: Extended_Public_Key pk; Extended_Secret_Key sk; - Logger *log = logger_new(); Test_Random rng; Test_Memory mem; + Logger *log = logger_new(mem); Moderation mod{mem}; Mod_Sanction sanctions[2] = {}; diff --git a/external/toxcore/c-toxcore/toxcore/group_onion_announce.c b/external/toxcore/c-toxcore/toxcore/group_onion_announce.c index d05db09..6d68013 100644 --- a/external/toxcore/c-toxcore/toxcore/group_onion_announce.c +++ b/external/toxcore/c-toxcore/toxcore/group_onion_announce.c @@ -14,6 +14,7 @@ #include "crypto_core.h" #include "group_announce.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "network.h" #include "onion_announce.h" @@ -76,7 +77,7 @@ void gca_onion_init(GC_Announces_List *group_announce, Onion_Announce *onion_a) } int create_gca_announce_request( - const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, + const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data, const uint8_t *gc_data, uint16_t gc_data_length) @@ -108,7 +109,7 @@ int create_gca_announce_request( random_nonce(rng, packet + 1); memcpy(packet + 1 + CRYPTO_NONCE_SIZE, public_key, CRYPTO_PUBLIC_KEY_SIZE); - const int len = encrypt_data(dest_client_id, secret_key, packet + 1, plain, + const int len = encrypt_data(mem, dest_client_id, secret_key, packet + 1, plain, encrypted_size, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE); const uint32_t full_length = (uint32_t)len + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE; diff --git a/external/toxcore/c-toxcore/toxcore/group_onion_announce.h b/external/toxcore/c-toxcore/toxcore/group_onion_announce.h index 5fbac02..bc9edb1 100644 --- a/external/toxcore/c-toxcore/toxcore/group_onion_announce.h +++ b/external/toxcore/c-toxcore/toxcore/group_onion_announce.h @@ -9,6 +9,7 @@ #include "attributes.h" #include "crypto_core.h" #include "group_announce.h" +#include "mem.h" #include "onion_announce.h" non_null() @@ -16,7 +17,7 @@ void gca_onion_init(GC_Announces_List *group_announce, Onion_Announce *onion_a); non_null() int create_gca_announce_request( - const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, + const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data, const uint8_t *gc_data, uint16_t gc_data_length); diff --git a/external/toxcore/c-toxcore/toxcore/logger.c b/external/toxcore/c-toxcore/toxcore/logger.c index 67fa523..69d7f50 100644 --- a/external/toxcore/c-toxcore/toxcore/logger.c +++ b/external/toxcore/c-toxcore/toxcore/logger.c @@ -13,69 +13,41 @@ #include #include -#include "attributes.h" #include "ccompat.h" +#include "mem.h" struct Logger { + const Memory *mem; + logger_cb *callback; void *context; void *userdata; }; -#ifndef NDEBUG -static const char *logger_level_name(Logger_Level level) -{ - switch (level) { - case LOGGER_LEVEL_TRACE: - return "TRACE"; - - case LOGGER_LEVEL_DEBUG: - return "DEBUG"; - - case LOGGER_LEVEL_INFO: - return "INFO"; - - case LOGGER_LEVEL_WARNING: - return "WARNING"; - - case LOGGER_LEVEL_ERROR: - return "ERROR"; - } - - return ""; -} -#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, - const char *message, void *userdata) -{ -#ifndef NDEBUG - // GL stands for "global logger". - 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 /* NDEBUG */ -} - -static const Logger logger_stderr = { - logger_stderr_handler, - nullptr, - nullptr, -}; - /* * Public Functions */ -Logger *logger_new(void) +Logger *logger_new(const Memory *mem) { - return (Logger *)calloc(1, sizeof(Logger)); + Logger *log = (Logger *)mem_alloc(mem, sizeof(Logger)); + + if (log == nullptr) { + return nullptr; + } + + log->mem = mem; + + return log; } void logger_kill(Logger *log) { - free(log); + if (log == nullptr) { + return; + } + + mem_delete(log->mem, log); } void logger_callback_log(Logger *log, logger_cb *function, void *context, void *userdata) @@ -89,7 +61,7 @@ void logger_write(const Logger *log, Logger_Level level, const char *file, int l const char *format, ...) { if (log == nullptr) { - log = &logger_stderr; + return; } if (log->callback == nullptr) { diff --git a/external/toxcore/c-toxcore/toxcore/logger.h b/external/toxcore/c-toxcore/toxcore/logger.h index 830db88..1c7c007 100644 --- a/external/toxcore/c-toxcore/toxcore/logger.h +++ b/external/toxcore/c-toxcore/toxcore/logger.h @@ -12,6 +12,7 @@ #include #include "attributes.h" +#include "mem.h" #ifdef __cplusplus extern "C" { @@ -38,7 +39,8 @@ typedef void logger_cb(void *context, Logger_Level level, const char *file, int /** * Creates a new logger with logging disabled (callback is NULL) by default. */ -Logger *logger_new(void); +non_null() +Logger *logger_new(const Memory *mem); /** * Frees all resources associated with the logger. diff --git a/external/toxcore/c-toxcore/toxcore/net_crypto.c b/external/toxcore/c-toxcore/toxcore/net_crypto.c index 5aafe8a..c17ff6c 100644 --- a/external/toxcore/c-toxcore/toxcore/net_crypto.c +++ b/external/toxcore/c-toxcore/toxcore/net_crypto.c @@ -230,7 +230,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin packet[0] = NET_PACKET_COOKIE_REQUEST; memcpy(packet + 1, dht_get_self_public_key(c->dht), CRYPTO_PUBLIC_KEY_SIZE); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE); - const int len = encrypt_data_symmetric(shared_key, nonce, plain, sizeof(plain), + const int len = encrypt_data_symmetric(c->mem, shared_key, nonce, plain, sizeof(plain), packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); if (len != COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE) { @@ -246,7 +246,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin * @retval 0 on success. */ non_null() -static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes, +static int create_cookie(const Memory *mem, const Random *rng, const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes, const uint8_t *encryption_key) { uint8_t contents[COOKIE_CONTENTS_LENGTH]; @@ -254,7 +254,7 @@ static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t memcpy(contents, &temp_time, sizeof(temp_time)); memcpy(contents + sizeof(temp_time), bytes, COOKIE_DATA_LENGTH); random_nonce(rng, cookie); - const int len = encrypt_data_symmetric(encryption_key, cookie, contents, sizeof(contents), cookie + CRYPTO_NONCE_SIZE); + const int len = encrypt_data_symmetric(mem, encryption_key, cookie, contents, sizeof(contents), cookie + CRYPTO_NONCE_SIZE); if (len != COOKIE_LENGTH - CRYPTO_NONCE_SIZE) { return -1; @@ -269,11 +269,11 @@ static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t * @retval 0 on success. */ non_null() -static int open_cookie(const Mono_Time *mono_time, uint8_t *bytes, const uint8_t *cookie, +static int open_cookie(const Memory *mem, const Mono_Time *mono_time, uint8_t *bytes, const uint8_t *cookie, const uint8_t *encryption_key) { uint8_t contents[COOKIE_CONTENTS_LENGTH]; - const int len = decrypt_data_symmetric(encryption_key, cookie, cookie + CRYPTO_NONCE_SIZE, + const int len = decrypt_data_symmetric(mem, encryption_key, cookie, cookie + CRYPTO_NONCE_SIZE, COOKIE_LENGTH - CRYPTO_NONCE_SIZE, contents); if (len != sizeof(contents)) { @@ -308,14 +308,14 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)]; - if (create_cookie(c->rng, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) { + if (create_cookie(c->mem, c->rng, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) { return -1; } memcpy(plain + COOKIE_LENGTH, request_plain + COOKIE_DATA_LENGTH, sizeof(uint64_t)); packet[0] = NET_PACKET_COOKIE_RESPONSE; random_nonce(c->rng, packet + 1); - const int len = encrypt_data_symmetric(shared_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE); + const int len = encrypt_data_symmetric(c->mem, shared_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE); if (len != COOKIE_RESPONSE_LENGTH - (1 + CRYPTO_NONCE_SIZE)) { return -1; @@ -342,7 +342,7 @@ static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, ui memcpy(dht_public_key, packet + 1, CRYPTO_PUBLIC_KEY_SIZE); const uint8_t *tmp_shared_key = dht_get_shared_key_sent(c->dht, dht_public_key); memcpy(shared_key, tmp_shared_key, CRYPTO_SHARED_KEY_SIZE); - const int len = decrypt_data_symmetric(shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, + const int len = decrypt_data_symmetric(c->mem, shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE, request_plain); @@ -439,7 +439,7 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_c * @retval COOKIE_LENGTH on success. */ non_null() -static int handle_cookie_response(uint8_t *cookie, uint64_t *number, +static int handle_cookie_response(const Memory *mem, uint8_t *cookie, uint64_t *number, const uint8_t *packet, uint16_t length, const uint8_t *shared_key) { @@ -448,7 +448,7 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, } uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)]; - const int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, + const int len = decrypt_data_symmetric(mem, shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, length - (1 + CRYPTO_NONCE_SIZE), plain); if (len != sizeof(plain)) { @@ -481,13 +481,13 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); - if (create_cookie(c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, + if (create_cookie(c->mem, c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, cookie_plain, c->secret_symmetric_key) != 0) { return -1; } random_nonce(c->rng, packet + 1 + COOKIE_LENGTH); - const int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain), + const int len = encrypt_data(c->mem, peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain), packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE); if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) { @@ -528,7 +528,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - if (open_cookie(c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { + if (open_cookie(c->mem, c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { return false; } @@ -540,7 +540,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH); uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; - const int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, + const int len = decrypt_data(c->mem, cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE, HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain); @@ -1084,7 +1084,7 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ VLA(uint8_t, packet, packet_size); packet[0] = NET_PACKET_CRYPTO_DATA; memcpy(packet + 1, conn->sent_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t)); - const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); + const int len = encrypt_data_symmetric(c->mem, conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); if (len + 1 + sizeof(uint16_t) != packet_size) { LOGGER_ERROR(c->log, "encryption failed: %d", len); @@ -1255,7 +1255,7 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint net_unpack_u16(packet + 1, &num); const uint16_t diff = num - num_cur_nonce; increment_nonce_number(nonce, diff); - const int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t), + const int len = decrypt_data_symmetric(c->mem, conn->shared_key, nonce, packet + 1 + sizeof(uint16_t), length - (1 + sizeof(uint16_t)), data); if ((unsigned int)len != length - crypto_packet_overhead) { @@ -1662,7 +1662,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, uint8_t cookie[COOKIE_LENGTH]; uint64_t number; - if (handle_cookie_response(cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) { + if (handle_cookie_response(c->mem, cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) { return -1; } diff --git a/external/toxcore/c-toxcore/toxcore/network.c b/external/toxcore/c-toxcore/toxcore/network.c index 55aa4e2..03bea7e 100644 --- a/external/toxcore/c-toxcore/toxcore/network.c +++ b/external/toxcore/c-toxcore/toxcore/network.c @@ -513,6 +513,12 @@ static int sys_listen(void *obj, Socket sock, int backlog) return listen(net_socket_to_native(sock), backlog); } +non_null() +static int sys_connect(void *obj, Socket sock, const Network_Addr *addr) +{ + return connect(net_socket_to_native(sock), (const struct sockaddr *)&addr->addr, addr->size); +} + non_null() static int sys_recvbuf(void *obj, Socket sock) { @@ -586,11 +592,98 @@ static int sys_setsockopt(void *obj, Socket sock, int level, int optname, const return setsockopt(net_socket_to_native(sock), level, optname, (const char *)optval, optlen); } +// sets and fills an array of addrs for address +// returns the number of entries in addrs +non_null() +static int sys_getaddrinfo(void *obj, const Memory *mem, const char *address, int family, int sock_type, Network_Addr **addrs) +{ + assert(addrs != nullptr); + + struct addrinfo hints = {0}; + hints.ai_family = family; + + + // different platforms favour a different field + // hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses. + hints.ai_socktype = sock_type; + // hints.ai_protocol = protocol; + + struct addrinfo *infos = nullptr; + + const int rc = getaddrinfo(address, nullptr, &hints, &infos); + + // Lookup failed. + if (rc != 0) { + // TODO(Green-Sky): log error + return 0; + } + + const int32_t max_count = INT32_MAX / sizeof(Network_Addr); + + // we count number of "valid" results + int result = 0; + for (struct addrinfo *walker = infos; walker != nullptr && result < max_count; walker = walker->ai_next) { + if (walker->ai_family == family || family == AF_UNSPEC) { + ++result; + } + + // do we need to check socktype/protocol? + } + + assert(max_count >= result); + + Network_Addr *tmp_addrs = (Network_Addr *)mem_valloc(mem, result, sizeof(Network_Addr)); + if (tmp_addrs == nullptr) { + freeaddrinfo(infos); + return 0; + } + + // now we fill in + int i = 0; + for (struct addrinfo *walker = infos; walker != nullptr; walker = walker->ai_next) { + if (walker->ai_family == family || family == AF_UNSPEC) { + tmp_addrs[i].size = sizeof(struct sockaddr_storage); + tmp_addrs[i].addr.ss_family = walker->ai_family; + + // according to spec, storage is supposed to be large enough (and source shows they are) + // storage is 128 bytes + assert(walker->ai_addrlen <= tmp_addrs[i].size); + + memcpy(&tmp_addrs[i].addr, walker->ai_addr, walker->ai_addrlen); + tmp_addrs[i].size = walker->ai_addrlen; + + ++i; + } + } + + assert(i == result); + + freeaddrinfo(infos); + + *addrs = tmp_addrs; + + // number of entries in addrs + return result; +} + +non_null() +static int sys_freeaddrinfo(void *obj, const Memory *mem, Network_Addr *addrs) +{ + if (addrs == nullptr) { + return 0; + } + + mem_delete(mem, addrs); + + return 0; +} + static const Network_Funcs os_network_funcs = { sys_close, sys_accept, sys_bind, sys_listen, + sys_connect, sys_recvbuf, sys_recv, sys_recvfrom, @@ -600,8 +693,10 @@ static const Network_Funcs os_network_funcs = { sys_socket_nonblock, sys_getsockopt, sys_setsockopt, + sys_getaddrinfo, + sys_freeaddrinfo, }; -static const Network os_network_obj = {&os_network_funcs}; +static const Network os_network_obj = {&os_network_funcs, nullptr}; const Network *os_network(void) { @@ -882,7 +977,11 @@ bool set_socket_nosigpipe(const Network *ns, Socket sock) bool set_socket_reuseaddr(const Network *ns, Socket sock) { int set = 1; +#if defined(OS_WIN32) + return net_setsockopt(ns, sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, &set, sizeof(set)) == 0; +#else return net_setsockopt(ns, sock, SOL_SOCKET, SO_REUSEADDR, &set, sizeof(set)) == 0; +#endif /* OS_WIN32 */ } bool set_socket_dualstack(const Network *ns, Socket sock) @@ -1815,37 +1914,34 @@ bool addr_parse_ip(const char *address, IP *to) * prefers v6 if `ip.family` was TOX_AF_UNSPEC and both available * Returns in `*extra` an IPv4 address, if family was TOX_AF_UNSPEC and `*to` is TOX_AF_INET6 * - * @return 0 on failure, `TOX_ADDR_RESOLVE_*` on success. + * @return false on failure, true on success. */ -non_null(1, 2, 3) nullable(4) -static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extra) +non_null(1, 2, 3, 4) nullable(5) +static bool addr_resolve(const Network *ns, const Memory *mem, const char *address, IP *to, IP *extra) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if ((true)) { - return 0; + return false; } #endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ if (address == nullptr || to == nullptr) { - return 0; + return false; } const Family tox_family = to->family; const int family = make_family(tox_family); - struct addrinfo hints = {0}; - hints.ai_family = family; - hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses. + Network_Addr *addrs = nullptr; + const int rc = ns->funcs->getaddrinfo(ns->obj, mem, address, family, 0, &addrs); - struct addrinfo *server = nullptr; - - const int rc = getaddrinfo(address, nullptr, &hints, &server); - - // Lookup failed. - if (rc != 0) { - return 0; + // Lookup failed / empty. + if (rc <= 0) { + return false; } + assert(addrs != nullptr); + IP ip4; ip_init(&ip4, false); // ipv6enabled = false IP ip6; @@ -1854,16 +1950,16 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr int result = 0; bool done = false; - for (struct addrinfo *walker = server; walker != nullptr && !done; walker = walker->ai_next) { - switch (walker->ai_family) { + for (int i = 0; i < rc && !done; ++i) { + switch (addrs[i].addr.ss_family) { case AF_INET: { - if (walker->ai_family == family) { /* AF_INET requested, done */ - const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)walker->ai_addr; + if (addrs[i].addr.ss_family == family) { /* AF_INET requested, done */ + const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)&addrs[i].addr; get_ip4(&to->ip.v4, &addr->sin_addr); result = TOX_ADDR_RESOLVE_INET; done = true; } else if ((result & TOX_ADDR_RESOLVE_INET) == 0) { /* AF_UNSPEC requested, store away */ - const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)walker->ai_addr; + const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)&addrs[i].addr; get_ip4(&ip4.ip.v4, &addr->sin_addr); result |= TOX_ADDR_RESOLVE_INET; } @@ -1872,16 +1968,16 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr } case AF_INET6: { - if (walker->ai_family == family) { /* AF_INET6 requested, done */ - if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { - const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(void *)walker->ai_addr; + if (addrs[i].addr.ss_family == family) { /* AF_INET6 requested, done */ + if (addrs[i].size == sizeof(struct sockaddr_in6)) { + const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(void *)&addrs[i].addr; get_ip6(&to->ip.v6, &addr->sin6_addr); result = TOX_ADDR_RESOLVE_INET6; done = true; } } else if ((result & TOX_ADDR_RESOLVE_INET6) == 0) { /* AF_UNSPEC requested, store away */ - if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { - const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(void *)walker->ai_addr; + if (addrs[i].size == sizeof(struct sockaddr_in6)) { + const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(void *)&addrs[i].addr; get_ip6(&ip6.ip.v6, &addr->sin6_addr); result |= TOX_ADDR_RESOLVE_INET6; } @@ -1906,37 +2002,34 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr } } - freeaddrinfo(server); - return result; + ns->funcs->freeaddrinfo(ns->obj, mem, addrs); + return result != 0; } -bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP *extra) +bool addr_resolve_or_parse_ip(const Network *ns, const Memory *mem, const char *address, IP *to, IP *extra, bool dns_enabled) { - if (addr_resolve(ns, address, to, extra) == 0) { - if (!addr_parse_ip(address, to)) { - return false; - } + if (dns_enabled && addr_resolve(ns, mem, address, to, extra)) { + return true; } - return true; + return addr_parse_ip(address, to); } -bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port) +bool net_connect(const Network *ns, const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port) { - struct sockaddr_storage addr = {0}; - size_t addrsize; + Network_Addr addr = {{0}}; if (net_family_is_ipv4(ip_port->ip.family)) { - struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; + struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr.addr; - addrsize = sizeof(struct sockaddr_in); + addr.size = sizeof(struct sockaddr_in); addr4->sin_family = AF_INET; fill_addr4(&ip_port->ip.ip.v4, &addr4->sin_addr); addr4->sin_port = ip_port->port; } else if (net_family_is_ipv6(ip_port->ip.family)) { - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr.addr; - addrsize = sizeof(struct sockaddr_in6); + addr.size = sizeof(struct sockaddr_in6); addr6->sin6_family = AF_INET6; fill_addr6(&ip_port->ip.ip.v6, &addr6->sin6_addr); addr6->sin6_port = ip_port->port; @@ -1958,7 +2051,7 @@ bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Por net_socket_to_native(sock), net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port)); errno = 0; - if (connect(net_socket_to_native(sock), (struct sockaddr *)&addr, addrsize) == -1) { + if (ns->funcs->connect(ns->obj, sock, &addr) == -1) { const int error = net_error(); // Non-blocking socket: "Operation in progress" means it's connecting. @@ -1974,7 +2067,7 @@ bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Por return true; } -int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type) +int32_t net_getipport(const Network *ns, const Memory *mem, const char *node, IP_Port **res, int tox_type, bool dns_enabled) { assert(node != nullptr); @@ -1996,6 +2089,10 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to return 1; } + if (!dns_enabled) { + return -1; + } + #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if ((true)) { IP_Port *ip_port = (IP_Port *)mem_alloc(mem, sizeof(IP_Port)); @@ -2010,25 +2107,29 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to } #endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ - // It's not an IP address, so now we try doing a DNS lookup. - struct addrinfo *infos; - const int ret = getaddrinfo(node, nullptr, nullptr, &infos); + int type = make_socktype(tox_type); + // ugly + if (tox_type == -1) { + type = 0; + } - if (ret != 0) { + // It's not an IP address, so now we try doing a DNS lookup. + Network_Addr *addrs = nullptr; + const int rc = ns->funcs->getaddrinfo(ns->obj, mem, node, AF_UNSPEC, type, &addrs); + + // Lookup failed / empty. + if (rc <= 0) { return -1; } + assert(addrs != nullptr); + // Used to avoid calloc parameter overflow const size_t max_count = min_u64(SIZE_MAX, INT32_MAX) / sizeof(IP_Port); - const int type = make_socktype(tox_type); size_t count = 0; - for (struct addrinfo *cur = infos; count < max_count && cur != nullptr; cur = cur->ai_next) { - if (cur->ai_socktype != 0 && type > 0 && cur->ai_socktype != type) { - continue; - } - - if (cur->ai_family != AF_INET && cur->ai_family != AF_INET6) { + for (int i = 0; i < rc && count < max_count; ++i) { + if (addrs[i].addr.ss_family != AF_INET && addrs[i].addr.ss_family != AF_INET6) { continue; } @@ -2038,40 +2139,36 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to assert(count <= max_count); if (count == 0) { - freeaddrinfo(infos); + ns->funcs->freeaddrinfo(ns->obj, mem, addrs); return 0; } IP_Port *ip_port = (IP_Port *)mem_valloc(mem, count, sizeof(IP_Port)); if (ip_port == nullptr) { - freeaddrinfo(infos); + ns->funcs->freeaddrinfo(ns->obj, mem, addrs); *res = nullptr; return -1; } *res = ip_port; - for (struct addrinfo *cur = infos; cur != nullptr; cur = cur->ai_next) { - 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; + for (int i = 0; i < rc && count < max_count; ++i) { + if (addrs[i].addr.ss_family == AF_INET) { + const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)&addrs[i].addr; 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; + } else if (addrs[i].addr.ss_family == AF_INET6) { + const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(const void *)&addrs[i].addr; memcpy(ip_port->ip.ip.v6.uint8, addr->sin6_addr.s6_addr, sizeof(IP6)); } else { continue; } - const Family *const family = make_tox_family(cur->ai_family); + const Family *const family = make_tox_family(addrs[i].addr.ss_family); assert(family != nullptr); if (family == nullptr) { - freeaddrinfo(infos); + ns->funcs->freeaddrinfo(ns->obj, mem, addrs); return -1; } @@ -2080,7 +2177,7 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to ++ip_port; } - freeaddrinfo(infos); + ns->funcs->freeaddrinfo(ns->obj, mem, addrs); return count; } diff --git a/external/toxcore/c-toxcore/toxcore/network.h b/external/toxcore/c-toxcore/toxcore/network.h index 06857b8..84c2433 100644 --- a/external/toxcore/c-toxcore/toxcore/network.h +++ b/external/toxcore/c-toxcore/toxcore/network.h @@ -39,6 +39,7 @@ 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_connect_cb(void *obj, Socket sock, const Network_Addr *addr); 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); @@ -48,8 +49,8 @@ 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); +typedef int net_getaddrinfo_cb(void *obj, const Memory *mem, const char *address, int family, int protocol, Network_Addr **addrs); +typedef int net_freeaddrinfo_cb(void *obj, const Memory *mem, Network_Addr *addrs); /** @brief Functions wrapping POSIX network functions. * @@ -61,6 +62,7 @@ typedef struct Network_Funcs { net_accept_cb *accept; net_bind_cb *bind; net_listen_cb *listen; + net_connect_cb *connect; net_recvbuf_cb *recvbuf; net_recv_cb *recv; net_recvfrom_cb *recvfrom; @@ -396,21 +398,23 @@ non_null() void ipport_copy(IP_Port *target, const IP_Port *source); /** - * Resolves string into an IP address + * @brief Resolves string into an IP address. * - * @param address a hostname (or something parseable to an IP address) - * @param to to.family MUST be initialized, either set to a specific IP version + * @param[in,out] ns Network object. + * @param[in] address a hostname (or something parseable to an IP address). + * @param[in,out] to to.family MUST be initialized, either set to a specific IP version * (TOX_AF_INET/TOX_AF_INET6) or to the unspecified TOX_AF_UNSPEC (0), if both - * IP versions are acceptable - * @param extra can be NULL and is only set in special circumstances, see returns + * IP versions are acceptable. + * @param[out] extra can be NULL and is only set in special circumstances, see returns. + * @param[in] dns_enabled if false, DNS resolution is skipped. * - * Returns in `*to` a matching address (IPv6 or IPv4) - * Returns in `*extra`, if not NULL, an IPv4 address, if `to->family` was TOX_AF_UNSPEC + * Returns in `*to` a matching address (IPv6 or IPv4). + * Returns in `*extra`, if not NULL, an IPv4 address, if `to->family` was `TOX_AF_UNSPEC`. * * @return true on success, false on failure */ -non_null(1, 2, 3) nullable(4) -bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP *extra); +non_null(1, 2, 3, 4) nullable(5) +bool addr_resolve_or_parse_ip(const Network *ns, const Memory *mem, const char *address, IP *to, IP *extra, bool dns_enabled); /** @brief Function to receive data, ip and port of sender is put into ip_port. * Packet data is put into data. @@ -501,7 +505,7 @@ void networking_poll(const Networking_Core *net, void *userdata); * Return false on failure. */ non_null() -bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port); +bool net_connect(const Network *ns, const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port); /** @brief High-level getaddrinfo implementation. * @@ -510,14 +514,21 @@ bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Por * address that can be specified by calling `net_connect()`, the port is ignored. * * Skip all addresses with socktype != type (use type = -1 to get all addresses) - * To correctly deallocate array memory use `net_freeipport()` + * To correctly deallocate array memory use `net_freeipport()`. + * + * @param ns Network object. + * @param mem Memory allocator. + * @param node The node parameter identifies the host or service on which to connect. + * @param[out] res An array of IP_Port structures will be allocated into this pointer. + * @param tox_type The type of socket to use (stream or datagram), only relevant for DNS lookups. + * @param dns_enabled If false, DNS resolution is skipped, when passed a hostname, this function will return an error. * * @return number of elements in res array. * @retval 0 if res array empty. * @retval -1 on error. */ non_null() -int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type); +int32_t net_getipport(const Network *ns, const Memory *mem, const char *node, IP_Port **res, int tox_type, bool dns_enabled); /** Deallocates memory allocated by net_getipport */ non_null(1) nullable(2) diff --git a/external/toxcore/c-toxcore/toxcore/network_test_util.cc b/external/toxcore/c-toxcore/toxcore/network_test_util.cc index 758e495..c8d2ff3 100644 --- a/external/toxcore/c-toxcore/toxcore/network_test_util.cc +++ b/external/toxcore/c-toxcore/toxcore/network_test_util.cc @@ -3,6 +3,7 @@ #include #include "crypto_core.h" +#include "mem.h" #include "network.h" #include "test_util.hh" @@ -11,6 +12,7 @@ Network_Funcs const Network_Class::vtable = { Method::invoke<&Network_Class::accept>, Method::invoke<&Network_Class::bind>, Method::invoke<&Network_Class::listen>, + Method::invoke<&Network_Class::connect>, Method::invoke<&Network_Class::recvbuf>, Method::invoke<&Network_Class::recv>, Method::invoke<&Network_Class::recvfrom>, @@ -34,6 +36,10 @@ int Test_Network::listen(void *obj, Socket sock, int backlog) { return net->funcs->listen(net->obj, sock, backlog); } +int Test_Network::connect(void *obj, Socket sock, const Network_Addr *addr) +{ + return net->funcs->connect(net->obj, sock, addr); +} 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) { @@ -70,13 +76,14 @@ int Test_Network::setsockopt( { return net->funcs->setsockopt(net->obj, sock, level, optname, optval, optlen); } -int Test_Network::getaddrinfo(void *obj, int family, Network_Addr **addrs) +int Test_Network::getaddrinfo(void *obj, const Memory *mem, const char *address, int family, + int protocol, Network_Addr **addrs) { - return net->funcs->getaddrinfo(net->obj, family, addrs); + return net->funcs->getaddrinfo(net->obj, mem, address, family, protocol, addrs); } -int Test_Network::freeaddrinfo(void *obj, Network_Addr *addrs) +int Test_Network::freeaddrinfo(void *obj, const Memory *mem, Network_Addr *addrs) { - return net->funcs->freeaddrinfo(net->obj, addrs); + return net->funcs->freeaddrinfo(net->obj, mem, addrs); } Network_Class::~Network_Class() = default; diff --git a/external/toxcore/c-toxcore/toxcore/network_test_util.hh b/external/toxcore/c-toxcore/toxcore/network_test_util.hh index 70f238a..be967d3 100644 --- a/external/toxcore/c-toxcore/toxcore/network_test_util.hh +++ b/external/toxcore/c-toxcore/toxcore/network_test_util.hh @@ -4,6 +4,7 @@ #include #include "crypto_core.h" +#include "mem.h" #include "network.h" #include "test_util.hh" @@ -24,6 +25,7 @@ struct Network_Class { virtual net_accept_cb accept = 0; virtual net_bind_cb bind = 0; virtual net_listen_cb listen = 0; + virtual net_connect_cb connect = 0; virtual net_recvbuf_cb recvbuf = 0; virtual net_recv_cb recv = 0; virtual net_recvfrom_cb recvfrom = 0; @@ -48,6 +50,7 @@ class Test_Network : public Network_Class { 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 connect(void *obj, Socket sock, const Network_Addr *addr) 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; @@ -60,8 +63,9 @@ class Test_Network : public Network_Class { 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; + int getaddrinfo(void *obj, const Memory *mem, const char *address, int family, int protocol, + Network_Addr **addrs) override; + int freeaddrinfo(void *obj, const Memory *mem, Network_Addr *addrs) override; }; template <> diff --git a/external/toxcore/c-toxcore/toxcore/onion.c b/external/toxcore/c-toxcore/toxcore/onion.c index 9fab57a..722d610 100644 --- a/external/toxcore/c-toxcore/toxcore/onion.c +++ b/external/toxcore/c-toxcore/toxcore/onion.c @@ -180,7 +180,7 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_ * return -1 on failure. * return length of created packet on success. */ -int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_length, +int create_onion_packet(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length) { @@ -202,7 +202,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_ ipport_pack(step2, &path->ip_port3); memcpy(step2 + SIZE_IPPORT, path->public_key3, CRYPTO_PUBLIC_KEY_SIZE); - int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, step1_size, + int len = encrypt_data_symmetric(mem, path->shared_key3, nonce, step1, step1_size, step2 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE); if (len != SIZE_IPPORT + length + CRYPTO_MAC_SIZE) { @@ -213,7 +213,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_ VLA(uint8_t, step3, step3_size); ipport_pack(step3, &path->ip_port2); memcpy(step3 + SIZE_IPPORT, path->public_key2, CRYPTO_PUBLIC_KEY_SIZE); - len = encrypt_data_symmetric(path->shared_key2, nonce, step2, step2_size, + len = encrypt_data_symmetric(mem, path->shared_key2, nonce, step2, step2_size, step3 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE); if (len != SIZE_IPPORT + SEND_BASE + length + CRYPTO_MAC_SIZE) { @@ -224,7 +224,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_ memcpy(packet + 1, nonce, CRYPTO_NONCE_SIZE); memcpy(packet + 1 + CRYPTO_NONCE_SIZE, path->public_key1, CRYPTO_PUBLIC_KEY_SIZE); - len = encrypt_data_symmetric(path->shared_key1, nonce, step3, step3_size, + len = encrypt_data_symmetric(mem, path->shared_key1, nonce, step3, step3_size, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE); if (len != SIZE_IPPORT + SEND_BASE * 2 + length + CRYPTO_MAC_SIZE) { @@ -243,7 +243,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_ * return -1 on failure. * return length of created packet on success. */ -int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_packet_length, +int create_onion_packet_tcp(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length) { @@ -265,7 +265,7 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac ipport_pack(step2, &path->ip_port3); memcpy(step2 + SIZE_IPPORT, path->public_key3, CRYPTO_PUBLIC_KEY_SIZE); - int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, step1_size, + int len = encrypt_data_symmetric(mem, path->shared_key3, nonce, step1, step1_size, step2 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE); if (len != SIZE_IPPORT + length + CRYPTO_MAC_SIZE) { @@ -274,7 +274,7 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac ipport_pack(packet + CRYPTO_NONCE_SIZE, &path->ip_port2); memcpy(packet + CRYPTO_NONCE_SIZE + SIZE_IPPORT, path->public_key2, CRYPTO_PUBLIC_KEY_SIZE); - len = encrypt_data_symmetric(path->shared_key2, nonce, step2, step2_size, + len = encrypt_data_symmetric(mem, path->shared_key2, nonce, step2, step2_size, packet + CRYPTO_NONCE_SIZE + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE); if (len != SIZE_IPPORT + SEND_BASE + length + CRYPTO_MAC_SIZE) { @@ -355,7 +355,7 @@ static int handle_send_initial(void *object, const IP_Port *source, const uint8_ } const int len = decrypt_data_symmetric( - shared_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_length, plain); + onion->mem, shared_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_length, plain); if (len != plaintext_length) { LOGGER_TRACE(onion->log, "decrypt failed: %d != %d", len, plaintext_length); @@ -393,7 +393,7 @@ int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, const I uint16_t data_len = 1 + CRYPTO_NONCE_SIZE + (len - SIZE_IPPORT); uint8_t *ret_part = data + data_len; random_nonce(onion->rng, ret_part); - len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ip_port, SIZE_IPPORT, + len = encrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, ret_part, ip_port, SIZE_IPPORT, ret_part + CRYPTO_NONCE_SIZE); if (len != SIZE_IPPORT + CRYPTO_MAC_SIZE) { @@ -436,7 +436,7 @@ static int handle_send_1(void *object, const IP_Port *source, const uint8_t *pac return 1; } - int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, + int len = decrypt_data_symmetric(onion->mem, shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_1), plain); if (len != length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_1 + CRYPTO_MAC_SIZE)) { @@ -459,7 +459,7 @@ static int handle_send_1(void *object, const IP_Port *source, const uint8_t *pac uint8_t ret_data[RETURN_1 + SIZE_IPPORT]; ipport_pack(ret_data, source); memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_1), RETURN_1); - len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data), + len = encrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data), ret_part + CRYPTO_NONCE_SIZE); if (len != RETURN_2 - CRYPTO_NONCE_SIZE) { @@ -502,7 +502,7 @@ static int handle_send_2(void *object, const IP_Port *source, const uint8_t *pac return 1; } - int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, + int len = decrypt_data_symmetric(onion->mem, shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_2), plain); if (len != length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_2 + CRYPTO_MAC_SIZE)) { @@ -532,7 +532,7 @@ static int handle_send_2(void *object, const IP_Port *source, const uint8_t *pac uint8_t ret_data[RETURN_2 + SIZE_IPPORT]; ipport_pack(ret_data, source); memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_2), RETURN_2); - len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data), + len = encrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data), ret_part + CRYPTO_NONCE_SIZE); if (len != RETURN_3 - CRYPTO_NONCE_SIZE) { @@ -574,7 +574,7 @@ static int handle_recv_3(void *object, const IP_Port *source, const uint8_t *pac change_symmetric_key(onion); uint8_t plain[SIZE_IPPORT + RETURN_2]; - const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, + const int len = decrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, SIZE_IPPORT + RETURN_2 + CRYPTO_MAC_SIZE, plain); if ((uint32_t)len != sizeof(plain)) { @@ -627,7 +627,7 @@ static int handle_recv_2(void *object, const IP_Port *source, const uint8_t *pac change_symmetric_key(onion); uint8_t plain[SIZE_IPPORT + RETURN_1]; - const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, + const int len = decrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, SIZE_IPPORT + RETURN_1 + CRYPTO_MAC_SIZE, plain); if ((uint32_t)len != sizeof(plain)) { @@ -679,7 +679,7 @@ static int handle_recv_1(void *object, const IP_Port *source, const uint8_t *pac change_symmetric_key(onion); uint8_t plain[SIZE_IPPORT]; - const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, + const int len = decrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, SIZE_IPPORT + CRYPTO_MAC_SIZE, plain); if ((uint32_t)len != SIZE_IPPORT) { diff --git a/external/toxcore/c-toxcore/toxcore/onion.h b/external/toxcore/c-toxcore/toxcore/onion.h index a5d3554..ef8fdb7 100644 --- a/external/toxcore/c-toxcore/toxcore/onion.h +++ b/external/toxcore/c-toxcore/toxcore/onion.h @@ -105,7 +105,7 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_ * return length of created packet on success. */ non_null() -int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_length, +int create_onion_packet(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length); @@ -119,7 +119,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_ * return length of created packet on success. */ non_null() -int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_packet_length, +int create_onion_packet_tcp(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length); diff --git a/external/toxcore/c-toxcore/toxcore/onion_announce.c b/external/toxcore/c-toxcore/toxcore/onion_announce.c index 593d81a..c7a6b38 100644 --- a/external/toxcore/c-toxcore/toxcore/onion_announce.c +++ b/external/toxcore/c-toxcore/toxcore/onion_announce.c @@ -9,7 +9,6 @@ #include "onion_announce.h" #include -#include #include #include "DHT.h" @@ -23,6 +22,7 @@ #include "network.h" #include "onion.h" #include "shared_key_cache.h" +#include "sort.h" #include "timed_auth.h" #define PING_ID_TIMEOUT ONION_ANNOUNCE_TIMEOUT @@ -103,7 +103,7 @@ void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint * return -1 on failure. * return packet length on success. */ -int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, +int create_announce_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data) { @@ -122,7 +122,7 @@ int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_pac packet[0] = NET_PACKET_ANNOUNCE_REQUEST_OLD; random_nonce(rng, packet + 1); - const int len = encrypt_data(dest_client_id, secret_key, packet + 1, plain, sizeof(plain), + const int len = encrypt_data(mem, dest_client_id, secret_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE); if ((uint32_t)len + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE != ONION_ANNOUNCE_REQUEST_MIN_SIZE) { @@ -146,7 +146,7 @@ int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_pac * return -1 on failure. * return 0 on success. */ -int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key, +int create_data_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length) { if (DATA_REQUEST_MIN_SIZE + length > max_packet_length) { @@ -167,7 +167,7 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_ memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, random_public_key, CRYPTO_PUBLIC_KEY_SIZE); - const int len = encrypt_data(encrypt_public_key, random_secret_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length, + const int len = encrypt_data(mem, encrypt_public_key, random_secret_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE); if (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + len != DATA_REQUEST_MIN_SIZE + @@ -193,14 +193,14 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_ * return 0 on success. */ int send_announce_request( - const Logger *log, const Networking_Core *net, const Random *rng, + const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng, const Onion_Path *path, const Node_format *dest, const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data) { uint8_t request[ONION_ANNOUNCE_REQUEST_MIN_SIZE]; - int len = create_announce_request(rng, request, sizeof(request), dest->public_key, public_key, secret_key, ping_id, + int len = create_announce_request(mem, rng, request, sizeof(request), dest->public_key, public_key, secret_key, ping_id, client_id, data_public_key, sendback_data); if (len != sizeof(request)) { @@ -208,7 +208,7 @@ int send_announce_request( } uint8_t packet[ONION_MAX_PACKET_SIZE]; - len = create_onion_packet(rng, packet, sizeof(packet), path, &dest->ip_port, request, sizeof(request)); + len = create_onion_packet(mem, rng, packet, sizeof(packet), path, &dest->ip_port, request, sizeof(request)); if (len == -1) { return -1; @@ -238,19 +238,19 @@ int send_announce_request( * return 0 on success. */ int send_data_request( - const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, + const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length) { uint8_t request[ONION_MAX_DATA_SIZE]; - int len = create_data_request(rng, request, sizeof(request), public_key, encrypt_public_key, nonce, data, length); + int len = create_data_request(mem, rng, request, sizeof(request), public_key, encrypt_public_key, nonce, data, length); if (len == -1) { return -1; } uint8_t packet[ONION_MAX_PACKET_SIZE]; - len = create_onion_packet(rng, packet, sizeof(packet), path, dest, request, len); + len = create_onion_packet(mem, rng, packet, sizeof(packet), path, dest, request, len); if (len == -1) { return -1; @@ -281,23 +281,17 @@ static int in_entries(const Onion_Announce *onion_a, const uint8_t *public_key) return -1; } -typedef struct Cmp_Data { +typedef struct Onion_Announce_Entry_Cmp { + const Memory *mem; const Mono_Time *mono_time; - const uint8_t *base_public_key; - Onion_Announce_Entry entry; -} Cmp_Data; + const uint8_t *comp_public_key; +} Onion_Announce_Entry_Cmp; non_null() -static int cmp_entry(const void *a, const void *b) +static int onion_announce_entry_cmp(const Onion_Announce_Entry_Cmp *cmp, const Onion_Announce_Entry *entry1, const Onion_Announce_Entry *entry2) { - const Cmp_Data *cmp1 = (const Cmp_Data *)a; - const Cmp_Data *cmp2 = (const Cmp_Data *)b; - const Onion_Announce_Entry entry1 = cmp1->entry; - const Onion_Announce_Entry entry2 = cmp2->entry; - const uint8_t *cmp_public_key = cmp1->base_public_key; - - const bool t1 = mono_time_is_timeout(cmp1->mono_time, entry1.announce_time, ONION_ANNOUNCE_TIMEOUT); - const bool t2 = mono_time_is_timeout(cmp1->mono_time, entry2.announce_time, ONION_ANNOUNCE_TIMEOUT); + const bool t1 = mono_time_is_timeout(cmp->mono_time, entry1->announce_time, ONION_ANNOUNCE_TIMEOUT); + const bool t2 = mono_time_is_timeout(cmp->mono_time, entry2->announce_time, ONION_ANNOUNCE_TIMEOUT); if (t1 && t2) { return 0; @@ -311,7 +305,7 @@ static int cmp_entry(const void *a, const void *b) return 1; } - const int closest = id_closest(cmp_public_key, entry1.public_key, entry2.public_key); + const int closest = id_closest(cmp->comp_public_key, entry1->public_key, entry2->public_key); if (closest == 1) { return 1; @@ -324,32 +318,81 @@ static int cmp_entry(const void *a, const void *b) return 0; } +non_null() +static bool onion_announce_entry_less_handler(const void *object, const void *a, const void *b) +{ + const Onion_Announce_Entry_Cmp *cmp = (const Onion_Announce_Entry_Cmp *)object; + const Onion_Announce_Entry *entry1 = (const Onion_Announce_Entry *)a; + const Onion_Announce_Entry *entry2 = (const Onion_Announce_Entry *)b; + + return onion_announce_entry_cmp(cmp, entry1, entry2) < 0; +} + +non_null() +static const void *onion_announce_entry_get_handler(const void *arr, uint32_t index) +{ + const Onion_Announce_Entry *entries = (const Onion_Announce_Entry *)arr; + return &entries[index]; +} + +non_null() +static void onion_announce_entry_set_handler(void *arr, uint32_t index, const void *val) +{ + Onion_Announce_Entry *entries = (Onion_Announce_Entry *)arr; + const Onion_Announce_Entry *entry = (const Onion_Announce_Entry *)val; + entries[index] = *entry; +} + +non_null() +static void *onion_announce_entry_subarr_handler(void *arr, uint32_t index, uint32_t size) +{ + Onion_Announce_Entry *entries = (Onion_Announce_Entry *)arr; + return &entries[index]; +} + +non_null() +static void *onion_announce_entry_alloc_handler(const void *object, uint32_t size) +{ + const Onion_Announce_Entry_Cmp *cmp = (const Onion_Announce_Entry_Cmp *)object; + Onion_Announce_Entry *tmp = (Onion_Announce_Entry *)mem_valloc(cmp->mem, size, sizeof(Onion_Announce_Entry)); + + if (tmp == nullptr) { + return nullptr; + } + + return tmp; +} + +non_null() +static void onion_announce_entry_delete_handler(const void *object, void *arr, uint32_t size) +{ + const Onion_Announce_Entry_Cmp *cmp = (const Onion_Announce_Entry_Cmp *)object; + mem_delete(cmp->mem, arr); +} + +static const Sort_Funcs onion_announce_entry_cmp_funcs = { + onion_announce_entry_less_handler, + onion_announce_entry_get_handler, + onion_announce_entry_set_handler, + onion_announce_entry_subarr_handler, + onion_announce_entry_alloc_handler, + onion_announce_entry_delete_handler, +}; + non_null() static void sort_onion_announce_list(const Memory *mem, const Mono_Time *mono_time, Onion_Announce_Entry *list, unsigned int length, const uint8_t *comp_public_key) { - // Pass comp_public_key to qsort with each Client_data entry, so the + // Pass comp_public_key to sort with each Onion_Announce_Entry entry, so the // comparison function can use it as the base of comparison. - Cmp_Data *cmp_list = (Cmp_Data *)mem_valloc(mem, length, sizeof(Cmp_Data)); + const Onion_Announce_Entry_Cmp cmp = { + mem, + mono_time, + comp_public_key, + }; - if (cmp_list == nullptr) { - return; - } - - for (uint32_t i = 0; i < length; ++i) { - cmp_list[i].mono_time = mono_time; - cmp_list[i].base_public_key = comp_public_key; - cmp_list[i].entry = list[i]; - } - - qsort(cmp_list, length, sizeof(Cmp_Data), cmp_entry); - - for (uint32_t i = 0; i < length; ++i) { - list[i] = cmp_list[i].entry; - } - - mem_delete(mem, cmp_list); + merge_sort(list, length, &cmp, &onion_announce_entry_cmp_funcs); } /** @brief add entry to entries list @@ -455,7 +498,7 @@ static int handle_announce_request_common( return 1; } - const int decrypted_len = decrypt_data_symmetric(shared_key, packet + 1, + const int decrypted_len = decrypt_data_symmetric(onion_a->mem, shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, plain_size + CRYPTO_MAC_SIZE, plain); if ((uint32_t)decrypted_len != plain_size) { @@ -542,7 +585,7 @@ static int handle_announce_request_common( offset += extra_size; uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE]; - const int len = encrypt_data_symmetric(shared_key, nonce, response, offset, + const int len = encrypt_data_symmetric(onion_a->mem, shared_key, nonce, response, offset, data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE); if (len != offset + CRYPTO_MAC_SIZE) { diff --git a/external/toxcore/c-toxcore/toxcore/onion_announce.h b/external/toxcore/c-toxcore/toxcore/onion_announce.h index 1158093..da0e190 100644 --- a/external/toxcore/c-toxcore/toxcore/onion_announce.h +++ b/external/toxcore/c-toxcore/toxcore/onion_announce.h @@ -65,7 +65,7 @@ void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint * return packet length on success. */ non_null() -int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, +int create_announce_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data); @@ -82,7 +82,7 @@ int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_pac * return 0 on success. */ non_null() -int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key, +int create_data_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length); /** @brief Create and send an onion announce request packet. @@ -101,7 +101,7 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_ */ non_null() int send_announce_request( - const Logger *log, const Networking_Core *net, const Random *rng, + const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng, const Onion_Path *path, const Node_format *dest, const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, @@ -125,7 +125,7 @@ int send_announce_request( */ non_null() int send_data_request( - const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, + const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length); diff --git a/external/toxcore/c-toxcore/toxcore/onion_client.c b/external/toxcore/c-toxcore/toxcore/onion_client.c index 3265759..45546cb 100644 --- a/external/toxcore/c-toxcore/toxcore/onion_client.c +++ b/external/toxcore/c-toxcore/toxcore/onion_client.c @@ -10,7 +10,6 @@ #include "onion_client.h" #include -#include #include #include "DHT.h" @@ -29,6 +28,7 @@ #include "onion.h" #include "onion_announce.h" #include "ping_array.h" +#include "sort.h" #include "timed_auth.h" #include "util.h" @@ -528,7 +528,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa { if (net_family_is_ipv4(path->ip_port1.ip.family) || net_family_is_ipv6(path->ip_port1.ip.family)) { uint8_t packet[ONION_MAX_PACKET_SIZE]; - const int len = create_onion_packet(onion_c->rng, packet, sizeof(packet), path, dest, data, length); + const int len = create_onion_packet(onion_c->mem, onion_c->rng, packet, sizeof(packet), path, dest, data, length); if (len == -1) { return -1; @@ -545,7 +545,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa if (ip_port_to_tcp_connections_number(&path->ip_port1, &tcp_connections_number)) { uint8_t packet[ONION_MAX_PACKET_SIZE]; - const int len = create_onion_packet_tcp(onion_c->rng, packet, sizeof(packet), path, dest, data, length); + const int len = create_onion_packet_tcp(onion_c->mem, onion_c->rng, packet, sizeof(packet), path, dest, data, length); if (len == -1) { return -1; @@ -661,7 +661,7 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con if (num == 0) { len = create_announce_request( - onion_c->rng, request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c), + onion_c->mem, onion_c->rng, request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c), nc_get_self_secret_key(onion_c->c), ping_id, nc_get_self_public_key(onion_c->c), onion_c->temp_public_key, sendback); } else { @@ -669,14 +669,14 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con if (onion_friend->gc_data_length == 0) { // contact is a friend len = create_announce_request( - onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key, + onion_c->mem, onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key, onion_friend->temp_secret_key, ping_id, onion_friend->real_public_key, zero_ping_id, sendback); } else { // contact is a gc onion_friend->is_groupchat = true; len = create_gca_announce_request( - onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key, + onion_c->mem, onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key, onion_friend->temp_secret_key, ping_id, onion_friend->real_public_key, zero_ping_id, sendback, onion_friend->gc_data, onion_friend->gc_data_length); @@ -694,23 +694,17 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con return send_onion_packet_tcp_udp(onion_c, &path, dest, request, len); } -typedef struct Onion_Client_Cmp_Data { +typedef struct Onion_Node_Cmp { + const Memory *mem; const Mono_Time *mono_time; - const uint8_t *base_public_key; - Onion_Node entry; -} Onion_Client_Cmp_Data; + const uint8_t *comp_public_key; +} Onion_Node_Cmp; non_null() -static int onion_client_cmp_entry(const void *a, const void *b) +static int onion_node_cmp(const Onion_Node_Cmp *cmp, const Onion_Node *entry1, const Onion_Node *entry2) { - const Onion_Client_Cmp_Data *cmp1 = (const Onion_Client_Cmp_Data *)a; - const Onion_Client_Cmp_Data *cmp2 = (const Onion_Client_Cmp_Data *)b; - const Onion_Node entry1 = cmp1->entry; - const Onion_Node entry2 = cmp2->entry; - const uint8_t *cmp_public_key = cmp1->base_public_key; - - const bool t1 = onion_node_timed_out(&entry1, cmp1->mono_time); - const bool t2 = onion_node_timed_out(&entry2, cmp2->mono_time); + const bool t1 = onion_node_timed_out(entry1, cmp->mono_time); + const bool t2 = onion_node_timed_out(entry2, cmp->mono_time); if (t1 && t2) { return 0; @@ -724,7 +718,7 @@ static int onion_client_cmp_entry(const void *a, const void *b) return 1; } - const int closest = id_closest(cmp_public_key, entry1.public_key, entry2.public_key); + const int closest = id_closest(cmp->comp_public_key, entry1->public_key, entry2->public_key); if (closest == 1) { return 1; @@ -737,31 +731,80 @@ static int onion_client_cmp_entry(const void *a, const void *b) return 0; } +non_null() +static bool onion_node_less_handler(const void *object, const void *a, const void *b) +{ + const Onion_Node_Cmp *cmp = (const Onion_Node_Cmp *)object; + const Onion_Node *entry1 = (const Onion_Node *)a; + const Onion_Node *entry2 = (const Onion_Node *)b; + + return onion_node_cmp(cmp, entry1, entry2) < 0; +} + +non_null() +static const void *onion_node_get_handler(const void *arr, uint32_t index) +{ + const Onion_Node *entries = (const Onion_Node *)arr; + return &entries[index]; +} + +non_null() +static void onion_node_set_handler(void *arr, uint32_t index, const void *val) +{ + Onion_Node *entries = (Onion_Node *)arr; + const Onion_Node *entry = (const Onion_Node *)val; + entries[index] = *entry; +} + +non_null() +static void *onion_node_subarr_handler(void *arr, uint32_t index, uint32_t size) +{ + Onion_Node *entries = (Onion_Node *)arr; + return &entries[index]; +} + +non_null() +static void *onion_node_alloc_handler(const void *object, uint32_t size) +{ + const Onion_Node_Cmp *cmp = (const Onion_Node_Cmp *)object; + Onion_Node *tmp = (Onion_Node *)mem_valloc(cmp->mem, size, sizeof(Onion_Node)); + + if (tmp == nullptr) { + return nullptr; + } + + return tmp; +} + +non_null() +static void onion_node_delete_handler(const void *object, void *arr, uint32_t size) +{ + const Onion_Node_Cmp *cmp = (const Onion_Node_Cmp *)object; + mem_delete(cmp->mem, arr); +} + +static const Sort_Funcs onion_node_cmp_funcs = { + onion_node_less_handler, + onion_node_get_handler, + onion_node_set_handler, + onion_node_subarr_handler, + onion_node_alloc_handler, + onion_node_delete_handler, +}; + non_null() static void sort_onion_node_list(const Memory *mem, const Mono_Time *mono_time, Onion_Node *list, unsigned int length, const uint8_t *comp_public_key) { - // Pass comp_public_key to qsort with each Client_data entry, so the + // Pass comp_public_key to sort with each Onion_Node entry, so the // comparison function can use it as the base of comparison. - Onion_Client_Cmp_Data *cmp_list = (Onion_Client_Cmp_Data *)mem_valloc(mem, length, sizeof(Onion_Client_Cmp_Data)); + const Onion_Node_Cmp cmp = { + mem, + mono_time, + comp_public_key, + }; - if (cmp_list == nullptr) { - return; - } - - for (uint32_t i = 0; i < length; ++i) { - cmp_list[i].mono_time = mono_time; - cmp_list[i].base_public_key = comp_public_key; - cmp_list[i].entry = list[i]; - } - - qsort(cmp_list, length, sizeof(Onion_Client_Cmp_Data), onion_client_cmp_entry); - - for (uint32_t i = 0; i < length; ++i) { - list[i] = cmp_list[i].entry; - } - - mem_delete(mem, cmp_list); + merge_sort(list, length, &cmp, &onion_node_cmp_funcs); } non_null() @@ -962,7 +1005,7 @@ static int handle_announce_response(void *object, const IP_Port *source, const u const uint16_t ciphertext_size = length - ciphertext_start; if (num == 0) { - len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c), + len = decrypt_data(onion_c->mem, public_key, nc_get_self_secret_key(onion_c->c), &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain); } else { if (!onion_c->friends_list[num - 1].is_valid) { @@ -970,7 +1013,7 @@ static int handle_announce_response(void *object, const IP_Port *source, const u return 1; } - len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key, + len = decrypt_data(onion_c->mem, public_key, onion_c->friends_list[num - 1].temp_secret_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain); } @@ -1066,7 +1109,7 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con const uint16_t ciphertext_size = length - ciphertext_start; if (num == 0) { - len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c), + len = decrypt_data(onion_c->mem, public_key, nc_get_self_secret_key(onion_c->c), &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain); } else { if (!onion_c->friends_list[num - 1].is_valid) { @@ -1074,7 +1117,7 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con return 1; } - len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key, + len = decrypt_data(onion_c->mem, public_key, onion_c->friends_list[num - 1].temp_secret_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain); } @@ -1136,7 +1179,7 @@ static int handle_data_response(void *object, const IP_Port *source, const uint8 const uint16_t temp_plain_size = length - ONION_DATA_RESPONSE_MIN_SIZE; VLA(uint8_t, temp_plain, temp_plain_size); - int len = decrypt_data(packet + 1 + CRYPTO_NONCE_SIZE, onion_c->temp_secret_key, packet + 1, + int len = decrypt_data(onion_c->mem, packet + 1 + CRYPTO_NONCE_SIZE, onion_c->temp_secret_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE), temp_plain); @@ -1146,7 +1189,7 @@ static int handle_data_response(void *object, const IP_Port *source, const uint8 const uint16_t plain_size = temp_plain_size - DATA_IN_RESPONSE_MIN_SIZE; VLA(uint8_t, plain, plain_size); - len = decrypt_data(temp_plain, nc_get_self_secret_key(onion_c->c), + len = decrypt_data(onion_c->mem, temp_plain, nc_get_self_secret_key(onion_c->c), packet + 1, temp_plain + CRYPTO_PUBLIC_KEY_SIZE, temp_plain_size - CRYPTO_PUBLIC_KEY_SIZE, plain); @@ -1305,7 +1348,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, const uint16_t packet_size = DATA_IN_RESPONSE_MIN_SIZE + length; VLA(uint8_t, packet, packet_size); memcpy(packet, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE); - int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key, + int len = encrypt_data(onion_c->mem, onion_c->friends_list[friend_num].real_public_key, nc_get_self_secret_key(onion_c->c), nonce, data, length, packet + CRYPTO_PUBLIC_KEY_SIZE); @@ -1324,7 +1367,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, uint8_t o_packet[ONION_MAX_PACKET_SIZE]; len = create_data_request( - onion_c->rng, o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key, + onion_c->mem, onion_c->rng, o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key, node_list[good_nodes[i]].data_public_key, nonce, packet, packet_size); if (len == -1) { @@ -1364,7 +1407,7 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin VLA(uint8_t, temp, temp_size); memcpy(temp, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE); memcpy(temp + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE); - int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key, + int len = encrypt_data(onion_c->mem, onion_c->friends_list[friend_num].real_public_key, nc_get_self_secret_key(onion_c->c), nonce, data, length, temp + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); @@ -1374,7 +1417,7 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin uint8_t packet_data[MAX_CRYPTO_REQUEST_SIZE]; len = create_request( - onion_c->rng, dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data, + onion_c->mem, onion_c->rng, dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data, onion_c->friends_list[friend_num].dht_public_key, temp, temp_size, CRYPTO_PACKET_DHTPK); assert(len <= UINT16_MAX); const Packet packet = {packet_data, (uint16_t)len}; @@ -1401,7 +1444,7 @@ static int handle_dht_dhtpk(void *object, const IP_Port *source, const uint8_t * } uint8_t plain[DHTPK_DATA_MAX_LENGTH]; - const int len = decrypt_data(packet, nc_get_self_secret_key(onion_c->c), + const int len = decrypt_data(onion_c->mem, packet, nc_get_self_secret_key(onion_c->c), packet + CRYPTO_PUBLIC_KEY_SIZE, packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, length - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), plain); diff --git a/external/toxcore/c-toxcore/toxcore/onion_client.h b/external/toxcore/c-toxcore/toxcore/onion_client.h index 61e4e6f..92be110 100644 --- a/external/toxcore/c-toxcore/toxcore/onion_client.h +++ b/external/toxcore/c-toxcore/toxcore/onion_client.h @@ -183,6 +183,8 @@ non_null() unsigned int onion_getfriend_dht_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key); #define ONION_DATA_IN_RESPONSE_MIN_SIZE (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE) + +// TODO(Jfreegman): This is not the correct value; data this large will be dropped by the onion client. #define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE) /** @brief Send data of length length to friendnum. diff --git a/external/toxcore/c-toxcore/toxcore/ping.c b/external/toxcore/c-toxcore/toxcore/ping.c index 303c418..d3dc92d 100644 --- a/external/toxcore/c-toxcore/toxcore/ping.c +++ b/external/toxcore/c-toxcore/toxcore/ping.c @@ -31,6 +31,7 @@ struct Ping { const Mono_Time *mono_time; const Random *rng; + const Memory *mem; DHT *dht; Ping_Array *ping_array; @@ -72,7 +73,7 @@ void ping_send_request(Ping *ping, const IP_Port *ipp, const uint8_t *public_key pk_copy(pk + 1, dht_get_self_public_key(ping->dht)); // Our pubkey random_nonce(ping->rng, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce - rc = encrypt_data_symmetric(shared_key, + rc = encrypt_data_symmetric(ping->mem, shared_key, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE, ping_plain, sizeof(ping_plain), pk + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); @@ -104,7 +105,7 @@ static int ping_send_response(const Ping *ping, const IP_Port *ipp, const uint8_ random_nonce(ping->rng, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce // Encrypt ping_id using recipient privkey - const int rc = encrypt_data_symmetric(shared_encryption_key, + const int rc = encrypt_data_symmetric(ping->mem, shared_encryption_key, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE, ping_plain, sizeof(ping_plain), pk + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); @@ -137,7 +138,7 @@ static int handle_ping_request(void *object, const IP_Port *source, const uint8_ uint8_t ping_plain[PING_PLAIN_SIZE]; // Decrypt ping_id - const int rc = decrypt_data_symmetric(shared_key, + const int rc = decrypt_data_symmetric(ping->mem, shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, PING_PLAIN_SIZE + CRYPTO_MAC_SIZE, @@ -182,7 +183,7 @@ static int handle_ping_response(void *object, const IP_Port *source, const uint8 uint8_t ping_plain[PING_PLAIN_SIZE]; // Decrypt ping_id - rc = decrypt_data_symmetric(shared_key, + rc = decrypt_data_symmetric(ping->mem, shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, PING_PLAIN_SIZE + CRYPTO_MAC_SIZE, @@ -348,6 +349,7 @@ Ping *ping_new(const Memory *mem, const Mono_Time *mono_time, const Random *rng, ping->mono_time = mono_time; ping->rng = rng; + ping->mem = mem; ping->dht = dht; networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_REQUEST, &handle_ping_request, dht); networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_RESPONSE, &handle_ping_response, dht); diff --git a/external/toxcore/c-toxcore/toxcore/sort.c b/external/toxcore/c-toxcore/toxcore/sort.c new file mode 100644 index 0000000..45b2ffa --- /dev/null +++ b/external/toxcore/c-toxcore/toxcore/sort.c @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023-2024 The TokTok team. + */ + +#include "sort.h" + +#include + +#include "attributes.h" +#include "ccompat.h" +#include "util.h" + +/** + * @brief Threshold for when to switch to insertion sort. + * + * This is a trade-off between the complexity of insertion sort and the + * overhead of merge sort. The threshold is chosen to be the smallest value + * that gives a measurable speedup for insertion sort over merge sort. This is + * based on measurements done in sort_bench.cc. Starting from 32 elements, + * merge sort is faster than insertion sort in all our tests (both unsorted + * and mostly-sorted). + * + * Toxcore has a lot of small arrays it wants to sort, so this optimisation + * makes sense. + */ +#define SMALL_ARRAY_THRESHOLD 16 + +non_null() +static void merge_sort_merge_back( + void *arr, + const void *l_arr, uint32_t l_arr_size, + const void *r_arr, uint32_t r_arr_size, + uint32_t left_start, + const void *object, const Sort_Funcs *funcs) +{ + uint32_t li = 0; + uint32_t ri = 0; + uint32_t k = left_start; + + while (li < l_arr_size && ri < r_arr_size) { + const void *l = funcs->get_callback(l_arr, li); + const void *r = funcs->get_callback(r_arr, ri); + // !(r < l) <=> (r >= l) <=> (l <= r) + if (!funcs->less_callback(object, r, l)) { + funcs->set_callback(arr, k, l); + ++li; + } else { + funcs->set_callback(arr, k, r); + ++ri; + } + ++k; + } + + /* Copy the remaining elements of `l_arr[]`, if there are any. */ + while (li < l_arr_size) { + funcs->set_callback(arr, k, funcs->get_callback(l_arr, li)); + ++li; + ++k; + } + + /* Copy the remaining elements of `r_arr[]`, if there are any. */ + while (ri < r_arr_size) { + funcs->set_callback(arr, k, funcs->get_callback(r_arr, ri)); + ++ri; + ++k; + } +} + +/** Function to merge the two haves `arr[left_start..mid]` and `arr[mid+1..right_end]` of array `arr[]`. */ +non_null() +static void merge_sort_merge( + void *arr, uint32_t left_start, uint32_t mid, uint32_t right_end, void *tmp, + const void *object, const Sort_Funcs *funcs) +{ + const uint32_t l_arr_size = mid - left_start + 1; + const uint32_t r_arr_size = right_end - mid; + + /* Temporary arrays, using the tmp buffer created in `merge_sort` below. */ + void *l_arr = funcs->subarr_callback(tmp, 0, l_arr_size); + void *r_arr = funcs->subarr_callback(tmp, l_arr_size, r_arr_size); + + /* Copy data to temp arrays `l_arr[]` and `r_arr[]`. + * + * This is iterating and repeatedly calling `get` and `set`, which sounds + * slow, but is only marginally slower than having a `copy` callback. With + * a `copy` callback, we'd save 3-4% in time. + */ + for (uint32_t i = 0; i < l_arr_size; ++i) { + funcs->set_callback(l_arr, i, funcs->get_callback(arr, left_start + i)); + } + for (uint32_t i = 0; i < r_arr_size; ++i) { + funcs->set_callback(r_arr, i, funcs->get_callback(arr, mid + 1 + i)); + } + + /* Merge the temp arrays back into `arr[left_start..right_end]`. */ + merge_sort_merge_back(arr, l_arr, l_arr_size, r_arr, r_arr_size, left_start, object, funcs); +} + +non_null() +static void insertion_sort_step(void *arr, void *tmp, uint32_t i, const void *object, const Sort_Funcs *funcs) +{ + funcs->set_callback(tmp, 0, funcs->get_callback(arr, i)); + uint32_t j = i; + + while (j > 0) { + if (!funcs->less_callback(object, tmp, funcs->get_callback(arr, j - 1))) { + break; + } + funcs->set_callback(arr, j, funcs->get_callback(arr, j - 1)); + --j; + } + + funcs->set_callback(arr, j, tmp); +} + +non_null() +static void insertion_sort_with_buf(void *arr, uint32_t arr_size, void *tmp, uint32_t tmp_size, const void *object, const Sort_Funcs *funcs) +{ + for (uint32_t i = 1; i < arr_size; ++i) { + insertion_sort_step(arr, tmp, i, object, funcs); + } +} + +non_null() +static bool insertion_sort(void *arr, uint32_t arr_size, const void *object, const Sort_Funcs *funcs) +{ + void *tmp = funcs->alloc_callback(object, 1); + + if (tmp == nullptr) { + return false; + } + + insertion_sort_with_buf(arr, arr_size, tmp, 1, object, funcs); + + funcs->delete_callback(object, tmp, 1); + return true; +} + +void merge_sort_with_buf(void *arr, uint32_t arr_size, void *tmp, uint32_t tmp_size, const void *object, const Sort_Funcs *funcs) +{ + assert(tmp_size >= arr_size); + + if (arr_size <= SMALL_ARRAY_THRESHOLD) { + assert(tmp_size >= 1); + insertion_sort_with_buf(arr, arr_size, tmp, tmp_size, object, funcs); + return; + } + + // Merge subarrays in bottom up manner. First merge subarrays of + // size 1 to create sorted subarrays of size 2, then merge subarrays + // of size 2 to create sorted subarrays of size 4, and so on. + for (uint32_t curr_size = 1; curr_size <= arr_size - 1; curr_size = 2 * curr_size) { + // Pick starting point of different subarrays of current size + for (uint32_t left_start = 0; left_start < arr_size - 1; left_start += 2 * curr_size) { + // Find ending point of left subarray. mid+1 is starting + // point of right + const uint32_t mid = min_u32(left_start + curr_size - 1, arr_size - 1); + const uint32_t right_end = min_u32(left_start + 2 * curr_size - 1, arr_size - 1); + + // Merge Subarrays arr[left_start...mid] & arr[mid+1...right_end] + merge_sort_merge(arr, left_start, mid, right_end, tmp, object, funcs); + } + } +} + +bool merge_sort(void *arr, uint32_t arr_size, const void *object, const Sort_Funcs *funcs) +{ + if (arr_size <= SMALL_ARRAY_THRESHOLD) { + return insertion_sort(arr, arr_size, object, funcs); + } + + void *tmp = funcs->alloc_callback(object, arr_size); + + if (tmp == nullptr) { + return false; + } + + merge_sort_with_buf(arr, arr_size, tmp, arr_size, object, funcs); + + funcs->delete_callback(object, tmp, arr_size); + return true; +} diff --git a/external/toxcore/c-toxcore/toxcore/sort.h b/external/toxcore/c-toxcore/toxcore/sort.h new file mode 100644 index 0000000..c84d776 --- /dev/null +++ b/external/toxcore/c-toxcore/toxcore/sort.h @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023-2024 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_SORT_H +#define C_TOXCORE_TOXCORE_SORT_H + +#include +#include + +#include "attributes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Compare elements with a less-than ordering: `a < b`. */ +typedef bool sort_less_cb(const void *object, const void *a, const void *b); +/** @brief Get element from array at index. */ +typedef const void *sort_get_cb(const void *arr, uint32_t index); +/** @brief Set element in array at index to new value (perform copy). */ +typedef void sort_set_cb(void *arr, uint32_t index, const void *val); +/** @brief Get a sub-array at an index of a given size (mutable pointer). + * + * Used to index in the temporary array allocated by `sort_alloc_cb` and get + * a sub-array for working memory. + */ +typedef void *sort_subarr_cb(void *arr, uint32_t index, uint32_t size); +/** @brief Allocate a new array of the element type. + * + * @param size The array size in elements of type T (not byte size). This value + * is always exactly the input array size as passed to `merge_sort`. + */ +typedef void *sort_alloc_cb(const void *object, uint32_t size); +/** @brief Free the element type array. */ +typedef void sort_delete_cb(const void *object, void *arr, uint32_t size); + +/** @brief Virtual function table for getting/setting elements in an array and + * comparing them. + * + * Only the `less`, `alloc`, and `delete` functions get a `this`-pointer. We + * assume that indexing in an array doesn't need any other information than the + * array itself. + * + * For now, the `this`-pointer is const, because we assume sorting doesn't need + * to mutate any state, but if necessary that can be changed in the future. + */ +typedef struct Sort_Funcs { + sort_less_cb *less_callback; + sort_get_cb *get_callback; + sort_set_cb *set_callback; + sort_subarr_cb *subarr_callback; + sort_alloc_cb *alloc_callback; + sort_delete_cb *delete_callback; +} Sort_Funcs; + +/** @brief Non-recursive merge sort function to sort `arr[0...arr_size-1]`. + * + * Avoids `memcpy` and avoids treating elements as byte arrays. Instead, uses + * callbacks to index in arrays and copy elements. This makes it quite a bit + * slower than `qsort`, but works with elements that require special care when + * being copied (e.g. if they are part of a graph or other data structure that + * with pointers or other invariants). + * + * This function actually uses insertion sort for small arrays (up to 16 + * elements), which is faster than merge sort for small arrays, especially + * when mostly sorted (a common use case in toxcore). + * + * Allocates a single temporary array with the provided alloc callback, and + * frees it at the end. This is significantly faster than an in-place + * implementation. + * + * Complexity: + * - Space: `O(n) where n = array_size`. + * - Time: `O(n * log n) where n = array_size`. + * + * Compared to `qsort`, this is about 60-70% slower for large arrays. For small + * arrays (up to 16 elements), it's about 50% faster than `qsort`. + * + * @param[in,out] arr An array of type T. + * @param arr_size Number of elements in @p arr (count, not byte size). + * @param[in] object Comparator object. + * @param[in] funcs Callback struct for elements of type T. + */ +non_null() +bool merge_sort(void *arr, uint32_t arr_size, const void *object, const Sort_Funcs *funcs); + +/** + * @brief Merge sort like above but with a pre-allocated buffer. + * + * This function is the same as `merge_sort` but uses a pre-allocated buffer + * for temporary storage. This can be useful if the caller wants to avoid + * dynamic memory allocation. + * + * This function is 1-2% faster than `merge_sort` for small arrays up to 1000 + * elements, and about 5-10% faster for large arrays (2000+ elements). + * + * The main upside is that `alloc` and `delete` callbacks don't need to be + * implemented, and the caller can use a stack-allocated buffer. + * + * @param[in,out] arr An array of type T. + * @param arr_size Number of elements in @p arr (count, not byte size). + * @param[in,out] tmp A buffer of size `tmp_size` for temporary storage. + * @param tmp_size Number of elements in @p tmp (count, not byte size). Must be + * at least as large as `arr_size`. + * @param[in] object Comparator object. + * @param[in] funcs Callback struct for elements of type T. + */ +non_null() +void merge_sort_with_buf(void *arr, uint32_t arr_size, void *tmp, uint32_t tmp_size, const void *object, const Sort_Funcs *funcs); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_SORT_H */ diff --git a/external/toxcore/c-toxcore/toxcore/sort_bench.cc b/external/toxcore/c-toxcore/toxcore/sort_bench.cc new file mode 100644 index 0000000..0e75bc9 --- /dev/null +++ b/external/toxcore/c-toxcore/toxcore/sort_bench.cc @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023-2024 The TokTok team. + */ + +#include + +#include +#include +#include +#include + +#include "mem.h" +#include "sort.h" +#include "sort_test_util.hh" + +namespace { + +std::pair, std::mt19937> random_vec(benchmark::State &state) +{ + std::mt19937 rng; + // INT_MAX-1 so later we have room to add 1 larger element if needed. + std::uniform_int_distribution dist{ + std::numeric_limits::min(), std::numeric_limits::max() - 1}; + + std::vector vec(state.range(0)); + std::generate(std::begin(vec), std::end(vec), [&]() { + std::array compare_value; + std::generate( + std::begin(compare_value), std::end(compare_value), [&]() { return dist(rng); }); + return Some_Type{nullptr, compare_value, "hello there"}; + }); + + return {vec, rng}; +} + +std::vector mostly_sorted_vec(benchmark::State &state) +{ + auto [vec, rng] = random_vec(state); + std::sort(vec.begin(), vec.end()); + + // Randomly swap 5% of the vector. + std::uniform_int_distribution dist{0, vec.size() - 1}; + for (std::size_t i = 0; i < vec.size() / 20; ++i) { + const auto a = dist(rng); + const auto b = dist(rng); + std::swap(vec[a], vec[b]); + } + + return vec; +} + +void BM_merge_sort(benchmark::State &state) +{ + const auto vec = random_vec(state).first; + + for (auto _ : state) { + auto unsorted = vec; + merge_sort(unsorted.data(), unsorted.size(), &state, &Some_Type::funcs); + } +} + +BENCHMARK(BM_merge_sort)->RangeMultiplier(2)->Range(8, 8 << 8); + +void BM_merge_sort_with_buf(benchmark::State &state) +{ + const auto vec = random_vec(state).first; + std::vector buf(vec.size()); + + for (auto _ : state) { + auto unsorted = vec; + merge_sort_with_buf( + unsorted.data(), unsorted.size(), buf.data(), buf.size(), &state, &Some_Type::funcs); + } +} + +BENCHMARK(BM_merge_sort_with_buf)->RangeMultiplier(2)->Range(8, 8 << 8); + +void BM_merge_sort_mostly_sorted(benchmark::State &state) +{ + auto vec = mostly_sorted_vec(state); + + for (auto _ : state) { + auto unsorted = vec; + merge_sort(unsorted.data(), unsorted.size(), &state, &Some_Type::funcs); + } +} + +BENCHMARK(BM_merge_sort_mostly_sorted)->RangeMultiplier(2)->Range(8, 8 << 8); + +void BM_qsort(benchmark::State &state) +{ + const auto vec = random_vec(state).first; + + for (auto _ : state) { + auto unsorted = vec; + qsort(unsorted.data(), unsorted.size(), sizeof(unsorted[0]), my_type_cmp); + } +} + +BENCHMARK(BM_qsort)->RangeMultiplier(2)->Range(8, 8 << 8); + +void BM_qsort_mostly_sorted(benchmark::State &state) +{ + auto vec = mostly_sorted_vec(state); + + for (auto _ : state) { + auto unsorted = vec; + qsort(unsorted.data(), unsorted.size(), sizeof(unsorted[0]), my_type_cmp); + } +} + +BENCHMARK(BM_qsort_mostly_sorted)->RangeMultiplier(2)->Range(8, 8 << 8); + +void BM_std_sort(benchmark::State &state) +{ + const auto vec = random_vec(state).first; + + for (auto _ : state) { + auto unsorted = vec; + std::sort(unsorted.begin(), unsorted.end()); + } +} + +BENCHMARK(BM_std_sort)->RangeMultiplier(2)->Range(8, 8 << 8); + +void BM_std_sort_mostly_sorted(benchmark::State &state) +{ + auto vec = mostly_sorted_vec(state); + + for (auto _ : state) { + auto unsorted = vec; + std::sort(unsorted.begin(), unsorted.end()); + } +} + +BENCHMARK(BM_std_sort_mostly_sorted)->RangeMultiplier(2)->Range(8, 8 << 8); + +} + +BENCHMARK_MAIN(); diff --git a/external/toxcore/c-toxcore/toxcore/sort_test.cc b/external/toxcore/c-toxcore/toxcore/sort_test.cc new file mode 100644 index 0000000..c8af334 --- /dev/null +++ b/external/toxcore/c-toxcore/toxcore/sort_test.cc @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023-2024 The TokTok team. + */ + +#include "sort.h" + +#include + +#include +#include + +#include "sort_test_util.hh" + +namespace { + +TEST(MergeSort, BehavesLikeStdSort) +{ + std::mt19937 rng; + // INT_MAX-1 so later we have room to add 1 larger element if needed. + std::uniform_int_distribution dist{ + std::numeric_limits::min(), std::numeric_limits::max() - 1}; + + constexpr auto int_funcs = sort_funcs(); + + // Test with int arrays. + for (uint32_t i = 1; i < 500; ++i) { + std::vector vec(i); + std::generate(std::begin(vec), std::end(vec), [&]() { return dist(rng); }); + + auto sorted = vec; + std::sort(sorted.begin(), sorted.end(), std::less()); + + // If vec was accidentally sorted, add another larger element that almost definitely makes + // it not sorted. + if (vec == sorted) { + int const largest = *std::prev(sorted.end()) + 1; + sorted.push_back(largest); + vec.insert(vec.begin(), largest); + } + ASSERT_NE(vec, sorted); + + // Just pass some arbitrary "self" to make sure the callbacks pass it through. + ASSERT_TRUE(merge_sort(vec.data(), vec.size(), &i, &int_funcs)); + ASSERT_EQ(vec, sorted); + } +} + +TEST(MergeSort, WorksWithNonTrivialTypes) +{ + std::mt19937 rng; + std::uniform_int_distribution dist{ + std::numeric_limits::min(), std::numeric_limits::max()}; + + constexpr auto string_funcs = sort_funcs(); + + // Test with std::string arrays. + for (uint32_t i = 1; i < 500; ++i) { + std::vector vec(i); + std::generate(std::begin(vec), std::end(vec), [&]() { return std::to_string(dist(rng)); }); + + auto sorted = vec; + std::sort(sorted.begin(), sorted.end(), std::less()); + + // If vec was accidentally sorted, add another larger element that almost definitely makes + // it not sorted. + if (vec == sorted) { + std::string const largest = "larger than largest int"; + sorted.push_back(largest); + vec.insert(vec.begin(), largest); + } + ASSERT_NE(vec, sorted); + + // Just pass some arbitrary "self" to make sure the callbacks pass it through. + ASSERT_TRUE(merge_sort(vec.data(), vec.size(), &i, &string_funcs)); + ASSERT_EQ(vec, sorted); + } +} + +} // namespace diff --git a/external/toxcore/c-toxcore/toxcore/sort_test_util.cc b/external/toxcore/c-toxcore/toxcore/sort_test_util.cc new file mode 100644 index 0000000..ed85127 --- /dev/null +++ b/external/toxcore/c-toxcore/toxcore/sort_test_util.cc @@ -0,0 +1,32 @@ +#include "sort_test_util.hh" + +#include +#include + +#include "sort.h" +#include "util.h" + +namespace { +template +int cmp_uint_array(const std::array &a, const std::array &b) +{ + for (std::size_t i = 0; i < a.size(); ++i) { + const int cmp = cmp_uint(a[i], b[i]); + if (cmp != 0) { + return cmp; + } + } + return 0; +} +} + +const Sort_Funcs Some_Type::funcs = sort_funcs(); + +int my_type_cmp(const void *va, const void *vb) +{ + const auto *a = static_cast(va); + const auto *b = static_cast(vb); + return cmp_uint_array(a->compare_value, b->compare_value); +} + +bool operator<(const Some_Type &a, const Some_Type &b) { return a.compare_value < b.compare_value; } diff --git a/external/toxcore/c-toxcore/toxcore/sort_test_util.hh b/external/toxcore/c-toxcore/toxcore/sort_test_util.hh new file mode 100644 index 0000000..8013290 --- /dev/null +++ b/external/toxcore/c-toxcore/toxcore/sort_test_util.hh @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023-2024 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_SORT_TEST_UTIL_H +#define C_TOXCORE_TOXCORE_SORT_TEST_UTIL_H + +#include + +#include "sort.h" + +struct Memory; + +template +constexpr Sort_Funcs sort_funcs() +{ + return { + [](const void *object, const void *va, const void *vb) { + const T *a = static_cast(va); + const T *b = static_cast(vb); + + return *a < *b; + }, + [](const void *arr, uint32_t index) -> const void * { + const T *vec = static_cast(arr); + return &vec[index]; + }, + [](void *arr, uint32_t index, const void *val) { + T *vec = static_cast(arr); + const T *value = static_cast(val); + vec[index] = *value; + }, + [](void *arr, uint32_t index, uint32_t size) -> void * { + T *vec = static_cast(arr); + return &vec[index]; + }, + [](const void *object, uint32_t size) -> void * { return new T[size]; }, + [](const void *object, void *arr, uint32_t size) { delete[] static_cast(arr); }, + }; +} + +// A realistic test case where we have a struct with some stuff and an expensive value we compare. +struct Some_Type { + const Memory *mem; + std::array compare_value; + const char *name; + + static const Sort_Funcs funcs; +}; + +int my_type_cmp(const void *va, const void *vb); +bool operator<(const Some_Type &a, const Some_Type &b); + +#endif // C_TOXCORE_TOXCORE_SORT_TEST_UTIL_H diff --git a/external/toxcore/c-toxcore/toxcore/tox.c b/external/toxcore/c-toxcore/toxcore/tox.c index b02eb4e..4918e7b 100644 --- a/external/toxcore/c-toxcore/toxcore/tox.c +++ b/external/toxcore/c-toxcore/toxcore/tox.c @@ -752,6 +752,8 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error Messenger_Options m_options = {false}; + m_options.dns_enabled = !tox_options_get_experimental_disable_dns(opts); + bool load_savedata_sk = false; bool load_savedata_tox = false; @@ -855,9 +857,10 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error } const char *const proxy_host = tox_options_get_proxy_host(opts); + const bool dns_enabled = !tox_options_get_experimental_disable_dns(opts); if (proxy_host == nullptr - || !addr_resolve_or_parse_ip(tox->sys.ns, proxy_host, &m_options.proxy_info.ip_port.ip, nullptr)) { + || !addr_resolve_or_parse_ip(tox->sys.ns, tox->sys.mem, proxy_host, &m_options.proxy_info.ip_port.ip, nullptr, dns_enabled)) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_HOST); // TODO(irungentoo): TOX_ERR_NEW_PROXY_NOT_FOUND if domain. mem_delete(sys->mem, tox); @@ -1139,7 +1142,7 @@ static int32_t resolve_bootstrap_node(Tox *tox, const char *host, uint16_t port, return -1; } - const int32_t count = net_getipport(tox->sys.mem, host, root, TOX_SOCK_DGRAM); + const int32_t count = net_getipport(tox->sys.ns, tox->sys.mem, host, root, TOX_SOCK_DGRAM, tox->m->options.dns_enabled); if (count < 1) { LOGGER_DEBUG(tox->m->log, "could not resolve bootstrap node '%s'", host); diff --git a/external/toxcore/c-toxcore/toxcore/tox.h b/external/toxcore/c-toxcore/toxcore/tox.h index 075f250..101437b 100644 --- a/external/toxcore/c-toxcore/toxcore/tox.h +++ b/external/toxcore/c-toxcore/toxcore/tox.h @@ -148,7 +148,7 @@ uint32_t tox_version_minor(void); * Incremented when bugfixes are applied without changing any functionality or * API or ABI. */ -#define TOX_VERSION_PATCH 19 +#define TOX_VERSION_PATCH 20 uint32_t tox_version_patch(void); @@ -274,7 +274,7 @@ uint32_t tox_max_status_message_length(void); * * @deprecated The macro will be removed in 0.3.0. Use the function instead. */ -#define TOX_MAX_FRIEND_REQUEST_LENGTH 1016 +#define TOX_MAX_FRIEND_REQUEST_LENGTH 921 uint32_t tox_max_friend_request_length(void); @@ -668,6 +668,24 @@ struct Tox_Options { * Default: false. */ bool experimental_groups_persistence; + + /** + * @brief Disable DNS hostname resolution. + * + * Hostnames or IP addresses are passed to the bootstrap/add_tcp_relay + * function and proxy host options. If disabled (this flag is true), only + * IP addresses are allowed. + * + * If this is set to true, the library will not attempt to resolve + * hostnames. This is useful for clients that want to resolve hostnames + * themselves and pass the resolved IP addresses to the library (e.g. in + * case it wants to use Tor). + * Passing hostnames will result in a TOX_ERR_BOOTSTRAP_BAD_HOST error if + * this is set to true. + * + * Default: false. May become true in the future (0.3.0). + */ + bool experimental_disable_dns; }; bool tox_options_get_ipv6_enabled(const Tox_Options *options); @@ -742,6 +760,10 @@ bool tox_options_get_experimental_groups_persistence(const Tox_Options *options) void tox_options_set_experimental_groups_persistence(Tox_Options *options, bool experimental_groups_persistence); +bool tox_options_get_experimental_disable_dns(const Tox_Options *options); + +void tox_options_set_experimental_disable_dns(Tox_Options *options, bool experimental_disable_dns); + /** * @brief Initialises a Tox_Options object with the default options. * diff --git a/external/toxcore/c-toxcore/toxcore/tox_api.c b/external/toxcore/c-toxcore/toxcore/tox_api.c index 18d861c..b979e4e 100644 --- a/external/toxcore/c-toxcore/toxcore/tox_api.c +++ b/external/toxcore/c-toxcore/toxcore/tox_api.c @@ -274,6 +274,14 @@ void tox_options_set_experimental_groups_persistence( { options->experimental_groups_persistence = experimental_groups_persistence; } +bool tox_options_get_experimental_disable_dns(const Tox_Options *options) +{ + return options->experimental_disable_dns; +} +void tox_options_set_experimental_disable_dns(Tox_Options *options, bool experimental_disable_dns) +{ + options->experimental_disable_dns = experimental_disable_dns; +} const uint8_t *tox_options_get_savedata_data(const Tox_Options *options) { @@ -299,6 +307,7 @@ void tox_options_default(Tox_Options *options) tox_options_set_dht_announcements_enabled(options, true); tox_options_set_experimental_thread_safety(options, false); tox_options_set_experimental_groups_persistence(options, false); + tox_options_set_experimental_disable_dns(options, false); } } diff --git a/external/toxcore/c-toxcore/toxcore/tox_private.c b/external/toxcore/c-toxcore/toxcore/tox_private.c index 7b6050a..ff6aa6e 100644 --- a/external/toxcore/c-toxcore/toxcore/tox_private.c +++ b/external/toxcore/c-toxcore/toxcore/tox_private.c @@ -124,7 +124,7 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip IP_Port *root; - const int32_t count = net_getipport(tox->sys.mem, ip, &root, TOX_SOCK_DGRAM); + const int32_t count = net_getipport(tox->sys.ns, tox->sys.mem, ip, &root, TOX_SOCK_DGRAM, tox->m->options.dns_enabled); if (count < 1) { SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_BAD_IP); diff --git a/external/toxcore/c-toxcore/toxcore/util.c b/external/toxcore/c-toxcore/toxcore/util.c index 1851e58..85d29a4 100644 --- a/external/toxcore/c-toxcore/toxcore/util.c +++ b/external/toxcore/c-toxcore/toxcore/util.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-3.0-or-later - * Copyright © 2016-2018 The TokTok team. + * Copyright © 2016-2024 The TokTok team. * Copyright © 2013 Tox project. * Copyright © 2013 plutooo */ @@ -16,6 +16,7 @@ #include #include +#include "attributes.h" #include "ccompat.h" #include "mem.h" diff --git a/external/toxcore/c-toxcore/toxcore/util_test.cc b/external/toxcore/c-toxcore/toxcore/util_test.cc index 94e653f..ccdd979 100644 --- a/external/toxcore/c-toxcore/toxcore/util_test.cc +++ b/external/toxcore/c-toxcore/toxcore/util_test.cc @@ -1,39 +1,14 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2024 The TokTok team. + */ #include "util.h" #include -#include "crypto_core.h" -#include "crypto_core_test_util.hh" +#include namespace { -TEST(Util, TwoRandomIdsAreNotEqual) -{ - Test_Random rng; - uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; - uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t sk2[CRYPTO_SECRET_KEY_SIZE]; - - crypto_new_keypair(rng, pk1, sk1); - crypto_new_keypair(rng, pk2, sk2); - - EXPECT_FALSE(pk_equal(pk1, pk2)); -} - -TEST(Util, IdCopyMakesKeysEqual) -{ - Test_Random rng; - uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE]; - uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; - uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0}; - - crypto_new_keypair(rng, pk1, sk1); - pk_copy(pk2, pk1); - - EXPECT_TRUE(pk_equal(pk1, pk2)); -} - TEST(Cmp, OrdersNumbersCorrectly) { EXPECT_EQ(cmp_uint(1, 2), -1); diff --git a/external/toxcore/c-toxcore/toxencryptsave/toxencryptsave.c b/external/toxcore/c-toxcore/toxencryptsave/toxencryptsave.c index b785c26..4e43b17 100644 --- a/external/toxcore/c-toxcore/toxencryptsave/toxencryptsave.c +++ b/external/toxcore/c-toxcore/toxencryptsave/toxencryptsave.c @@ -231,7 +231,7 @@ bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t plaintext[], si ciphertext += crypto_box_NONCEBYTES; /* now encrypt */ - const int32_t encrypted_len = encrypt_data_symmetric(key->key, nonce, plaintext, plaintext_len, ciphertext); + const int32_t encrypted_len = encrypt_data_symmetric(os_memory(), key->key, nonce, plaintext, plaintext_len, ciphertext); if (encrypted_len < 0 || (size_t)encrypted_len != plaintext_len + crypto_box_MACBYTES) { SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED); return false; @@ -316,7 +316,7 @@ bool tox_pass_key_decrypt(const Tox_Pass_Key *key, const uint8_t ciphertext[], s ciphertext += crypto_box_NONCEBYTES; /* decrypt the ciphertext */ - const int32_t decrypted_len = decrypt_data_symmetric(key->key, nonce, ciphertext, decrypt_length + crypto_box_MACBYTES, plaintext); + const int32_t decrypted_len = decrypt_data_symmetric(os_memory(), key->key, nonce, ciphertext, decrypt_length + crypto_box_MACBYTES, plaintext); if (decrypted_len < 0 || (size_t)decrypted_len != decrypt_length) { SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_FAILED); return false;