diff --git a/.cirrus.yml b/.cirrus.yml index 28c40dcdf0..5f7bf44342 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,5 +1,6 @@ --- bazel-opt_task: + timeout_in: 5m container: image: toxchat/toktok-stack:latest-release cpu: 2 @@ -7,9 +8,9 @@ bazel-opt_task: configure_script: - git submodule update --init --recursive - /src/workspace/tools/inject-repo c-toxcore - - sed -i -e 's/build --config=remote/#&/' /src/workspace/.bazelrc.local test_all_script: - cd /src/workspace && bazel test -k + --remote_cache=http://$CIRRUS_HTTP_CACHE_HOST --build_tag_filters=-haskell --test_tag_filters=-haskell -- @@ -17,6 +18,7 @@ bazel-opt_task: -//c-toxcore/auto_tests:tcp_relay_test # Cirrus doesn't allow external network connections. bazel-dbg_task: + timeout_in: 5m container: image: toxchat/toktok-stack:latest-debug cpu: 2 @@ -26,14 +28,15 @@ bazel-dbg_task: - /src/workspace/tools/inject-repo c-toxcore test_all_script: - cd /src/workspace && bazel test -k + --remote_cache=http://$CIRRUS_HTTP_CACHE_HOST --build_tag_filters=-haskell --test_tag_filters=-haskell - --remote_http_cache=http://$CIRRUS_HTTP_CACHE_HOST -- //c-toxcore/... -//c-toxcore/auto_tests:tcp_relay_test # Cirrus doesn't allow external network connections. cimple_task: + timeout_in: 5m container: image: toxchat/toktok-stack:latest-release cpu: 2 @@ -41,17 +44,18 @@ cimple_task: configure_script: - git submodule update --init --recursive - /src/workspace/tools/inject-repo c-toxcore - - sed -i -e 's/build --config=remote/#&/' /src/workspace/.bazelrc.local test_all_script: - cd /src/workspace && bazel test -k + --remote_cache=http://$CIRRUS_HTTP_CACHE_HOST --build_tag_filters=haskell --test_tag_filters=haskell -- //c-toxcore/... freebsd_task: + timeout_in: 5m freebsd_instance: - image_family: freebsd-14-0 + image_family: freebsd-14-1 configure_script: - PAGER=cat ASSUME_ALWAYS_YES=YES pkg install cmake diff --git a/.github/scripts/cmake-android b/.github/scripts/cmake-android index d15f555c79..95ec6600a8 100755 --- a/.github/scripts/cmake-android +++ b/.github/scripts/cmake-android @@ -10,7 +10,7 @@ ABI=${1:-"armeabi-v7a"} case $ABI in armeabi-v7a) TARGET=armv7a-linux-androideabi - NDK_API=19 + NDK_API=21 ;; arm64-v8a) TARGET=aarch64-linux-android @@ -18,7 +18,7 @@ case $ABI in ;; x86) TARGET=i686-linux-android - NDK_API=19 + NDK_API=21 ;; x86_64) TARGET=x86_64-linux-android diff --git a/.github/scripts/flags-clang.sh b/.github/scripts/flags-clang.sh index d0a7729813..f0d9a11c87 100644 --- a/.github/scripts/flags-clang.sh +++ b/.github/scripts/flags-clang.sh @@ -36,9 +36,6 @@ add_flag -Wno-padded # This warns on things like _XOPEN_SOURCE, which we currently need (we # probably won't need these in the future). add_flag -Wno-reserved-id-macro -# TODO(iphydf): Clean these up. They are likely not bugs, but still -# potential issues and probably confusing. -add_flag -Wno-sign-compare # We don't want to have default cases, we want to explicitly define all cases add_flag -Wno-switch-default # __attribute__((nonnull)) causes this warning on defensive null checks. diff --git a/.github/scripts/flags-gcc.sh b/.github/scripts/flags-gcc.sh index 0cacdb4b17..50a0531ac9 100644 --- a/.github/scripts/flags-gcc.sh +++ b/.github/scripts/flags-gcc.sh @@ -47,8 +47,7 @@ add_flag -Wunused-value # struct Foo foo = {0}; is a common idiom. add_flag -Wno-missing-field-initializers -# TODO(iphydf): Clean these up. They are likely not bugs, but still -# potential issues and probably confusing. +# Checked by clang, but gcc is warning when it's not necessary. add_flag -Wno-sign-compare # File transfer code has this. add_flag -Wno-type-limits diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml new file mode 100644 index 0000000000..f618b9ecbf --- /dev/null +++ b/.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/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..9f4ee30be3 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,12 @@ +name: release + +on: + push: + branches: [master] + pull_request_target: + branches: [master] + types: [opened, reopened, synchronize] + +jobs: + release: + uses: TokTok/ci-tools/.github/workflows/release-drafter.yml@master diff --git a/.gitmodules b/.gitmodules index e2793dd7e9..5f564571dc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "third_party/cmp"] path = third_party/cmp - url = https://github.com/camgunz/cmp + url = https://github.com/TokTok/cmp diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bb93bc34a..36bfb39b2c 100644 --- a/CHANGELOG.md +++ b/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/CMakeLists.txt b/CMakeLists.txt index 6f6d37da13..f211207794 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,7 @@ set_source_files_properties( # versions in a synchronised way. set(PROJECT_VERSION_MAJOR "0") set(PROJECT_VERSION_MINOR "2") -set(PROJECT_VERSION_PATCH "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 @@ -161,7 +161,7 @@ option(DHT_BOOTSTRAP "Enable building of DHT_bootstrap" ON) option(BOOTSTRAP_DAEMON "Enable building of tox-bootstrapd" ON) if(BOOTSTRAP_DAEMON AND WIN32) message(WARNING "Building tox-bootstrapd for Windows is not supported, disabling") - set(BOOTSTRAP_DAEMON OFF) + set(BOOTSTRAP_DAEMON OFF CACHE BOOL "" FORCE) endif() option(BUILD_FUZZ_TESTS "Build fuzzing harnesses" OFF) @@ -177,6 +177,7 @@ include(Dependencies) if(MUST_BUILD_TOXAV) set(NO_TOXAV_ERROR_TYPE SEND_ERROR) + set(BUILD_TOXAV ON CACHE BOOL "" FORCE) else() set(NO_TOXAV_ERROR_TYPE WARNING) endif() @@ -184,11 +185,11 @@ endif() if(BUILD_TOXAV) if(NOT OPUS_FOUND) message(${NO_TOXAV_ERROR_TYPE} "Option BUILD_TOXAV is enabled but required library OPUS was not found.") - set(BUILD_TOXAV OFF) + set(BUILD_TOXAV OFF CACHE BOOL "" FORCE) endif() if(NOT VPX_FOUND) message(${NO_TOXAV_ERROR_TYPE} "Option BUILD_TOXAV is enabled but required library VPX was not found.") - set(BUILD_TOXAV OFF) + set(BUILD_TOXAV OFF CACHE BOOL "" FORCE) endif() endif() @@ -391,6 +392,7 @@ if(BUILD_TOXAV) toxav/rtp.h toxav/toxav.c toxav/toxav.h + toxav/toxav_hacks.h toxav/toxav_old.c toxav/video.c toxav/video.h) @@ -597,7 +599,7 @@ if(BOOTSTRAP_DAEMON) add_subdirectory(other/bootstrap_daemon) else() message(WARNING "Option BOOTSTRAP_DAEMON is enabled but required library LIBCONFIG was not found.") - set(BOOTSTRAP_DAEMON OFF) + set(BOOTSTRAP_DAEMON OFF CACHE BOOL "" FORCE) endif() endif() diff --git a/auto_tests/conference_av_test.c b/auto_tests/conference_av_test.c index 39383bd74c..28a2a3a1e3 100644 --- a/auto_tests/conference_av_test.c +++ b/auto_tests/conference_av_test.c @@ -420,7 +420,7 @@ static void test_groupav(AutoTox *autotoxes) tox_events_callback_conference_connected(autotoxes[i].dispatch, handle_conference_connected); } - ck_assert_msg(toxav_add_av_groupchat(autotoxes[0].tox, audio_callback, &autotoxes[0]) != UINT32_MAX, + ck_assert_msg(toxav_add_av_groupchat(autotoxes[0].tox, audio_callback, &autotoxes[0]) != -1, "failed to create group"); printf("tox #%u: inviting its first friend\n", autotoxes[0].index); ck_assert_msg(tox_conference_invite(autotoxes[0].tox, 0, 0, nullptr) != 0, "failed to invite friend"); diff --git a/auto_tests/conference_double_invite_test.c b/auto_tests/conference_double_invite_test.c index 06d880a20d..4d16c8158b 100644 --- a/auto_tests/conference_double_invite_test.c +++ b/auto_tests/conference_double_invite_test.c @@ -28,7 +28,7 @@ static void handle_conference_invite( ck_assert_msg(!state->joined, "invitation callback generated for already joined conference"); - if (friend_number != -1) { + if (friend_number != UINT32_MAX) { Tox_Err_Conference_Join err; state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, diff --git a/auto_tests/conference_invite_merge_test.c b/auto_tests/conference_invite_merge_test.c index d0af332d22..536f47fd74 100644 --- a/auto_tests/conference_invite_merge_test.c +++ b/auto_tests/conference_invite_merge_test.c @@ -21,7 +21,7 @@ static void handle_conference_invite( const uint8_t *cookie = tox_event_conference_invite_get_cookie(event); const size_t length = tox_event_conference_invite_get_cookie_length(event); - if (friend_number != -1) { + if (friend_number != UINT32_MAX) { Tox_Err_Conference_Join err; state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, diff --git a/auto_tests/toxav_many_test.c b/auto_tests/toxav_many_test.c index 2892f7245c..fe1a1033c6 100644 --- a/auto_tests/toxav_many_test.c +++ b/auto_tests/toxav_many_test.c @@ -168,29 +168,33 @@ static void test_av_three_calls(void) Time_Data time_data; pthread_mutex_init(&time_data.lock, nullptr); { + Tox_Options *opts = tox_options_new(nullptr); + ck_assert(opts != nullptr); + tox_options_set_experimental_thread_safety(opts, true); Tox_Err_New error; - bootstrap = tox_new_log(nullptr, &error, &index[0]); + bootstrap = tox_new_log(opts, &error, &index[0]); ck_assert(error == TOX_ERR_NEW_OK); time_data.clock = current_time_monotonic(bootstrap->mono_time); set_current_time_callback(bootstrap, &time_data); - alice = tox_new_log(nullptr, &error, &index[1]); + alice = tox_new_log(opts, &error, &index[1]); ck_assert(error == TOX_ERR_NEW_OK); set_current_time_callback(alice, &time_data); - bobs[0] = tox_new_log(nullptr, &error, &index[2]); + bobs[0] = tox_new_log(opts, &error, &index[2]); ck_assert(error == TOX_ERR_NEW_OK); set_current_time_callback(bobs[0], &time_data); - bobs[1] = tox_new_log(nullptr, &error, &index[3]); + bobs[1] = tox_new_log(opts, &error, &index[3]); ck_assert(error == TOX_ERR_NEW_OK); set_current_time_callback(bobs[1], &time_data); - bobs[2] = tox_new_log(nullptr, &error, &index[4]); + bobs[2] = tox_new_log(opts, &error, &index[4]); ck_assert(error == TOX_ERR_NEW_OK); set_current_time_callback(bobs[2], &time_data); + tox_options_free(opts); } printf("Created 5 instances of Tox\n"); diff --git a/configure.ac b/configure.ac index 76eca6bec7..b2869a9cd7 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.65]) -AC_INIT([tox], [0.2.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/other/analysis/run-clang b/other/analysis/run-clang index a8c85a983a..3f7113b49a 100755 --- a/other/analysis/run-clang +++ b/other/analysis/run-clang @@ -27,7 +27,6 @@ run() { -Wno-missing-noreturn \ -Wno-old-style-cast \ -Wno-padded \ - -Wno-sign-compare \ -Wno-switch-default \ -Wno-tautological-pointer-compare \ -Wno-unreachable-code-return \ diff --git a/other/analysis/run-cppcheck b/other/analysis/run-cppcheck index 7e341f698d..03c597d709 100755 --- a/other/analysis/run-cppcheck +++ b/other/analysis/run-cppcheck @@ -20,8 +20,6 @@ CPPCHECK+=("--suppress=knownConditionTrueFalse") CPPCHECK+=("--suppress=missingIncludeSystem") # TODO(iphydf): Maybe fix? CPPCHECK+=("--suppress=signConversion") -# TODO(iphydf): Fixed in the toxav refactor PR. -CPPCHECK+=("--suppress=redundantAssignment") # We use this for VLAs. CPPCHECK_CXX+=("--suppress=allocaCalled") diff --git a/other/bootstrap_daemon/docker/Dockerfile b/other/bootstrap_daemon/docker/Dockerfile index 1cbaf4c0ae..3d150e02f6 100644 --- a/other/bootstrap_daemon/docker/Dockerfile +++ b/other/bootstrap_daemon/docker/Dockerfile @@ -5,11 +5,11 @@ FROM alpine:3.19.0 AS build RUN ["apk", "--no-cache", "add",\ "clang",\ "cmake",\ - "linux-headers",\ "libconfig-dev",\ "libconfig-static",\ "libsodium-dev",\ "libsodium-static",\ + "linux-headers",\ "musl-dev",\ "ninja",\ "python3"] diff --git a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 index c726f000c5..33ace212cb 100644 --- a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 +++ b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 @@ -1 +1 @@ -e96f03a89051c5df12c28d0d6941184da2b92742d248bd4c57d31189a0052844 /usr/local/bin/tox-bootstrapd +9ec2993a28988bd147bf8f4f21a824c2fc5dbf7255e391b3ce517d337ebce5c1 /usr/local/bin/tox-bootstrapd diff --git a/other/bootstrap_daemon/src/config.c b/other/bootstrap_daemon/src/config.c index 05e473554d..ba9efa2ad7 100644 --- a/other/bootstrap_daemon/src/config.c +++ b/other/bootstrap_daemon/src/config.c @@ -138,9 +138,20 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por } } +// A wrapper function that actually takes a bool argument +static int tox_config_lookup_bool(const config_t *config, const char *path, bool *bool_value) +{ + int int_value = 0; + if (config_lookup_bool(config, path, &int_value) == CONFIG_FALSE) { + return CONFIG_FALSE; + } + *bool_value = int_value != 0; + return CONFIG_TRUE; +} + bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **keys_file_path, int *port, - int *enable_ipv6, int *enable_ipv4_fallback, int *enable_lan_discovery, int *enable_tcp_relay, - uint16_t **tcp_relay_ports, int *tcp_relay_port_count, int *enable_motd, char **motd) + bool *enable_ipv6, bool *enable_ipv4_fallback, bool *enable_lan_discovery, bool *enable_tcp_relay, + uint16_t **tcp_relay_ports, int *tcp_relay_port_count, bool *enable_motd, char **motd) { config_t cfg; @@ -207,14 +218,14 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char ** memcpy(*keys_file_path, tmp_keys_file, keys_file_path_len); // Get IPv6 option - if (config_lookup_bool(&cfg, NAME_ENABLE_IPV6, enable_ipv6) == CONFIG_FALSE) { + if (tox_config_lookup_bool(&cfg, NAME_ENABLE_IPV6, enable_ipv6) == CONFIG_FALSE) { log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_IPV6); log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_IPV6, DEFAULT_ENABLE_IPV6 ? "true" : "false"); *enable_ipv6 = DEFAULT_ENABLE_IPV6; } // Get IPv4 fallback option - if (config_lookup_bool(&cfg, NAME_ENABLE_IPV4_FALLBACK, enable_ipv4_fallback) == CONFIG_FALSE) { + if (tox_config_lookup_bool(&cfg, NAME_ENABLE_IPV4_FALLBACK, enable_ipv4_fallback) == CONFIG_FALSE) { log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_IPV4_FALLBACK); log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_IPV4_FALLBACK, DEFAULT_ENABLE_IPV4_FALLBACK ? "true" : "false"); @@ -222,7 +233,7 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char ** } // Get LAN discovery option - if (config_lookup_bool(&cfg, NAME_ENABLE_LAN_DISCOVERY, enable_lan_discovery) == CONFIG_FALSE) { + if (tox_config_lookup_bool(&cfg, NAME_ENABLE_LAN_DISCOVERY, enable_lan_discovery) == CONFIG_FALSE) { log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_LAN_DISCOVERY); log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, DEFAULT_ENABLE_LAN_DISCOVERY ? "true" : "false"); @@ -230,28 +241,28 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char ** } // Get TCP relay option - if (config_lookup_bool(&cfg, NAME_ENABLE_TCP_RELAY, enable_tcp_relay) == CONFIG_FALSE) { + if (tox_config_lookup_bool(&cfg, NAME_ENABLE_TCP_RELAY, enable_tcp_relay) == CONFIG_FALSE) { log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_TCP_RELAY); log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_TCP_RELAY, DEFAULT_ENABLE_TCP_RELAY ? "true" : "false"); *enable_tcp_relay = DEFAULT_ENABLE_TCP_RELAY; } - if (*enable_tcp_relay != 0) { + if (*enable_tcp_relay) { parse_tcp_relay_ports_config(&cfg, tcp_relay_ports, tcp_relay_port_count); } else { *tcp_relay_port_count = 0; } // Get MOTD option - if (config_lookup_bool(&cfg, NAME_ENABLE_MOTD, enable_motd) == CONFIG_FALSE) { + if (tox_config_lookup_bool(&cfg, NAME_ENABLE_MOTD, enable_motd) == CONFIG_FALSE) { log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_MOTD); log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_MOTD, DEFAULT_ENABLE_MOTD ? "true" : "false"); *enable_motd = DEFAULT_ENABLE_MOTD; } - if (*enable_motd != 0) { + if (*enable_motd) { // Get MOTD const char *tmp_motd; @@ -273,14 +284,14 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char ** log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_PID_FILE_PATH, *pid_file_path); log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_KEYS_FILE_PATH, *keys_file_path); log_write(LOG_LEVEL_INFO, "'%s': %d\n", NAME_PORT, *port); - log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV6, *enable_ipv6 != 0 ? "true" : "false"); - log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV4_FALLBACK, *enable_ipv4_fallback != 0 ? "true" : "false"); - log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, *enable_lan_discovery != 0 ? "true" : "false"); + log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV6, *enable_ipv6 ? "true" : "false"); + log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV4_FALLBACK, *enable_ipv4_fallback ? "true" : "false"); + log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, *enable_lan_discovery ? "true" : "false"); - log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_TCP_RELAY, *enable_tcp_relay != 0 ? "true" : "false"); + log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_TCP_RELAY, *enable_tcp_relay ? "true" : "false"); // Show info about tcp ports only if tcp relay is enabled - if (*enable_tcp_relay != 0) { + if (*enable_tcp_relay) { if (*tcp_relay_port_count == 0) { log_write(LOG_LEVEL_ERROR, "No TCP ports could be read.\n"); } else { @@ -292,9 +303,9 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char ** } } - log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_MOTD, *enable_motd != 0 ? "true" : "false"); + log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_MOTD, *enable_motd ? "true" : "false"); - if (*enable_motd != 0) { + if (*enable_motd) { log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_MOTD, *motd); } diff --git a/other/bootstrap_daemon/src/config.h b/other/bootstrap_daemon/src/config.h index be1e57aa51..677dde5c8b 100644 --- a/other/bootstrap_daemon/src/config.h +++ b/other/bootstrap_daemon/src/config.h @@ -17,14 +17,14 @@ * * Important: You are responsible for freeing `pid_file_path` and `keys_file_path` * also, iff `tcp_relay_ports_count` > 0, then you are responsible for freeing `tcp_relay_ports` - * and also `motd` iff `enable_motd` is set. + * and also `motd` iff `enable_motd` is true. * * @return true on success, * false on failure, doesn't modify any data pointed by arguments. */ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **keys_file_path, int *port, - int *enable_ipv6, int *enable_ipv4_fallback, int *enable_lan_discovery, int *enable_tcp_relay, - uint16_t **tcp_relay_ports, int *tcp_relay_port_count, int *enable_motd, char **motd); + bool *enable_ipv6, bool *enable_ipv4_fallback, bool *enable_lan_discovery, bool *enable_tcp_relay, + uint16_t **tcp_relay_ports, int *tcp_relay_port_count, bool *enable_motd, char **motd); /** * Bootstraps off nodes listed in the config file. diff --git a/other/bootstrap_daemon/src/config_defaults.h b/other/bootstrap_daemon/src/config_defaults.h index 2e2c94f804..68f444f187 100644 --- a/other/bootstrap_daemon/src/config_defaults.h +++ b/other/bootstrap_daemon/src/config_defaults.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-3.0-or-later - * Copyright © 2016-2023 The TokTok team. + * Copyright © 2016-2024 The TokTok team. * Copyright © 2014-2016 Tox project. */ @@ -10,17 +10,19 @@ #ifndef C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_DEFAULTS_H #define C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_DEFAULTS_H +#include + #include "global.h" #define DEFAULT_PID_FILE_PATH "tox-bootstrapd.pid" #define DEFAULT_KEYS_FILE_PATH "tox-bootstrapd.keys" #define DEFAULT_PORT 33445 -#define DEFAULT_ENABLE_IPV6 1 // 1 - true, 0 - false -#define DEFAULT_ENABLE_IPV4_FALLBACK 1 // 1 - true, 0 - false -#define DEFAULT_ENABLE_LAN_DISCOVERY 1 // 1 - true, 0 - false -#define DEFAULT_ENABLE_TCP_RELAY 1 // 1 - true, 0 - false +#define DEFAULT_ENABLE_IPV6 true +#define DEFAULT_ENABLE_IPV4_FALLBACK true +#define DEFAULT_ENABLE_LAN_DISCOVERY true +#define DEFAULT_ENABLE_TCP_RELAY true #define DEFAULT_TCP_RELAY_PORTS 443, 3389, 33445 // comma-separated list of ports -#define DEFAULT_ENABLE_MOTD 1 // 1 - true, 0 - false +#define DEFAULT_ENABLE_MOTD true #define DEFAULT_MOTD DAEMON_NAME #endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_DEFAULTS_H diff --git a/other/bootstrap_daemon/src/tox-bootstrapd.c b/other/bootstrap_daemon/src/tox-bootstrapd.c index 44a9c282c4..60e14c08f5 100644 --- a/other/bootstrap_daemon/src/tox-bootstrapd.c +++ b/other/bootstrap_daemon/src/tox-bootstrapd.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 © 2014-2016 Tox project. */ @@ -240,13 +240,13 @@ int main(int argc, char *argv[]) char *pid_file_path = nullptr; char *keys_file_path = nullptr; int start_port = 0; - int enable_ipv6 = 0; - int enable_ipv4_fallback = 0; - int enable_lan_discovery = 0; - int enable_tcp_relay = 0; + bool enable_ipv6 = false; + bool enable_ipv4_fallback = false; + bool enable_lan_discovery = false; + bool enable_tcp_relay = false; uint16_t *tcp_relay_ports = nullptr; int tcp_relay_port_count = 0; - int enable_motd = 0; + bool enable_motd = false; char *motd = nullptr; if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &start_port, &enable_ipv6, &enable_ipv4_fallback, @@ -281,7 +281,7 @@ int main(int argc, char *argv[]) free(pid_file_path); IP ip; - ip_init(&ip, enable_ipv6 != 0); + ip_init(&ip, enable_ipv6); Logger *logger = logger_new(); @@ -296,10 +296,10 @@ int main(int argc, char *argv[]) Networking_Core *net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr); if (net == nullptr) { - if (enable_ipv6 != 0 && enable_ipv4_fallback != 0) { + if (enable_ipv6 && enable_ipv4_fallback) { log_write(LOG_LEVEL_WARNING, "Couldn't initialize IPv6 networking. Falling back to using IPv4.\n"); - enable_ipv6 = 0; - ip_init(&ip, enable_ipv6 != 0); + enable_ipv6 = false; + ip_init(&ip, enable_ipv6); net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr); if (net == nullptr) { @@ -334,7 +334,7 @@ int main(int argc, char *argv[]) mono_time_update(mono_time); - DHT *const dht = new_dht(logger, mem, rng, ns, mono_time, net, true, enable_lan_discovery != 0); + DHT *const dht = new_dht(logger, mem, rng, ns, mono_time, net, true, enable_lan_discovery); if (dht == nullptr) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n"); @@ -429,7 +429,7 @@ int main(int argc, char *argv[]) gca_onion_init(group_announce, onion_a); - if (enable_motd != 0) { + if (enable_motd) { if (bootstrap_set_callbacks(dht_get_net(dht), DAEMON_VERSION_NUMBER, (uint8_t *)motd, strlen(motd) + 1) == 0) { log_write(LOG_LEVEL_INFO, "Set MOTD successfully.\n"); free(motd); @@ -472,7 +472,7 @@ int main(int argc, char *argv[]) TCP_Server *tcp_server = nullptr; - if (enable_tcp_relay != 0) { + if (enable_tcp_relay) { if (tcp_relay_port_count == 0) { log_write(LOG_LEVEL_ERROR, "No TCP relay ports read. Exiting.\n"); kill_onion_announce(onion_a); @@ -488,7 +488,7 @@ int main(int argc, char *argv[]) return 1; } - tcp_server = new_tcp_server(logger, mem, rng, ns, enable_ipv6 != 0, + tcp_server = new_tcp_server(logger, mem, rng, ns, enable_ipv6, tcp_relay_port_count, tcp_relay_ports, dht_get_self_secret_key(dht), onion, forwarding); @@ -535,7 +535,7 @@ int main(int argc, char *argv[]) } } - if (bootstrap_from_config(cfg_file_path, dht, enable_ipv6 != 0)) { + if (bootstrap_from_config(cfg_file_path, dht, enable_ipv6)) { log_write(LOG_LEVEL_INFO, "List of bootstrap nodes read successfully.\n"); } else { log_write(LOG_LEVEL_ERROR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path); @@ -561,7 +561,7 @@ int main(int argc, char *argv[]) Broadcast_Info *broadcast = nullptr; - if (enable_lan_discovery != 0) { + if (enable_lan_discovery) { broadcast = lan_discovery_init(ns); log_write(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n"); } @@ -589,12 +589,12 @@ int main(int argc, char *argv[]) do_dht(dht); - if (enable_lan_discovery != 0 && mono_time_is_timeout(mono_time, last_lan_discovery, LAN_DISCOVERY_INTERVAL)) { + if (enable_lan_discovery && mono_time_is_timeout(mono_time, last_lan_discovery, LAN_DISCOVERY_INTERVAL)) { lan_discovery_send(dht_get_net(dht), broadcast, dht_get_self_public_key(dht), net_htons_port); last_lan_discovery = mono_time_get(mono_time); } - if (enable_tcp_relay != 0) { + if (enable_tcp_relay) { do_tcp_server(tcp_server, mono_time); } @@ -618,7 +618,7 @@ int main(int argc, char *argv[]) break; default: - log_write(LOG_LEVEL_INFO, "Received (%d) signal. Exiting.\n", caught_signal); + log_write(LOG_LEVEL_INFO, "Received (%ld) signal. Exiting.\n", (long)caught_signal); } lan_discovery_kill(broadcast); diff --git a/other/bootstrap_daemon/websocket/websockify/go.mod b/other/bootstrap_daemon/websocket/websockify/go.mod index 6db72397b2..541af4e64e 100644 --- a/other/bootstrap_daemon/websocket/websockify/go.mod +++ b/other/bootstrap_daemon/websocket/websockify/go.mod @@ -4,4 +4,4 @@ go 1.17 require github.com/gorilla/websocket v1.5.1 -require golang.org/x/net v0.17.0 // indirect +require golang.org/x/net v0.23.0 // indirect diff --git a/other/bootstrap_daemon/websocket/websockify/go.sum b/other/bootstrap_daemon/websocket/websockify/go.sum index 487893c99c..b147484d65 100644 --- a/other/bootstrap_daemon/websocket/websockify/go.sum +++ b/other/bootstrap_daemon/websocket/websockify/go.sum @@ -4,6 +4,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -11,8 +13,10 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -24,17 +28,22 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/other/docker/compcert/compcert.Dockerfile b/other/docker/compcert/compcert.Dockerfile index 567ea786c5..90f16edf6f 100644 --- a/other/docker/compcert/compcert.Dockerfile +++ b/other/docker/compcert/compcert.Dockerfile @@ -13,7 +13,7 @@ COPY --from=sources /src/ /work/ SHELL ["/bin/bash", "-o", "pipefail", "-c"] -RUN git clone --depth=1 https://github.com/jedisct1/libsodium /work/libsodium +RUN git clone --depth=1 --branch=stable https://github.com/jedisct1/libsodium /work/libsodium COPY other/docker/compcert/Makefile /work/ RUN make "-j$(nproc)" RUN ./send_message_test | grep 'tox clients connected' diff --git a/other/docker/perf/Dockerfile b/other/docker/perf/Dockerfile index fe2db29c57..864f29c727 100644 --- a/other/docker/perf/Dockerfile +++ b/other/docker/perf/Dockerfile @@ -3,10 +3,10 @@ FROM alpine:3.14.0 RUN ["apk", "add", "--no-cache", \ "bash", \ "gcc", \ - "linux-headers", \ - "musl-dev", \ "libsodium-dev", \ "libvpx-dev", \ + "linux-headers", \ + "musl-dev", \ "opus-dev", \ "perf"] diff --git a/other/docker/pkgsrc/pkgsrc.Dockerfile b/other/docker/pkgsrc/pkgsrc.Dockerfile index c27ed7cb35..3483bdfba4 100644 --- a/other/docker/pkgsrc/pkgsrc.Dockerfile +++ b/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/other/docker/windows/get_packages.sh b/other/docker/windows/get_packages.sh index efd81e68c9..54fc155851 100755 --- a/other/docker/windows/get_packages.sh +++ b/other/docker/windows/get_packages.sh @@ -52,7 +52,7 @@ if [ "$SUPPORT_TEST" = "true" ]; then https://dl.winehq.org/wine-builds/debian/dists/bookworm/winehq-bookworm.sources . ./check_sha256.sh - check_sha256 "78b185fabdb323971d13bd329fefc8038e08559aa51c4996de18db0639a51df6" \ + check_sha256 "d965d646defe94b3dfba6d5b4406900ac6c81065428bf9d9303ad7a72ee8d1b8" \ "/etc/apt/keyrings/winehq-archive.key" check_sha256 "8dd8ef66c749d56e798646674c1c185a99b3ed6727ca0fbb5e493951e66c0f9e" \ "/etc/apt/sources.list.d/winehq-bookworm.sources" diff --git a/other/emscripten/Dockerfile b/other/emscripten/Dockerfile index 112b75672b..adfbdba7e3 100644 --- a/other/emscripten/Dockerfile +++ b/other/emscripten/Dockerfile @@ -34,6 +34,7 @@ RUN . "/work/emsdk/emsdk_env.sh" \ && emconfigure ./configure --disable-shared \ --without-pthreads \ --disable-ssp --disable-asm --disable-pie \ + --host x86_64-linux-gnu \ && emmake make install -j8 # Build an unused libsodium binding first so emcc caches all the system diff --git a/other/event_tooling/generate_event_c.cpp b/other/event_tooling/generate_event_c.cpp index 2ef1e056fa..9ac3d4856f 100644 --- a/other/event_tooling/generate_event_c.cpp +++ b/other/event_tooling/generate_event_c.cpp @@ -444,7 +444,10 @@ void generate_event_impl(const std::string& event_name, const std::vector> /etc/apt/sources.list && \ @@ -36,12 +48,37 @@ RUN echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu focal main RUN apt-get update && apt-get full-upgrade -y && \ apt-get -y install --no-install-suggests --no-install-recommends \ - gcc-10 g++-10 gcc-10-plugin-dev gcc-10-multilib gcc-multilib gdb lcov \ - clang-12 clang-tools-12 libc++1-12 libc++-12-dev \ - libc++abi1-12 libc++abi-12-dev libclang1-12 libclang-12-dev \ - libclang-common-12-dev libclang-cpp12 libclang-cpp12-dev liblld-12 \ - liblld-12-dev liblldb-12 liblldb-12-dev libllvm12 libomp-12-dev \ - libomp5-12 lld-12 lldb-12 llvm-12 llvm-12-dev llvm-12-runtime llvm-12-tools \ + clang-12 \ + clang-tools-12 \ + g++-10 \ + gcc-10 \ + gcc-10-multilib \ + gcc-10-plugin-dev \ + gcc-multilib \ + gdb \ + lcov \ + libc++-12-dev \ + libc++1-12 \ + libc++abi-12-dev \ + libc++abi1-12 \ + libclang-12-dev \ + libclang-common-12-dev \ + libclang-cpp12 \ + libclang-cpp12-dev \ + libclang1-12 \ + liblld-12 \ + liblld-12-dev \ + liblldb-12 \ + liblldb-12-dev \ + libllvm12 \ + libomp-12-dev \ + libomp5-12 \ + lld-12 \ + lldb-12 \ + llvm-12 \ + llvm-12-dev \ + llvm-12-runtime \ + llvm-12-tools \ && rm -rf /var/lib/apt/lists/* RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 0 diff --git a/third_party/cmp b/third_party/cmp index 643e6a62d4..2ac6bca152 160000 --- a/third_party/cmp +++ b/third_party/cmp @@ -1 +1 @@ -Subproject commit 643e6a62d4eb0ec2277de269cda33da02cba2756 +Subproject commit 2ac6bca152987c805c04423ebbba4b750585337f diff --git a/toxav/BUILD.bazel b/toxav/BUILD.bazel index f9a669e15d..90fb40d716 100644 --- a/toxav/BUILD.bazel +++ b/toxav/BUILD.bazel @@ -41,125 +41,30 @@ cc_library( deps = ["//c-toxcore/toxcore:ccompat"], ) -cc_library( - name = "bwcontroller", - srcs = ["bwcontroller.c"], - hdrs = ["bwcontroller.h"], - deps = [ - ":ring_buffer", - "//c-toxcore/toxcore", - "//c-toxcore/toxcore:Messenger", - "//c-toxcore/toxcore:ccompat", - "//c-toxcore/toxcore:logger", - "//c-toxcore/toxcore:mono_time", - "//c-toxcore/toxcore:tox", - "//c-toxcore/toxcore:util", - ], -) - -cc_library( - name = "rtp", - srcs = ["rtp.c"], - hdrs = ["rtp.h"], - deps = [ - ":bwcontroller", - "//c-toxcore/toxcore:Messenger", - "//c-toxcore/toxcore:ccompat", - "//c-toxcore/toxcore:logger", - "//c-toxcore/toxcore:mono_time", - "//c-toxcore/toxcore:tox", - "//c-toxcore/toxcore:util", - ], -) - -cc_test( - name = "rtp_test", - size = "small", - srcs = ["rtp_test.cc"], - deps = [ - ":rtp", - "//c-toxcore/toxcore:crypto_core", - "@com_google_googletest//:gtest", - "@com_google_googletest//:gtest_main", - ], -) - -cc_library( - name = "audio", - srcs = ["audio.c"], - hdrs = ["audio.h"], - deps = [ - ":public_api", - ":rtp", - "//c-toxcore/toxcore:ccompat", - "//c-toxcore/toxcore:logger", - "//c-toxcore/toxcore:mono_time", - "//c-toxcore/toxcore:util", - "@opus", - ], -) - -cc_library( - name = "video", - srcs = [ - "msi.c", - "video.c", - ], - hdrs = [ - "msi.h", - "video.h", - ], - deps = [ - ":audio", - ":public_api", - ":ring_buffer", - ":rtp", - "//c-toxcore/toxcore:Messenger", - "//c-toxcore/toxcore:ccompat", - "//c-toxcore/toxcore:logger", - "//c-toxcore/toxcore:mono_time", - "//c-toxcore/toxcore:network", - "//c-toxcore/toxcore:util", - "@libvpx", - ], -) - -cc_library( - name = "groupav", - srcs = ["groupav.c"], - hdrs = ["groupav.h"], - deps = [ - "//c-toxcore/toxcore", - "//c-toxcore/toxcore:ccompat", - "//c-toxcore/toxcore:group", - "//c-toxcore/toxcore:logger", - "//c-toxcore/toxcore:mono_time", - "//c-toxcore/toxcore:tox", - "//c-toxcore/toxcore:util", - "@opus", - ], -) - cc_library( name = "toxav", - srcs = [ - "toxav.c", - "toxav_old.c", - ], - hdrs = [ - "toxav.h", - ], + srcs = glob( + [ + "*.c", + "*.h", + ], + exclude = ["toxav.h"], + ), + hdrs = ["toxav.h"], visibility = ["//c-toxcore:__subpackages__"], deps = [ - ":groupav", - ":rtp", - ":video", "//c-toxcore/toxcore:Messenger", "//c-toxcore/toxcore:ccompat", + "//c-toxcore/toxcore:group", "//c-toxcore/toxcore:logger", "//c-toxcore/toxcore:mono_time", + "//c-toxcore/toxcore:net_crypto", + "//c-toxcore/toxcore:network", "//c-toxcore/toxcore:tox", "//c-toxcore/toxcore:util", + "@libsodium", + "@libvpx", + "@opus", ], ) diff --git a/toxav/Makefile.inc b/toxav/Makefile.inc index a8465a2f66..6d34135f3c 100644 --- a/toxav/Makefile.inc +++ b/toxav/Makefile.inc @@ -19,6 +19,7 @@ libtoxav_la_SOURCES = ../toxav/rtp.h \ ../toxav/ring_buffer.h \ ../toxav/ring_buffer.c \ ../toxav/toxav.h \ + ../toxav/toxav_hacks.h \ ../toxav/toxav.c \ ../toxav/toxav_old.c diff --git a/toxav/audio.c b/toxav/audio.c index 2cbc02d20a..ab11cc0d6b 100644 --- a/toxav/audio.c +++ b/toxav/audio.c @@ -13,6 +13,7 @@ #include "../toxcore/ccompat.h" #include "../toxcore/logger.h" #include "../toxcore/mono_time.h" +#include "../toxcore/network.h" static struct JitterBuffer *jbuf_new(uint32_t capacity); static void jbuf_clear(struct JitterBuffer *q); @@ -25,6 +26,8 @@ static bool reconfigure_audio_encoder(const Logger *log, OpusEncoder **e, uint32 uint8_t new_ch, uint32_t *old_br, uint32_t *old_sr, uint8_t *old_ch); static bool reconfigure_audio_decoder(ACSession *ac, uint32_t sampling_rate, uint8_t channels); + + ACSession *ac_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t friend_number, toxav_audio_receive_frame_cb *cb, void *cb_data) { @@ -150,9 +153,9 @@ void ac_iterate(ACSession *ac) ac->lp_channel_count = opus_packet_get_nb_channels(msg->data + 4); - /* NOTE: even though OPUS supports decoding mono frames with stereo decoder and vice versa, - * it didn't work quite well. - */ + /** NOTE: even though OPUS supports decoding mono frames with stereo decoder and vice versa, + * it didn't work quite well. + */ if (!reconfigure_audio_decoder(ac, ac->lp_sampling_rate, ac->lp_channel_count)) { LOGGER_WARNING(ac->log, "Failed to reconfigure decoder!"); free(msg); @@ -273,6 +276,7 @@ static struct JitterBuffer *jbuf_new(uint32_t capacity) q->capacity = capacity; return q; } + static void jbuf_clear(struct JitterBuffer *q) { while (q->bottom != q->top) { @@ -281,6 +285,7 @@ static void jbuf_clear(struct JitterBuffer *q) ++q->bottom; } } + static void jbuf_free(struct JitterBuffer *q) { if (q == nullptr) { @@ -291,6 +296,11 @@ static void jbuf_free(struct JitterBuffer *q) free(q->queue); free(q); } + +/* + * if -1 is returned the RTPMessage m needs to be free'd by the caller + * if 0 is returned the RTPMessage m is stored in the ringbuffer and must NOT be freed by the caller + */ static int jbuf_write(const Logger *log, struct JitterBuffer *q, struct RTPMessage *m) { const uint16_t sequnum = m->header.sequnum; @@ -319,6 +329,7 @@ static int jbuf_write(const Logger *log, struct JitterBuffer *q, struct RTPMessa return 0; } + static struct RTPMessage *jbuf_read(struct JitterBuffer *q, int32_t *success) { if (q->top == q->bottom) { @@ -377,6 +388,21 @@ static OpusEncoder *create_audio_encoder(const Logger *log, uint32_t bit_rate, u goto FAILURE; } + /* + * The libopus library defaults to VBR, which is unsafe in any VoIP environment + * (see for example doi:10.1109/SP.2011.34). Switching to CBR very slightly + * decreases audio quality at lower bitrates. + * + * Parameters: + * `[in]` `x` `opus_int32`: Whether to use VBR mode, 1 (VBR) is default + */ + status = opus_encoder_ctl(rc, OPUS_SET_VBR(0)); + + if (status != OPUS_OK) { + LOGGER_ERROR(log, "Error while setting encoder ctl: %s", opus_strerror(status)); + goto FAILURE; + } + /* * Configures the encoder's use of inband forward error correction. * Note: diff --git a/toxav/bwcontroller.c b/toxav/bwcontroller.c index e9ceb96b5a..8dacc92bb0 100644 --- a/toxav/bwcontroller.c +++ b/toxav/bwcontroller.c @@ -10,12 +10,16 @@ #include #include "ring_buffer.h" +#include "toxav_hacks.h" #include "../toxcore/ccompat.h" #include "../toxcore/logger.h" #include "../toxcore/mono_time.h" +#include "../toxcore/network.h" +#include "../toxcore/tox_private.h" #include "../toxcore/util.h" + #define BWC_PACKET_ID 196 #define BWC_SEND_INTERVAL_MS 950 // 0.95s #define BWC_AVG_PKT_COUNT 20 @@ -38,9 +42,8 @@ typedef struct BWCRcvPkt { struct BWController { m_cb *mcb; void *mcb_user_data; - - Messenger *m; Tox *tox; + const Logger *log; uint32_t friend_number; BWCCycle cycle; @@ -49,6 +52,7 @@ struct BWController { uint32_t packet_loss_counted_cycles; Mono_Time *bwc_mono_time; + bool bwc_receive_active; /* if this is set to false then incoming bwc packets will not be processed by bwc_handle_data() */ }; struct BWCMessage { @@ -56,11 +60,11 @@ struct BWCMessage { uint32_t recv; }; -static int bwc_handle_data(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object); -static int bwc_send_custom_lossy_packet(Tox *tox, int32_t friendnumber, const uint8_t *data, uint32_t length); +static void bwc_handle_data(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data); static void send_update(BWController *bwc); -BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb, void *mcb_user_data, + +BWController *bwc_new(const Logger *log, Tox *tox, uint32_t friendnumber, m_cb *mcb, void *mcb_user_data, Mono_Time *bwc_mono_time) { BWController *retu = (BWController *)calloc(1, sizeof(BWController)); @@ -69,16 +73,18 @@ BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb, return nullptr; } - LOGGER_DEBUG(m->log, "Creating bandwidth controller"); + LOGGER_DEBUG(log, "Creating bandwidth controller"); + retu->mcb = mcb; retu->mcb_user_data = mcb_user_data; - retu->m = m; retu->friend_number = friendnumber; retu->bwc_mono_time = bwc_mono_time; const uint64_t now = current_time_monotonic(bwc_mono_time); retu->cycle.last_sent_timestamp = now; retu->cycle.last_refresh_timestamp = now; retu->tox = tox; + retu->log = log; + retu->bwc_receive_active = true; retu->rcvpkt.rb = rb_new(BWC_AVG_PKT_COUNT); retu->cycle.lost = 0; retu->cycle.recv = 0; @@ -89,7 +95,6 @@ BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb, rb_write(retu->rcvpkt.rb, &retu->rcvpkt.packet_length_array[i]); } - m_callback_rtp_packet(m, friendnumber, BWC_PACKET_ID, bwc_handle_data, retu); return retu; } @@ -99,7 +104,6 @@ void bwc_kill(BWController *bwc) return; } - m_callback_rtp_packet(bwc->m, bwc->friend_number, BWC_PACKET_ID, nullptr, nullptr); rb_kill(bwc->rcvpkt.rb); free(bwc); } @@ -111,7 +115,7 @@ void bwc_add_lost(BWController *bwc, uint32_t bytes_lost) } if (bytes_lost > 0) { - LOGGER_DEBUG(bwc->m->log, "BWC lost(1): %d", (int)bytes_lost); + LOGGER_DEBUG(bwc->log, "BWC lost(1): %d", (int)bytes_lost); bwc->cycle.lost += bytes_lost; send_update(bwc); } @@ -135,7 +139,7 @@ static void send_update(BWController *bwc) bwc->packet_loss_counted_cycles = 0; if (bwc->cycle.lost != 0) { - LOGGER_DEBUG(bwc->m->log, "%p Sent update rcv: %u lost: %u percent: %f %%", + LOGGER_DEBUG(bwc->log, "%p Sent update rcv: %u lost: %u percent: %f %%", (void *)bwc, bwc->cycle.recv, bwc->cycle.lost, ((double)bwc->cycle.lost / (bwc->cycle.recv + bwc->cycle.lost)) * 100.0); uint8_t bwc_packet[sizeof(struct BWCMessage) + 1]; @@ -148,13 +152,11 @@ static void send_update(BWController *bwc) offset += net_pack_u32(bwc_packet + offset, bwc->cycle.recv); assert(offset == sizeof(bwc_packet)); - if (bwc_send_custom_lossy_packet(bwc->tox, bwc->friend_number, bwc_packet, sizeof(bwc_packet)) == -1) { - char *netstrerror = net_new_strerror(net_error()); - char *stdstrerror = net_new_strerror(errno); - LOGGER_WARNING(bwc->m->log, "BWC send failed (len: %u)! std error: %s, net error %s", - (unsigned)sizeof(bwc_packet), stdstrerror, netstrerror); - net_kill_strerror(stdstrerror); - net_kill_strerror(netstrerror); + Tox_Err_Friend_Custom_Packet error; + tox_friend_send_lossy_packet(bwc->tox, bwc->friend_number, bwc_packet, sizeof(bwc_packet), &error); + + if (error != TOX_ERR_FRIEND_CUSTOM_PACKET_OK) { + LOGGER_WARNING(bwc->log, "BWC send failed: %d", error); } } @@ -166,11 +168,11 @@ static void send_update(BWController *bwc) static int on_update(BWController *bwc, const struct BWCMessage *msg) { - LOGGER_DEBUG(bwc->m->log, "%p Got update from peer", (void *)bwc); + LOGGER_DEBUG(bwc->log, "%p Got update from peer", (void *)bwc); /* Peers sent update too soon */ if (bwc->cycle.last_recv_timestamp + BWC_SEND_INTERVAL_MS > current_time_monotonic(bwc->bwc_mono_time)) { - LOGGER_INFO(bwc->m->log, "%p Rejecting extra update", (void *)bwc); + LOGGER_INFO(bwc->log, "%p Rejecting extra update", (void *)bwc); return -1; } @@ -180,8 +182,8 @@ static int on_update(BWController *bwc, const struct BWCMessage *msg) if (lost != 0 && bwc->mcb != nullptr) { const uint32_t recv = msg->recv; - LOGGER_DEBUG(bwc->m->log, "recved: %u lost: %u percentage: %f %%", recv, lost, - ((double)lost / (recv + lost)) * 100.0); + LOGGER_DEBUG(bwc->log, "recved: %u lost: %u percentage: %f %%", recv, lost, + ((double) lost / (recv + lost)) * 100.0); bwc->mcb(bwc, bwc->friend_number, (float)lost / (recv + lost), bwc->mcb_user_data); @@ -190,28 +192,41 @@ static int on_update(BWController *bwc, const struct BWCMessage *msg) return 0; } -/* - * return -1 on failure, 0 on success - * - */ -static int bwc_send_custom_lossy_packet(Tox *tox, int32_t friendnumber, const uint8_t *data, uint32_t length) +static void bwc_handle_data(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data) { - Tox_Err_Friend_Custom_Packet error; - tox_friend_send_lossy_packet(tox, friendnumber, data, (size_t)length, &error); + /* get BWController object from Tox and friend number */ + ToxAV *toxav = (ToxAV *)tox_get_av_object(tox); - if (error == TOX_ERR_FRIEND_CUSTOM_PACKET_OK) { - return 0; + if (toxav == nullptr) { + // LOGGER_ERROR(log, "Could not get ToxAV object from Tox"); + return; } - return -1; -} - -static int bwc_handle_data(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object) -{ - BWController *bwc = (BWController *)object; + const Logger *log = toxav_get_logger(toxav); if (length - 1 != sizeof(struct BWCMessage)) { - return -1; + LOGGER_ERROR(log, "Got BWCMessage of insufficient size."); + return; + } + + const ToxAVCall *call = call_get(toxav, friend_number); + + if (call == nullptr) { + LOGGER_ERROR(log, "Could not get ToxAVCall object from ToxAV."); + return; + } + + /* get Call object from Tox and friend number */ + BWController *bwc = bwc_controller_get(call); + + if (bwc == nullptr) { + LOGGER_WARNING(log, "No session!"); + return; + } + + if (!bwc->bwc_receive_active) { + LOGGER_WARNING(log, "receiving not allowed!"); + return; } size_t offset = 1; // Ignore packet id. @@ -220,5 +235,15 @@ static int bwc_handle_data(Messenger *m, uint32_t friend_number, const uint8_t * offset += net_unpack_u32(data + offset, &msg.recv); assert(offset == length); - return on_update(bwc, &msg); + on_update(bwc, &msg); +} + +void bwc_allow_receiving(Tox *tox) +{ + tox_callback_friend_lossy_packet_per_pktid(tox, bwc_handle_data, BWC_PACKET_ID); +} + +void bwc_stop_receiving(Tox *tox) +{ + tox_callback_friend_lossy_packet_per_pktid(tox, nullptr, BWC_PACKET_ID); } diff --git a/toxav/bwcontroller.h b/toxav/bwcontroller.h index 53931c030b..0a8f618bc0 100644 --- a/toxav/bwcontroller.h +++ b/toxav/bwcontroller.h @@ -5,19 +5,24 @@ #ifndef C_TOXCORE_TOXAV_BWCONTROLLER_H #define C_TOXCORE_TOXAV_BWCONTROLLER_H -#include "../toxcore/Messenger.h" +#include + +#include "../toxcore/logger.h" +#include "../toxcore/mono_time.h" #include "../toxcore/tox.h" typedef struct BWController BWController; typedef void m_cb(BWController *bwc, uint32_t friend_number, float loss, void *user_data); -BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb, void *mcb_user_data, - Mono_Time *bwc_mono_time); +BWController *bwc_new(const Logger *log, Tox *tox, uint32_t friendnumber, + m_cb *mcb, void *mcb_user_data, Mono_Time *bwc_mono_time); void bwc_kill(BWController *bwc); void bwc_add_lost(BWController *bwc, uint32_t bytes_lost); void bwc_add_recv(BWController *bwc, uint32_t recv_bytes); +void bwc_allow_receiving(Tox *tox); +void bwc_stop_receiving(Tox *tox); #endif /* C_TOXCORE_TOXAV_BWCONTROLLER_H */ diff --git a/toxav/groupav.c b/toxav/groupav.c index 63dd569df6..14ca9bb293 100644 --- a/toxav/groupav.c +++ b/toxav/groupav.c @@ -476,7 +476,7 @@ int groupchat_enable_av(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t return -1; } - for (uint32_t i = 0; i < numpeers; ++i) { + for (uint32_t i = 0; i < (uint32_t)numpeers; ++i) { group_av_peer_new(group_av, conference_number, i); } @@ -508,7 +508,7 @@ int groupchat_disable_av(const Group_Chats *g_c, uint32_t conference_number) return -1; } - for (uint32_t i = 0; i < numpeers; ++i) { + for (uint32_t i = 0; i < (uint32_t)numpeers; ++i) { group_av_peer_delete(group_av, conference_number, group_peer_get_object(g_c, conference_number, i)); group_peer_set_object(g_c, conference_number, i, nullptr); } diff --git a/toxav/msi.c b/toxav/msi.c index 1b375410b2..5173621361 100644 --- a/toxav/msi.c +++ b/toxav/msi.c @@ -9,8 +9,13 @@ #include #include +#include "toxav_hacks.h" + #include "../toxcore/ccompat.h" #include "../toxcore/logger.h" +#include "../toxcore/net_crypto.h" +#include "../toxcore/tox.h" +#include "../toxcore/tox_private.h" #include "../toxcore/util.h" #define MSI_MAXMSG_SIZE 256 @@ -55,20 +60,20 @@ typedef struct MSIMessage { } MSIMessage; static void msg_init(MSIMessage *dest, MSIRequest request); +static void kill_call(const Logger *log, MSICall *call); static int msg_parse_in(const Logger *log, MSIMessage *dest, const uint8_t *data, uint16_t length); static uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const uint8_t *value, uint8_t value_len, uint16_t *length); -static int send_message(const Messenger *m, uint32_t friend_number, const MSIMessage *msg); -static int send_error(const Messenger *m, uint32_t friend_number, MSIError error); -static bool invoke_callback(MSICall *call, MSICallbackID cb); +static int send_message(const Logger *log, Tox *tox, uint32_t friend_number, const MSIMessage *msg); +static int send_error(const Logger *log, Tox *tox, uint32_t friend_number, MSIError error); static MSICall *get_call(MSISession *session, uint32_t friend_number); static MSICall *new_call(MSISession *session, uint32_t friend_number); -static void kill_call(MSICall *call); -static void on_peer_status(Messenger *m, uint32_t friend_number, bool is_online, void *user_data); -static void handle_init(MSICall *call, const MSIMessage *msg); -static void handle_push(MSICall *call, const MSIMessage *msg); -static void handle_pop(MSICall *call, const MSIMessage *msg); -static void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *user_data); +static bool invoke_callback(const Logger *log, MSICall *call, MSICallbackID cb); +static void handle_init(const Logger *log, MSICall *call, const MSIMessage *msg); +static void handle_push(const Logger *log, MSICall *call, const MSIMessage *msg); +static void handle_pop(const Logger *log, MSICall *call, const MSIMessage *msg); +static void handle_msi_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, + void *user_data); /* * Public functions @@ -99,43 +104,43 @@ void msi_callback_capabilities(MSISession *session, msi_action_cb *callback) session->capabilities_callback = callback; } -MSISession *msi_new(Messenger *m) +MSISession *msi_new(const Logger *log, Tox *tox) { - if (m == nullptr) { + if (tox == nullptr) { return nullptr; } MSISession *retu = (MSISession *)calloc(1, sizeof(MSISession)); if (retu == nullptr) { - LOGGER_ERROR(m->log, "Allocation failed! Program might misbehave!"); + LOGGER_ERROR(log, "Allocation failed! Program might misbehave!"); return nullptr; } if (create_recursive_mutex(retu->mutex) != 0) { - LOGGER_ERROR(m->log, "Failed to init mutex! Program might misbehave"); + LOGGER_ERROR(log, "Failed to init mutex! Program might misbehave"); free(retu); return nullptr; } - retu->messenger = m; - - m_callback_msi_packet(m, handle_msi_packet, retu); + retu->tox = tox; - /* This is called when remote terminates session */ - m_callback_connectionstatus_internal_av(m, on_peer_status, retu); + // register callback + tox_callback_friend_lossless_packet_per_pktid(tox, handle_msi_packet, PACKET_ID_MSI); - LOGGER_DEBUG(m->log, "New msi session: %p ", (void *)retu); + LOGGER_DEBUG(log, "New msi session: %p ", (void *)retu); return retu; } -int msi_kill(MSISession *session, const Logger *log) + +int msi_kill(const Logger *log, Tox *tox, MSISession *session) { if (session == nullptr) { LOGGER_ERROR(log, "Tried to terminate non-existing session"); return -1; } - m_callback_msi_packet(session->messenger, nullptr, nullptr); + // UN-register callback + tox_callback_friend_lossless_packet_per_pktid(tox, nullptr, PACKET_ID_MSI); if (pthread_mutex_trylock(session->mutex) != 0) { LOGGER_ERROR(log, "Failed to acquire lock on msi mutex"); @@ -149,10 +154,10 @@ int msi_kill(MSISession *session, const Logger *log) MSICall *it = get_call(session, session->calls_head); while (it != nullptr) { - send_message(session->messenger, it->friend_number, &msg); + send_message(log, session->tox, it->friend_number, &msg); MSICall *temp_it = it; it = it->next; - kill_call(temp_it); /* This will eventually free session->calls */ + kill_call(log, temp_it); /* This will eventually free session->calls */ } } @@ -163,21 +168,57 @@ int msi_kill(MSISession *session, const Logger *log) free(session); return 0; } -int msi_invite(MSISession *session, MSICall **call, uint32_t friend_number, uint8_t capabilities) + +/* + * return true if friend is offline and the call was canceled. + */ +bool check_peer_offline_status(const Logger *log, const Tox *tox, MSISession *session, uint32_t friend_number) +{ + if (tox == nullptr || session == nullptr) { + return false; + } + + Tox_Err_Friend_Query f_con_query_error; + const Tox_Connection f_con_status = tox_friend_get_connection_status(tox, friend_number, &f_con_query_error); + + if (f_con_status == TOX_CONNECTION_NONE) { + /* Friend is now offline */ + LOGGER_DEBUG(log, "Friend %d is now offline", friend_number); + + pthread_mutex_lock(session->mutex); + MSICall *call = get_call(session, friend_number); + + if (call == nullptr) { + pthread_mutex_unlock(session->mutex); + return true; + } + + invoke_callback(log, call, MSI_ON_PEERTIMEOUT); /* Failure is ignored */ + kill_call(log, call); + pthread_mutex_unlock(session->mutex); + return true; + } + + return false; +} + +int msi_invite(const Logger *log, MSISession *session, MSICall **call, uint32_t friend_number, uint8_t capabilities) { + LOGGER_DEBUG(log, "msi_invite:session:%p", (void *)session); + if (session == nullptr) { return -1; } - LOGGER_DEBUG(session->messenger->log, "Session: %p Inviting friend: %u", (void *)session, friend_number); + LOGGER_DEBUG(log, "Session: %p Inviting friend: %u", (void *)session, friend_number); if (pthread_mutex_trylock(session->mutex) != 0) { - LOGGER_ERROR(session->messenger->log, "Failed to acquire lock on msi mutex"); + LOGGER_ERROR(log, "Failed to acquire lock on msi mutex"); return -1; } if (get_call(session, friend_number) != nullptr) { - LOGGER_ERROR(session->messenger->log, "Already in a call"); + LOGGER_ERROR(log, "Already in a call"); pthread_mutex_unlock(session->mutex); return -1; } @@ -197,17 +238,18 @@ int msi_invite(MSISession *session, MSICall **call, uint32_t friend_number, uint msg.capabilities.exists = true; msg.capabilities.value = capabilities; - send_message(temp->session->messenger, temp->friend_number, &msg); + send_message(log, temp->session->tox, temp->friend_number, &msg); temp->state = MSI_CALL_REQUESTING; *call = temp; - LOGGER_DEBUG(session->messenger->log, "Invite sent"); + LOGGER_DEBUG(log, "Invite sent"); pthread_mutex_unlock(session->mutex); return 0; } -int msi_hangup(MSICall *call) + +int msi_hangup(const Logger *log, MSICall *call) { if (call == nullptr || call->session == nullptr) { return -1; @@ -215,16 +257,16 @@ int msi_hangup(MSICall *call) MSISession *session = call->session; - LOGGER_DEBUG(session->messenger->log, "Session: %p Hanging up call with friend: %u", (void *)call->session, + LOGGER_DEBUG(log, "Session: %p Hanging up call with friend: %u", (void *)call->session, call->friend_number); if (pthread_mutex_trylock(session->mutex) != 0) { - LOGGER_ERROR(session->messenger->log, "Failed to acquire lock on msi mutex"); + LOGGER_ERROR(log, "Failed to acquire lock on msi mutex"); return -1; } if (call->state == MSI_CALL_INACTIVE) { - LOGGER_ERROR(session->messenger->log, "Call is in invalid state!"); + LOGGER_ERROR(log, "Call is in invalid state!"); pthread_mutex_unlock(session->mutex); return -1; } @@ -232,13 +274,14 @@ int msi_hangup(MSICall *call) MSIMessage msg; msg_init(&msg, REQU_POP); - send_message(session->messenger, call->friend_number, &msg); + send_message(log, session->tox, call->friend_number, &msg); - kill_call(call); + kill_call(log, call); pthread_mutex_unlock(session->mutex); return 0; } -int msi_answer(MSICall *call, uint8_t capabilities) + +int msi_answer(const Logger *log, MSICall *call, uint8_t capabilities) { if (call == nullptr || call->session == nullptr) { return -1; @@ -246,18 +289,18 @@ int msi_answer(MSICall *call, uint8_t capabilities) MSISession *session = call->session; - LOGGER_DEBUG(session->messenger->log, "Session: %p Answering call from: %u", (void *)call->session, + LOGGER_DEBUG(log, "Session: %p Answering call from: %u", (void *)call->session, call->friend_number); if (pthread_mutex_trylock(session->mutex) != 0) { - LOGGER_ERROR(session->messenger->log, "Failed to acquire lock on msi mutex"); + LOGGER_ERROR(log, "Failed to acquire lock on msi mutex"); return -1; } if (call->state != MSI_CALL_REQUESTED) { /* Though sending in invalid state will not cause anything weird * Its better to not do it like a maniac */ - LOGGER_ERROR(session->messenger->log, "Call is in invalid state!"); + LOGGER_ERROR(log, "Call is in invalid state!"); pthread_mutex_unlock(session->mutex); return -1; } @@ -270,14 +313,15 @@ int msi_answer(MSICall *call, uint8_t capabilities) msg.capabilities.exists = true; msg.capabilities.value = capabilities; - send_message(session->messenger, call->friend_number, &msg); + send_message(log, session->tox, call->friend_number, &msg); call->state = MSI_CALL_ACTIVE; pthread_mutex_unlock(session->mutex); return 0; } -int msi_change_capabilities(MSICall *call, uint8_t capabilities) + +int msi_change_capabilities(const Logger *log, MSICall *call, uint8_t capabilities) { if (call == nullptr || call->session == nullptr) { return -1; @@ -285,16 +329,16 @@ int msi_change_capabilities(MSICall *call, uint8_t capabilities) MSISession *session = call->session; - LOGGER_DEBUG(session->messenger->log, "Session: %p Trying to change capabilities to friend %u", (void *)call->session, + LOGGER_DEBUG(log, "Session: %p Trying to change capabilities to friend %u", (void *)call->session, call->friend_number); if (pthread_mutex_trylock(session->mutex) != 0) { - LOGGER_ERROR(session->messenger->log, "Failed to acquire lock on msi mutex"); + LOGGER_ERROR(log, "Failed to acquire lock on msi mutex"); return -1; } if (call->state != MSI_CALL_ACTIVE) { - LOGGER_ERROR(session->messenger->log, "Call is in invalid state!"); + LOGGER_ERROR(log, "Call is in invalid state!"); pthread_mutex_unlock(session->mutex); return -1; } @@ -307,7 +351,7 @@ int msi_change_capabilities(MSICall *call, uint8_t capabilities) msg.capabilities.exists = true; msg.capabilities.value = capabilities; - send_message(call->session->messenger, call->friend_number, &msg); + send_message(log, call->session->tox, call->friend_number, &msg); pthread_mutex_unlock(session->mutex); return 0; @@ -351,10 +395,51 @@ static bool check_enum_high(const Logger *log, const uint8_t *bytes, uint8_t enu return true; } +static const uint8_t *msg_parse_one(const Logger *log, MSIMessage *dest, const uint8_t *it, int *size_constraint) +{ + switch (*it) { + case ID_REQUEST: { + if (!check_size(log, it, size_constraint, 1) || + !check_enum_high(log, it, REQU_POP)) { + return nullptr; + } + + dest->request.value = (MSIRequest)it[2]; + dest->request.exists = true; + return it + 3; + } + + case ID_ERROR: { + if (!check_size(log, it, size_constraint, 1) || + !check_enum_high(log, it, MSI_E_UNDISCLOSED)) { + return nullptr; + } + + dest->error.value = (MSIError)it[2]; + dest->error.exists = true; + return it + 3; + } + + case ID_CAPABILITIES: { + if (!check_size(log, it, size_constraint, 1)) { + return nullptr; + } + + dest->capabilities.value = it[2]; + dest->capabilities.exists = true; + return it + 3; + } + + default: { + LOGGER_ERROR(log, "Invalid id byte: %d", *it); + return nullptr; + } + } +} + static int msg_parse_in(const Logger *log, MSIMessage *dest, const uint8_t *data, uint16_t length) { /* Parse raw data received from socket into MSIMessage struct */ - assert(dest != nullptr); if (length == 0 || data[length - 1] != 0) { /* End byte must have value 0 */ @@ -368,46 +453,10 @@ static int msg_parse_in(const Logger *log, MSIMessage *dest, const uint8_t *data int size_constraint = length; while (*it != 0) {/* until end byte is hit */ - switch (*it) { - case ID_REQUEST: { - if (!check_size(log, it, &size_constraint, 1) || - !check_enum_high(log, it, REQU_POP)) { - return -1; - } - - dest->request.value = (MSIRequest)it[2]; - dest->request.exists = true; - it += 3; - break; - } - - case ID_ERROR: { - if (!check_size(log, it, &size_constraint, 1) || - !check_enum_high(log, it, MSI_E_UNDISCLOSED)) { - return -1; - } - - dest->error.value = (MSIError)it[2]; - dest->error.exists = true; - it += 3; - break; - } - - case ID_CAPABILITIES: { - if (!check_size(log, it, &size_constraint, 1)) { - return -1; - } + it = msg_parse_one(log, dest, it, &size_constraint); - dest->capabilities.value = it[2]; - dest->capabilities.exists = true; - it += 3; - break; - } - - default: { - LOGGER_ERROR(log, "Invalid id byte"); - return -1; - } + if (it == nullptr) { + return -1; } } @@ -418,6 +467,7 @@ static int msg_parse_in(const Logger *log, MSIMessage *dest, const uint8_t *data return 0; } + static uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const uint8_t *value, uint8_t value_len, uint16_t *length) { @@ -437,11 +487,48 @@ static uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const uint8_ return dest + value_len; /* Set to next position ready to be written */ } -static int send_message(const Messenger *m, uint32_t friend_number, const MSIMessage *msg) + +/* Send an msi packet. + * + * return 1 on success + * return 0 on failure + */ +static int m_msi_packet(Tox *tox, int32_t friendnumber, const uint8_t *data, uint16_t length) { - /* Parse and send message */ - assert(m != nullptr); + // TODO(Zoff): make this better later! ------------------- + /* we need to prepend 1 byte (packet id) to data + * do this without malloc, memcpy and free in the future + */ + const size_t length_new = (size_t)length + 1; + uint8_t *data_new = (uint8_t *)malloc(length_new); + + if (data_new == nullptr) { + return 0; + } + + data_new[0] = PACKET_ID_MSI; + + if (length != 0) { + memcpy(data_new + 1, data, length); + } + + Tox_Err_Friend_Custom_Packet error; + tox_friend_send_lossless_packet(tox, friendnumber, data_new, length_new, &error); + + free(data_new); + + if (error == TOX_ERR_FRIEND_CUSTOM_PACKET_OK) { + return 1; + } + + return 0; +} + +static int send_message(const Logger *log, Tox *tox, uint32_t friend_number, const MSIMessage *msg) +{ + assert(tox != nullptr); + /* Parse and send message */ uint8_t parsed[MSI_MAXMSG_SIZE]; uint8_t *it = parsed; @@ -452,7 +539,7 @@ static int send_message(const Messenger *m, uint32_t friend_number, const MSIMes it = msg_parse_header_out(ID_REQUEST, it, &cast, sizeof(cast), &size); } else { - LOGGER_DEBUG(m->log, "Must have request field"); + LOGGER_DEBUG(log, "Must have request field"); return -1; } @@ -468,26 +555,27 @@ static int send_message(const Messenger *m, uint32_t friend_number, const MSIMes } if (it == parsed) { - LOGGER_WARNING(m->log, "Parsing message failed; empty message"); + LOGGER_WARNING(log, "Parsing message failed; empty message"); return -1; } *it = 0; ++size; - if (m_msi_packet(m, friend_number, parsed, size)) { - LOGGER_DEBUG(m->log, "Sent message"); + if (m_msi_packet(tox, friend_number, parsed, size) == 1) { + LOGGER_DEBUG(log, "Sent message"); return 0; } return -1; } -static int send_error(const Messenger *m, uint32_t friend_number, MSIError error) + +static int send_error(const Logger *log, Tox *tox, uint32_t friend_number, MSIError error) { - /* Send error message */ - assert(m != nullptr); + assert(tox != nullptr); - LOGGER_DEBUG(m->log, "Sending error: %d to friend: %d", error, friend_number); + /* Send error message */ + LOGGER_DEBUG(log, "Sending error: %d to friend: %d", error, friend_number); MSIMessage msg; msg_init(&msg, REQU_POP); @@ -495,13 +583,14 @@ static int send_error(const Messenger *m, uint32_t friend_number, MSIError error msg.error.exists = true; msg.error.value = error; - send_message(m, friend_number, &msg); + send_message(log, tox, friend_number, &msg); return 0; } -static int invoke_callback_inner(MSICall *call, MSICallbackID id) + +static int invoke_callback_inner(const Logger *log, MSICall *call, MSICallbackID id) { MSISession *session = call->session; - LOGGER_DEBUG(session->messenger->log, "invoking callback function: %d", id); + LOGGER_DEBUG(log, "invoking callback function: %d", id); switch (id) { case MSI_ON_INVITE: @@ -523,15 +612,16 @@ static int invoke_callback_inner(MSICall *call, MSICallbackID id) return session->capabilities_callback(session->av, call); } - LOGGER_FATAL(session->messenger->log, "invalid callback id: %d", id); + LOGGER_FATAL(log, "invalid callback id: %d", id); return -1; } -static bool invoke_callback(MSICall *call, MSICallbackID cb) + +static bool invoke_callback(const Logger *log, MSICall *call, MSICallbackID cb) { assert(call != nullptr); - if (invoke_callback_inner(call, cb) != 0) { - LOGGER_WARNING(call->session->messenger->log, + if (invoke_callback_inner(log, call, cb) != 0) { + LOGGER_WARNING(log, "Callback state handling failed, sending error"); /* If no callback present or error happened while handling, @@ -546,6 +636,7 @@ static bool invoke_callback(MSICall *call, MSICallbackID cb) return true; } + static MSICall *get_call(MSISession *session, uint32_t friend_number) { assert(session != nullptr); @@ -556,6 +647,7 @@ static MSICall *get_call(MSISession *session, uint32_t friend_number) return session->calls[friend_number]; } + static MSICall *new_call(MSISession *session, uint32_t friend_number) { assert(session != nullptr); @@ -607,7 +699,8 @@ static MSICall *new_call(MSISession *session, uint32_t friend_number) session->calls[friend_number] = rc; return rc; } -static void kill_call(MSICall *call) + +static void kill_call(const Logger *log, MSICall *call) { /* Assume that session mutex is locked */ if (call == nullptr) { @@ -616,7 +709,7 @@ static void kill_call(MSICall *call) MSISession *session = call->session; - LOGGER_DEBUG(session->messenger->log, "Killing call: %p", (void *)call); + LOGGER_DEBUG(log, "Killing call: %p", (void *)call); MSICall *prev = call->prev; MSICall *next = call->next; @@ -648,37 +741,12 @@ static void kill_call(MSICall *call) free(call); session->calls = nullptr; } -static void on_peer_status(Messenger *m, uint32_t friend_number, bool is_online, void *user_data) -{ - MSISession *session = (MSISession *)user_data; - - if (is_online) { - // Friend is online. - return; - } - LOGGER_DEBUG(m->log, "Friend %d is now offline", friend_number); - pthread_mutex_lock(session->mutex); - MSICall *call = get_call(session, friend_number); - - if (call == nullptr) { - pthread_mutex_unlock(session->mutex); - return; - } - - invoke_callback(call, MSI_ON_PEERTIMEOUT); /* Failure is ignored */ - kill_call(call); - pthread_mutex_unlock(session->mutex); -} -static bool try_handle_init(MSICall *call, const MSIMessage *msg) +static bool try_handle_init(const Logger *log, MSICall *call, const MSIMessage *msg) { - assert(call != nullptr); - LOGGER_DEBUG(call->session->messenger->log, - "Session: %p Handling 'init' friend: %d", (void *)call->session, call->friend_number); - if (!msg->capabilities.exists) { - LOGGER_WARNING(call->session->messenger->log, "Session: %p Invalid capabilities on 'init'", (void *)call->session); + LOGGER_WARNING(log, "Session: %p Invalid capabilities on 'init'", (void *)call->session); call->error = MSI_E_INVALID_MESSAGE; return false; } @@ -689,7 +757,7 @@ static bool try_handle_init(MSICall *call, const MSIMessage *msg) call->peer_capabilities = msg->capabilities.value; call->state = MSI_CALL_REQUESTED; - if (!invoke_callback(call, MSI_ON_INVITE)) { + if (!invoke_callback(log, call, MSI_ON_INVITE)) { return false; } @@ -704,7 +772,7 @@ static bool try_handle_init(MSICall *call, const MSIMessage *msg) * we can automatically answer the re-call. */ - LOGGER_INFO(call->session->messenger->log, "Friend is recalling us"); + LOGGER_INFO(log, "Friend is recalling us"); MSIMessage out_msg; msg_init(&out_msg, REQU_PUSH); @@ -712,7 +780,7 @@ static bool try_handle_init(MSICall *call, const MSIMessage *msg) out_msg.capabilities.exists = true; out_msg.capabilities.value = call->self_capabilities; - send_message(call->session->messenger, call->friend_number, &out_msg); + send_message(log, call->session->tox, call->friend_number, &out_msg); /* If peer changed capabilities during re-call they will * be handled accordingly during the next step @@ -722,7 +790,7 @@ static bool try_handle_init(MSICall *call, const MSIMessage *msg) case MSI_CALL_REQUESTED: // fall-through case MSI_CALL_REQUESTING: { - LOGGER_WARNING(call->session->messenger->log, "Session: %p Invalid state on 'init'", (void *)call->session); + LOGGER_WARNING(log, "Session: %p Invalid state on 'init'", (void *)call->session); call->error = MSI_E_INVALID_STATE; return false; } @@ -730,26 +798,28 @@ static bool try_handle_init(MSICall *call, const MSIMessage *msg) return true; } -static void handle_init(MSICall *call, const MSIMessage *msg) + +static void handle_init(const Logger *log, MSICall *call, const MSIMessage *msg) { assert(call != nullptr); - LOGGER_DEBUG(call->session->messenger->log, + LOGGER_DEBUG(log, "Session: %p Handling 'init' friend: %d", (void *)call->session, call->friend_number); - if (!try_handle_init(call, msg)) { - send_error(call->session->messenger, call->friend_number, call->error); - kill_call(call); + if (!try_handle_init(log, call, msg)) { + send_error(log, call->session->tox, call->friend_number, call->error); + kill_call(log, call); } } -static void handle_push(MSICall *call, const MSIMessage *msg) + +static void handle_push(const Logger *log, MSICall *call, const MSIMessage *msg) { assert(call != nullptr); - LOGGER_DEBUG(call->session->messenger->log, "Session: %p Handling 'push' friend: %d", (void *)call->session, + LOGGER_DEBUG(log, "Session: %p Handling 'push' friend: %d", (void *)call->session, call->friend_number); if (!msg->capabilities.exists) { - LOGGER_WARNING(call->session->messenger->log, "Session: %p Invalid capabilities on 'push'", (void *)call->session); + LOGGER_WARNING(log, "Session: %p Invalid capabilities on 'push'", (void *)call->session); call->error = MSI_E_INVALID_MESSAGE; goto FAILURE; } @@ -757,12 +827,11 @@ static void handle_push(MSICall *call, const MSIMessage *msg) switch (call->state) { case MSI_CALL_ACTIVE: { if (call->peer_capabilities != msg->capabilities.value) { - /* Only act if capabilities changed */ - LOGGER_INFO(call->session->messenger->log, "Friend is changing capabilities to: %u", msg->capabilities.value); + LOGGER_INFO(log, "Friend is changing capabilities to: %u", msg->capabilities.value); call->peer_capabilities = msg->capabilities.value; - if (!invoke_callback(call, MSI_ON_CAPABILITIES)) { + if (!invoke_callback(log, call, MSI_ON_CAPABILITIES)) { goto FAILURE; } } @@ -771,13 +840,13 @@ static void handle_push(MSICall *call, const MSIMessage *msg) } case MSI_CALL_REQUESTING: { - LOGGER_INFO(call->session->messenger->log, "Friend answered our call"); + LOGGER_INFO(log, "Friend answered our call"); /* Call started */ call->peer_capabilities = msg->capabilities.value; call->state = MSI_CALL_ACTIVE; - if (!invoke_callback(call, MSI_ON_START)) { + if (!invoke_callback(log, call, MSI_ON_START)) { goto FAILURE; } @@ -786,8 +855,7 @@ static void handle_push(MSICall *call, const MSIMessage *msg) case MSI_CALL_INACTIVE: // fall-through case MSI_CALL_REQUESTED: { - /* Pushes during initialization state are ignored */ - LOGGER_WARNING(call->session->messenger->log, "Ignoring invalid push"); + LOGGER_WARNING(log, "Ignoring invalid push"); break; } } @@ -795,76 +863,102 @@ static void handle_push(MSICall *call, const MSIMessage *msg) return; FAILURE: - send_error(call->session->messenger, call->friend_number, call->error); - kill_call(call); + send_error(log, call->session->tox, call->friend_number, call->error); + kill_call(log, call); } -static void handle_pop(MSICall *call, const MSIMessage *msg) + +static void handle_pop(const Logger *log, MSICall *call, const MSIMessage *msg) { assert(call != nullptr); - LOGGER_DEBUG(call->session->messenger->log, "Session: %p Handling 'pop', friend id: %d", (void *)call->session, + LOGGER_DEBUG(log, "Session: %p Handling 'pop', friend id: %d", (void *)call->session, call->friend_number); /* callback errors are ignored */ if (msg->error.exists) { - LOGGER_WARNING(call->session->messenger->log, "Friend detected an error: %d", msg->error.value); + LOGGER_WARNING(log, "Friend detected an error: %d", msg->error.value); call->error = msg->error.value; - invoke_callback(call, MSI_ON_ERROR); + invoke_callback(log, call, MSI_ON_ERROR); } else { switch (call->state) { case MSI_CALL_INACTIVE: { - LOGGER_FATAL(call->session->messenger->log, "Handling what should be impossible case"); + LOGGER_FATAL(log, "Handling what should be impossible case"); break; } case MSI_CALL_ACTIVE: { /* Hangup */ - LOGGER_INFO(call->session->messenger->log, "Friend hung up on us"); - invoke_callback(call, MSI_ON_END); + LOGGER_INFO(log, "Friend hung up on us"); + invoke_callback(log, call, MSI_ON_END); break; } case MSI_CALL_REQUESTING: { /* Reject */ - LOGGER_INFO(call->session->messenger->log, "Friend rejected our call"); - invoke_callback(call, MSI_ON_END); + LOGGER_INFO(log, "Friend rejected our call"); + invoke_callback(log, call, MSI_ON_END); break; } case MSI_CALL_REQUESTED: { /* Cancel */ - LOGGER_INFO(call->session->messenger->log, "Friend canceled call invite"); - invoke_callback(call, MSI_ON_END); + LOGGER_INFO(log, "Friend canceled call invite"); + invoke_callback(log, call, MSI_ON_END); break; } } } - kill_call(call); + kill_call(log, call); } -static void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *user_data) + +static void handle_msi_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, + void *user_data) { - MSISession *session = (MSISession *)user_data; + const ToxAV *toxav = (ToxAV *)tox_get_av_object(tox); + + if (toxav == nullptr) { + return; + } + + const Logger *log = toxav_get_logger(toxav); + + if (length < 2) { + LOGGER_ERROR(log, "MSI packet is less than 2 bytes in size"); + // we need more than the ID byte for MSI messages + return; + } - LOGGER_DEBUG(m->log, "Got msi message"); + const uint16_t payload_length = (uint16_t)(length - 1); + + // Zoff: do not show the first byte, its always "PACKET_ID_MSI" + const uint8_t *data_strip_id_byte = data + 1; + + LOGGER_DEBUG(log, "Got msi message"); + + MSISession *session = tox_av_msi_get(toxav); + + if (session == nullptr) { + return; + } MSIMessage msg; - if (msg_parse_in(m->log, &msg, data, length) == -1) { - LOGGER_WARNING(m->log, "Error parsing message"); - send_error(m, friend_number, MSI_E_INVALID_MESSAGE); + if (msg_parse_in(log, &msg, data_strip_id_byte, payload_length) == -1) { + LOGGER_WARNING(log, "Error parsing message"); + send_error(log, tox, friend_number, MSI_E_INVALID_MESSAGE); return; } - LOGGER_DEBUG(m->log, "Successfully parsed message"); + LOGGER_DEBUG(log, "Successfully parsed message"); pthread_mutex_lock(session->mutex); MSICall *call = get_call(session, friend_number); if (call == nullptr) { if (msg.request.value != REQU_INIT) { - send_error(m, friend_number, MSI_E_STRAY_MESSAGE); + send_error(log, tox, friend_number, MSI_E_STRAY_MESSAGE); pthread_mutex_unlock(session->mutex); return; } @@ -872,7 +966,7 @@ static void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_ call = new_call(session, friend_number); if (call == nullptr) { - send_error(m, friend_number, MSI_E_SYSTEM); + send_error(log, tox, friend_number, MSI_E_SYSTEM); pthread_mutex_unlock(session->mutex); return; } @@ -880,17 +974,17 @@ static void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_ switch (msg.request.value) { case REQU_INIT: { - handle_init(call, &msg); + handle_init(log, call, &msg); break; } case REQU_PUSH: { - handle_push(call, &msg); + handle_push(log, call, &msg); break; } case REQU_POP: { - handle_pop(call, &msg); /* always kills the call */ + handle_pop(log, call, &msg); /* always kills the call */ break; } } diff --git a/toxav/msi.h b/toxav/msi.h index f034a35c9c..88d01572ff 100644 --- a/toxav/msi.h +++ b/toxav/msi.h @@ -11,7 +11,6 @@ #include "audio.h" #include "video.h" -#include "../toxcore/Messenger.h" #include "../toxcore/logger.h" /** @@ -42,22 +41,22 @@ typedef enum MSICapabilities { * Call state identifiers. */ typedef enum MSICallState { - MSI_CALL_INACTIVE, /* Default */ - MSI_CALL_ACTIVE, - MSI_CALL_REQUESTING, /* when sending call invite */ - MSI_CALL_REQUESTED, /* when getting call invite */ + MSI_CALL_INACTIVE = 0, /* Default */ + MSI_CALL_ACTIVE = 1, + MSI_CALL_REQUESTING = 2, /* when sending call invite */ + MSI_CALL_REQUESTED = 3, /* when getting call invite */ } MSICallState; /** * Callbacks ids that handle the states */ typedef enum MSICallbackID { - MSI_ON_INVITE, /* Incoming call */ - MSI_ON_START, /* Call (RTP transmission) started */ - MSI_ON_END, /* Call that was active ended */ - MSI_ON_ERROR, /* On protocol error */ - MSI_ON_PEERTIMEOUT, /* Peer timed out; stop the call */ - MSI_ON_CAPABILITIES, /* Peer requested capabilities change */ + MSI_ON_INVITE = 0, /* Incoming call */ + MSI_ON_START = 1, /* Call (RTP transmission) started */ + MSI_ON_END = 2, /* Call that was active ended */ + MSI_ON_ERROR = 3, /* On protocol error */ + MSI_ON_PEERTIMEOUT = 4, /* Peer timed out; stop the call */ + MSI_ON_CAPABILITIES = 5, /* Peer requested capabilities change */ } MSICallbackID; /** @@ -96,7 +95,7 @@ typedef struct MSISession { uint32_t calls_head; void *av; - Messenger *messenger; + Tox *tox; pthread_mutex_t mutex[1]; @@ -111,11 +110,11 @@ typedef struct MSISession { /** * Start the control session. */ -MSISession *msi_new(Messenger *m); +MSISession *msi_new(const Logger *log, Tox *tox); /** * Terminate control session. NOTE: all calls will be freed */ -int msi_kill(MSISession *session, const Logger *log); +int msi_kill(const Logger *log, Tox *tox, MSISession *session); /** * Callback setters. */ @@ -128,18 +127,20 @@ void msi_callback_capabilities(MSISession *session, msi_action_cb *callback); /** * Send invite request to friend_number. */ -int msi_invite(MSISession *session, MSICall **call, uint32_t friend_number, uint8_t capabilities); +int msi_invite(const Logger *log, MSISession *session, MSICall **call, uint32_t friend_number, uint8_t capabilities); /** * Hangup call. NOTE: `call` will be freed */ -int msi_hangup(MSICall *call); +int msi_hangup(const Logger *log, MSICall *call); /** * Answer call request. */ -int msi_answer(MSICall *call, uint8_t capabilities); +int msi_answer(const Logger *log, MSICall *call, uint8_t capabilities); /** * Change capabilities of the call. */ -int msi_change_capabilities(MSICall *call, uint8_t capabilities); +int msi_change_capabilities(const Logger *log, MSICall *call, uint8_t capabilities); + +bool check_peer_offline_status(const Logger *log, const Tox *tox, MSISession *session, uint32_t friend_number); #endif /* C_TOXCORE_TOXAV_MSI_H */ diff --git a/toxav/rtp.c b/toxav/rtp.c index 8ad4ce670e..32b2545d84 100644 --- a/toxav/rtp.c +++ b/toxav/rtp.c @@ -9,12 +9,16 @@ #include #include +#include + #include "bwcontroller.h" +#include "toxav_hacks.h" -#include "../toxcore/Messenger.h" #include "../toxcore/ccompat.h" #include "../toxcore/logger.h" #include "../toxcore/mono_time.h" +#include "../toxcore/net_crypto.h" +#include "../toxcore/tox_private.h" #include "../toxcore/util.h" /** @@ -23,30 +27,15 @@ */ #define VIDEO_KEEP_KEYFRAME_IN_BUFFER_FOR_MS 15 -/** - * return -1 on failure, 0 on success - * - */ -static int rtp_send_custom_lossy_packet(Tox *tox, int32_t friendnumber, const uint8_t *data, uint32_t length) -{ - Tox_Err_Friend_Custom_Packet error; - tox_friend_send_lossy_packet(tox, friendnumber, data, (size_t)length, &error); - - if (error == TOX_ERR_FRIEND_CUSTOM_PACKET_OK) { - return 0; - } - - return -1; -} - // allocate_len is NOT including header! -static struct RTPMessage *new_message(const struct RTPHeader *header, size_t allocate_len, const uint8_t *data, - uint16_t data_length) +static struct RTPMessage *new_message(const Logger *log, const struct RTPHeader *header, size_t allocate_len, + const uint8_t *data, uint16_t data_length) { assert(allocate_len >= data_length); struct RTPMessage *msg = (struct RTPMessage *)calloc(1, sizeof(struct RTPMessage) + allocate_len); if (msg == nullptr) { + LOGGER_DEBUG(log, "Could not allocate RTPMessage buffer"); return nullptr; } @@ -241,7 +230,7 @@ static struct RTPMessage *process_frame(const Logger *log, struct RTPWorkBufferL } /** - * @param log A logger. + * @param log A pointer to the Logger object. * @param wkbl The list of in-progress frames, i.e. all the slots. * @param slot_id The slot we want to fill the data into. * @param is_keyframe Whether the data is part of a key frame. @@ -309,7 +298,7 @@ static bool fill_data_into_slot(const Logger *log, struct RTPWorkBufferList *wkb return slot->received_len == header->data_length_full; } -static void update_bwc_values(const Logger *log, RTPSession *session, const struct RTPMessage *msg) +static void update_bwc_values(RTPSession *session, const struct RTPMessage *msg) { if (session->first_packets_counter < DISMISS_FIRST_LOST_VIDEO_PACKET_COUNT) { ++session->first_packets_counter; @@ -319,7 +308,7 @@ static void update_bwc_values(const Logger *log, RTPSession *session, const stru bwc_add_recv(session->bwc, data_length_full); if (received_length_full < data_length_full) { - LOGGER_DEBUG(log, "BWC: full length=%u received length=%d", data_length_full, received_length_full); + LOGGER_DEBUG(session->log, "BWC: full length=%u received length=%d", data_length_full, received_length_full); bwc_add_lost(session->bwc, data_length_full - received_length_full); } } @@ -347,22 +336,16 @@ static void update_bwc_values(const Logger *log, RTPSession *session, const stru * @retval -1 on error. * @retval 0 on success. */ -static int handle_video_packet(RTPSession *session, const struct RTPHeader *header, - const uint8_t *incoming_data, uint16_t incoming_data_length, const Logger *log) +static int handle_video_packet(const Logger *log, RTPSession *session, const struct RTPHeader *header, + const uint8_t *incoming_data, uint16_t incoming_data_length) { // Full frame length in bytes. The frame may be split into multiple packets, // but this value is the complete assembled frame size. const uint32_t full_frame_length = header->data_length_full; - // Current offset in the frame. If this is the first packet of a multipart - // frame or it's not a multipart frame, then this value is 0. - const uint32_t offset = header->offset_full; // without header - // The sender tells us whether this is a key frame. const bool is_keyframe = (header->flags & RTP_KEY_FRAME) != 0; - LOGGER_DEBUG(log, "-- handle_video_packet -- full lens=%u len=%u offset=%u is_keyframe=%s", - (unsigned)incoming_data_length, (unsigned)full_frame_length, (unsigned)offset, is_keyframe ? "K" : "."); LOGGER_DEBUG(log, "wkbl->next_free_entry:003=%d", session->work_buffer_list->next_free_entry); const bool is_multipart = full_frame_length != incoming_data_length; @@ -387,10 +370,13 @@ static int handle_video_packet(RTPSession *session, const struct RTPHeader *head // get_slot just told us it's full, so process_frame must return non-null. assert(m_new != nullptr); - LOGGER_DEBUG(log, "-- handle_video_packet -- CALLBACK-001a b0=%d b1=%d", (int)m_new->data[0], (int)m_new->data[1]); - update_bwc_values(log, session, m_new); + LOGGER_DEBUG(log, "-- handle_video_packet -- CALLBACK-001a b0=%d b1=%d", (int)m_new->data[0], + (int)m_new->data[1]); + update_bwc_values(session, m_new); // Pass ownership of m_new to the callback. - session->mcb(session->m->mono_time, session->cs, m_new); + Mono_Time *mt = toxav_get_av_mono_time(session->toxav); + assert(mt != nullptr); + session->mcb(mt, session->cs, m_new); // Now we no longer own m_new. m_new = nullptr; @@ -425,9 +411,12 @@ static int handle_video_packet(RTPSession *session, const struct RTPHeader *head struct RTPMessage *m_new = process_frame(log, session->work_buffer_list, slot_id); if (m_new != nullptr) { - LOGGER_DEBUG(log, "-- handle_video_packet -- CALLBACK-003a b0=%d b1=%d", (int)m_new->data[0], (int)m_new->data[1]); - update_bwc_values(log, session, m_new); - session->mcb(session->m->mono_time, session->cs, m_new); + LOGGER_DEBUG(log, "-- handle_video_packet -- CALLBACK-003a b0=%d b1=%d", (int)m_new->data[0], + (int)m_new->data[1]); + update_bwc_values(session, m_new); + Mono_Time *mt = toxav_get_av_mono_time(session->toxav); + assert(mt != nullptr); + session->mcb(mt, session->cs, m_new); m_new = nullptr; } @@ -436,80 +425,113 @@ static int handle_video_packet(RTPSession *session, const struct RTPHeader *head } /** - * @retval -1 on error. - * @retval 0 on success. + * receive custom lossypackets and process them. they can be incoming audio or video packets */ -static int handle_rtp_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object) +void handle_rtp_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data) { - RTPSession *session = (RTPSession *)object; + ToxAV *toxav = (ToxAV *)tox_get_av_object(tox); - if (session == nullptr || length < RTP_HEADER_SIZE + 1) { - LOGGER_WARNING(m->log, "No session or invalid length of received buffer!"); - return -1; + if (toxav == nullptr) { + // LOGGER_WARNING(log, "ToxAV is NULL!"); + return; + } + + const Logger *log = toxav_get_logger(toxav); + + if (length < RTP_HEADER_SIZE + 1) { + LOGGER_WARNING(log, "Invalid length of received buffer!"); + return; + } + + ToxAVCall *call = call_get(toxav, friend_number); + + if (call == nullptr) { + LOGGER_WARNING(log, "ToxAVCall is NULL!"); + return; + } + + RTPSession *session = rtp_session_get(call, data[0]); + + if (session == nullptr) { + LOGGER_WARNING(log, "No session!"); + return; + } + + if (!session->rtp_receive_active) { + LOGGER_WARNING(log, "receiving not allowed!"); + return; } // Get the packet type. const uint8_t packet_type = data[0]; - ++data; - --length; + const uint8_t *payload = &data[1]; + // TODO(Zoff): is this ok? + const uint16_t payload_size = (uint16_t)length - 1; // Unpack the header. struct RTPHeader header; - rtp_header_unpack(data, &header); + rtp_header_unpack(payload, &header); if (header.pt != packet_type % 128) { - LOGGER_WARNING(m->log, "RTPHeader packet type and Tox protocol packet type did not agree: %d != %d", + LOGGER_WARNING(log, "RTPHeader packet type and Tox protocol packet type did not agree: %d != %d", header.pt, packet_type % 128); - return -1; + return; } if (header.pt != session->payload_type % 128) { - LOGGER_WARNING(m->log, "RTPHeader packet type does not match this session's payload type: %d != %d", + LOGGER_WARNING(log, "RTPHeader packet type does not match this session's payload type: %d != %d", header.pt, session->payload_type % 128); - return -1; + return; } if ((header.flags & RTP_LARGE_FRAME) != 0 && header.offset_full >= header.data_length_full) { - LOGGER_ERROR(m->log, "Invalid video packet: frame offset (%u) >= full frame length (%u)", + LOGGER_ERROR(log, "Invalid video packet: frame offset (%u) >= full frame length (%u)", (unsigned)header.offset_full, (unsigned)header.data_length_full); - return -1; + return; } if (header.offset_lower >= header.data_length_lower) { - LOGGER_ERROR(m->log, "Invalid old protocol video packet: frame offset (%u) >= full frame length (%u)", + LOGGER_ERROR(log, "Invalid old protocol video packet: frame offset (%u) >= full frame length (%u)", (unsigned)header.offset_lower, (unsigned)header.data_length_lower); - return -1; + return; } - LOGGER_DEBUG(m->log, "header.pt %d, video %d", (uint8_t)header.pt, RTP_TYPE_VIDEO % 128); + LOGGER_DEBUG(log, "header.pt %d, video %d", (uint8_t)header.pt, RTP_TYPE_VIDEO % 128); // The sender uses the new large-frame capable protocol and is sending a // video packet. if ((header.flags & RTP_LARGE_FRAME) != 0 && header.pt == (RTP_TYPE_VIDEO % 128)) { - return handle_video_packet(session, &header, data + RTP_HEADER_SIZE, length - RTP_HEADER_SIZE, m->log); + handle_video_packet(log, session, &header, &payload[RTP_HEADER_SIZE], payload_size - RTP_HEADER_SIZE); + return; } // everything below here is for the old 16 bit protocol ------------------ - if (header.data_length_lower == length - RTP_HEADER_SIZE) { + if (header.data_length_lower == payload_size - RTP_HEADER_SIZE) { /* The message is sent in single part */ /* Message is not late; pick up the latest parameters */ session->rsequnum = header.sequnum; session->rtimestamp = header.timestamp; - bwc_add_recv(session->bwc, length); + bwc_add_recv(session->bwc, payload_size); /* Invoke processing of active multiparted message */ if (session->mp != nullptr) { - session->mcb(session->m->mono_time, session->cs, session->mp); + Mono_Time *mt = toxav_get_av_mono_time(session->toxav); + assert(mt != nullptr); + session->mcb(mt, session->cs, session->mp); session->mp = nullptr; } /* The message came in the allowed time; */ - return session->mcb(session->m->mono_time, session->cs, new_message(&header, length - RTP_HEADER_SIZE, - data + RTP_HEADER_SIZE, length - RTP_HEADER_SIZE)); + session->mp = new_message(log, &header, payload_size - RTP_HEADER_SIZE, &payload[RTP_HEADER_SIZE], payload_size - RTP_HEADER_SIZE); + Mono_Time *mt = toxav_get_av_mono_time(session->toxav); + assert(mt != nullptr); + session->mcb(mt, session->cs, session->mp); + session->mp = nullptr; + return; } /* The message is sent in multiple parts */ @@ -527,24 +549,26 @@ static int handle_rtp_packet(Messenger *m, uint32_t friend_number, const uint8_t /* First case */ /* Make sure we have enough allocated memory */ - if (session->mp->header.data_length_lower - session->mp->len < length - RTP_HEADER_SIZE || + if (session->mp->header.data_length_lower - session->mp->len < payload_size - RTP_HEADER_SIZE || session->mp->header.data_length_lower <= header.offset_lower) { /* There happened to be some corruption on the stream; * continue wihtout this part */ - return 0; + return; } - memcpy(session->mp->data + header.offset_lower, data + RTP_HEADER_SIZE, - length - RTP_HEADER_SIZE); - session->mp->len += length - RTP_HEADER_SIZE; - bwc_add_recv(session->bwc, length); + memcpy(session->mp->data + header.offset_lower, &payload[RTP_HEADER_SIZE], + payload_size - RTP_HEADER_SIZE); + session->mp->len += payload_size - RTP_HEADER_SIZE; + bwc_add_recv(session->bwc, payload_size); if (session->mp->len == session->mp->header.data_length_lower) { /* Received a full message; now push it for the further * processing. */ - session->mcb(session->m->mono_time, session->cs, session->mp); + Mono_Time *mt = toxav_get_av_mono_time(session->toxav); + assert(mt != nullptr); + session->mcb(mt, session->cs, session->mp); session->mp = nullptr; } } else { @@ -553,17 +577,19 @@ static int handle_rtp_packet(Messenger *m, uint32_t friend_number, const uint8_t /* The received message part is from the old message; * discard it. */ - return 0; + return; } /* Push the previous message for processing */ - session->mcb(session->m->mono_time, session->cs, session->mp); + Mono_Time *mt = toxav_get_av_mono_time(session->toxav); + assert(mt != nullptr); + session->mcb(mt, session->cs, session->mp); session->mp = nullptr; goto NEW_MULTIPARTED; } } else { - /* In this case threat the message as if it was received in order + /* In this case treat the message as if it was received in order */ /* This is also a point for new multiparted messages */ NEW_MULTIPARTED: @@ -571,21 +597,21 @@ static int handle_rtp_packet(Messenger *m, uint32_t friend_number, const uint8_t /* Message is not late; pick up the latest parameters */ session->rsequnum = header.sequnum; session->rtimestamp = header.timestamp; - bwc_add_recv(session->bwc, length); + bwc_add_recv(session->bwc, payload_size); /* Store message. */ - session->mp = new_message(&header, header.data_length_lower, data + RTP_HEADER_SIZE, length - RTP_HEADER_SIZE); + session->mp = new_message(log, &header, header.data_length_lower, &payload[RTP_HEADER_SIZE], payload_size - RTP_HEADER_SIZE); if (session->mp != nullptr) { memmove(session->mp->data + header.offset_lower, session->mp->data, session->mp->len); } else { - LOGGER_WARNING(m->log, "new_message() returned a null pointer"); - return -1; + LOGGER_WARNING(log, "new_message() returned a null pointer"); + return; } } - return 0; + return; } size_t rtp_header_pack(uint8_t *const rdata, const struct RTPHeader *header) @@ -647,24 +673,29 @@ size_t rtp_header_unpack(const uint8_t *data, struct RTPHeader *header) return p - data; } -RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnumber, +static uint32_t rtp_random_u32(void) +{ + // HINT: uses libsodium function + return randombytes_random(); +} + +RTPSession *rtp_new(const Logger *log, int payload_type, Tox *tox, ToxAV *toxav, uint32_t friendnumber, BWController *bwc, void *cs, rtp_m_cb *mcb) { assert(mcb != nullptr); assert(cs != nullptr); - assert(m != nullptr); RTPSession *session = (RTPSession *)calloc(1, sizeof(RTPSession)); if (session == nullptr) { - LOGGER_WARNING(m->log, "Alloc failed! Program might misbehave!"); + LOGGER_WARNING(log, "Alloc failed! Program might misbehave!"); return nullptr; } session->work_buffer_list = (struct RTPWorkBufferList *)calloc(1, sizeof(struct RTPWorkBufferList)); if (session->work_buffer_list == nullptr) { - LOGGER_ERROR(m->log, "out of memory while allocating work buffer list"); + LOGGER_ERROR(log, "out of memory while allocating work buffer list"); free(session); return nullptr; } @@ -672,11 +703,12 @@ RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnum // First entry is free. session->work_buffer_list->next_free_entry = 0; - session->ssrc = payload_type == RTP_TYPE_VIDEO ? 0 : random_u32(m->rng); + session->ssrc = payload_type == RTP_TYPE_VIDEO ? 0 : rtp_random_u32(); // Zoff: what is this?? session->payload_type = payload_type; - session->m = m; session->tox = tox; + session->toxav = toxav; session->friend_number = friendnumber; + session->rtp_receive_active = true; // set NULL just in case session->mp = nullptr; @@ -687,26 +719,18 @@ RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnum session->cs = cs; session->mcb = mcb; - if (-1 == rtp_allow_receiving(session)) { - LOGGER_WARNING(m->log, "Failed to start rtp receiving mode"); - free(session->work_buffer_list); - free(session); - return nullptr; - } - return session; } -void rtp_kill(RTPSession *session) +void rtp_kill(const Logger *log, RTPSession *session) { if (session == nullptr) { + LOGGER_WARNING(log, "No session"); return; } - LOGGER_DEBUG(session->m->log, "Terminated RTP session: %p", (void *)session); - rtp_stop_receiving(session); - - LOGGER_DEBUG(session->m->log, "Terminated RTP session V3 work_buffer_list->next_free_entry: %d", + LOGGER_DEBUG(log, "Terminated RTP session: %p", (void *)session); + LOGGER_DEBUG(log, "Terminated RTP session V3 work_buffer_list->next_free_entry: %d", (int)session->work_buffer_list->next_free_entry); for (int8_t i = 0; i < session->work_buffer_list->next_free_entry; ++i) { @@ -716,114 +740,123 @@ void rtp_kill(RTPSession *session) free(session); } -int rtp_allow_receiving(RTPSession *session) +void rtp_allow_receiving_mark(RTPSession *session) { - if (session == nullptr) { - return -1; + if (session != nullptr) { + session->rtp_receive_active = true; } +} - if (m_callback_rtp_packet(session->m, session->friend_number, session->payload_type, - handle_rtp_packet, session) == -1) { - LOGGER_WARNING(session->m->log, "Failed to register rtp receive handler"); - return -1; +void rtp_stop_receiving_mark(RTPSession *session) +{ + if (session != nullptr) { + session->rtp_receive_active = false; } +} - LOGGER_DEBUG(session->m->log, "Started receiving on session: %p", (void *)session); - return 0; +void rtp_allow_receiving(Tox *tox) +{ + // register callback + tox_callback_friend_lossy_packet_per_pktid(tox, handle_rtp_packet, RTP_TYPE_AUDIO); + tox_callback_friend_lossy_packet_per_pktid(tox, handle_rtp_packet, RTP_TYPE_VIDEO); } -int rtp_stop_receiving(RTPSession *session) +void rtp_stop_receiving(Tox *tox) { - if (session == nullptr) { - return -1; - } + // UN-register callback + tox_callback_friend_lossy_packet_per_pktid(tox, nullptr, RTP_TYPE_AUDIO); + tox_callback_friend_lossy_packet_per_pktid(tox, nullptr, RTP_TYPE_VIDEO); +} + +static void rtp_send_piece(const Logger *log, Tox *tox, uint32_t friend_number, const struct RTPHeader *header, + const uint8_t *data, uint8_t *rdata, uint16_t length) +{ + rtp_header_pack(rdata + 1, header); + memcpy(rdata + 1 + RTP_HEADER_SIZE, data, length); - m_callback_rtp_packet(session->m, session->friend_number, session->payload_type, nullptr, nullptr); + Tox_Err_Friend_Custom_Packet error; + tox_friend_send_lossy_packet(tox, friend_number, + rdata, length + RTP_HEADER_SIZE + 1, &error); - LOGGER_DEBUG(session->m->log, "Stopped receiving on session: %p", (void *)session); - return 0; + if (error != TOX_ERR_FRIEND_CUSTOM_PACKET_OK) { + char *netstrerror = net_new_strerror(net_error()); + LOGGER_WARNING(log, "RTP send failed (len: %d)! tox error: %d, net error: %s", + length + RTP_HEADER_SIZE + 1, error, netstrerror); + net_kill_strerror(netstrerror); + } } -/** - * Send a frame of audio or video data, chunked in @ref RTPMessage instances. - * - * @param session The A/V session to send the data for. - * @param data A byte array of length @p length. - * @param length The number of bytes to send from @p data. - * @param is_keyframe Whether this video frame is a key frame. If it is an - * audio frame, this parameter is ignored. - */ -int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length, - bool is_keyframe, const Logger *log) +static struct RTPHeader rtp_default_header(const RTPSession *session, uint32_t length, bool is_keyframe) { - if (session == nullptr) { - LOGGER_ERROR(log, "No session!"); - return -1; + uint16_t length_safe = (uint16_t)length; + + if (length > UINT16_MAX) { + length_safe = UINT16_MAX; } struct RTPHeader header = {0}; - header.ve = 2; // this is unused in toxav + if (is_keyframe) { + header.flags |= RTP_KEY_FRAME; + } - header.pe = 0; + if (session->payload_type == RTP_TYPE_VIDEO) { + header.flags |= RTP_LARGE_FRAME; + } + header.ve = 2; // this is unused in toxav + header.pe = 0; header.xe = 0; - header.cc = 0; - header.ma = 0; - header.pt = session->payload_type % 128; - header.sequnum = session->sequnum; - - header.timestamp = current_time_monotonic(session->m->mono_time); - + Mono_Time *mt = toxav_get_av_mono_time(session->toxav); + if (mt != nullptr) { + header.timestamp = current_time_monotonic(mt); + } else { + header.timestamp = 0; + } header.ssrc = session->ssrc; - header.offset_lower = 0; - - // here the highest bits gets stripped anyway, no need to do keyframe bit magic here! - header.data_length_lower = length; - - if (session->payload_type == RTP_TYPE_VIDEO) { - header.flags = RTP_LARGE_FRAME; - } - - uint16_t length_safe = (uint16_t)length; - - if (length > UINT16_MAX) { - length_safe = UINT16_MAX; - } - header.data_length_lower = length_safe; header.data_length_full = length; // without header header.offset_lower = 0; header.offset_full = 0; - if (is_keyframe) { - header.flags |= RTP_KEY_FRAME; + return header; +} + +/** + * @brief Send a frame of audio or video data, chunked in @ref RTPMessage instances. + * + * @param session The A/V session to send the data for. + * @param data A byte array of length @p length. + * @param length The number of bytes to send from @p data. + * @param is_keyframe Whether this video frame is a key frame. If it is an + * audio frame, this parameter is ignored. + */ +int rtp_send_data(const Logger *log, RTPSession *session, const uint8_t *data, uint32_t length, + bool is_keyframe) +{ + if (session == nullptr) { + return -1; } - const uint16_t rdata_size = length + RTP_HEADER_SIZE + 1; + const uint16_t rdata_size = min_u32(length + RTP_HEADER_SIZE + 1, MAX_CRYPTO_DATA_SIZE); VLA(uint8_t, rdata, rdata_size); memset(rdata, 0, rdata_size); rdata[0] = session->payload_type; // packet id == payload_type + struct RTPHeader header = rtp_default_header(session, length, is_keyframe); + if (MAX_CRYPTO_DATA_SIZE > (length + RTP_HEADER_SIZE + 1)) { /* * The length is lesser than the maximum allowed length (including header) * Send the packet in single piece. */ - rtp_header_pack(rdata + 1, &header); - memcpy(rdata + 1 + RTP_HEADER_SIZE, data, length); - - if (-1 == rtp_send_custom_lossy_packet(session->tox, session->friend_number, rdata, rdata_size)) { - char *netstrerror = net_new_strerror(net_error()); - LOGGER_WARNING(session->m->log, "RTP send failed (len: %u)! net error: %s", - rdata_size, netstrerror); - net_kill_strerror(netstrerror); - } + assert(length < UINT16_MAX); + rtp_send_piece(log, session->tox, session->friend_number, &header, data, rdata, length); } else { /* * The length is greater than the maximum allowed length (including header) @@ -833,16 +866,7 @@ int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length, uint16_t piece = MAX_CRYPTO_DATA_SIZE - (RTP_HEADER_SIZE + 1); while ((length - sent) + RTP_HEADER_SIZE + 1 > MAX_CRYPTO_DATA_SIZE) { - rtp_header_pack(rdata + 1, &header); - memcpy(rdata + 1 + RTP_HEADER_SIZE, data + sent, piece); - - if (-1 == rtp_send_custom_lossy_packet(session->tox, session->friend_number, - rdata, piece + RTP_HEADER_SIZE + 1)) { - char *netstrerror = net_new_strerror(net_error()); - LOGGER_WARNING(session->m->log, "RTP send failed (len: %d)! net error: %s", - piece + RTP_HEADER_SIZE + 1, netstrerror); - net_kill_strerror(netstrerror); - } + rtp_send_piece(log, session->tox, session->friend_number, &header, data + sent, rdata, piece); sent += piece; header.offset_lower = sent; @@ -853,16 +877,7 @@ int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length, piece = length - sent; if (piece != 0) { - rtp_header_pack(rdata + 1, &header); - memcpy(rdata + 1 + RTP_HEADER_SIZE, data + sent, piece); - - if (-1 == rtp_send_custom_lossy_packet(session->tox, session->friend_number, rdata, - piece + RTP_HEADER_SIZE + 1)) { - char *netstrerror = net_new_strerror(net_error()); - LOGGER_WARNING(session->m->log, "RTP send failed (len: %d)! net error: %s", - piece + RTP_HEADER_SIZE + 1, netstrerror); - net_kill_strerror(netstrerror); - } + rtp_send_piece(log, session->tox, session->friend_number, &header, data + sent, rdata, piece); } } diff --git a/toxav/rtp.h b/toxav/rtp.h index 8acd48d061..1e2e2e8f0d 100644 --- a/toxav/rtp.h +++ b/toxav/rtp.h @@ -9,7 +9,6 @@ #include "bwcontroller.h" -#include "../toxcore/Messenger.h" #include "../toxcore/logger.h" #include "../toxcore/tox.h" @@ -36,6 +35,11 @@ typedef enum RTP_Type { RTP_TYPE_VIDEO = 193, } RTP_Type; +#ifndef TOXAV_DEFINED +#define TOXAV_DEFINED +typedef struct ToxAV ToxAV; +#endif /* TOXAV_DEFINED */ + /** * A bit mask (up to 64 bits) specifying features of the current frame affecting * the behaviour of the decoder. @@ -157,14 +161,19 @@ typedef struct RTPSession { struct RTPMessage *mp; /* Expected parted message */ struct RTPWorkBufferList *work_buffer_list; uint8_t first_packets_counter; /* dismiss first few lost video packets */ - Messenger *m; + const Logger *log; Tox *tox; + ToxAV *toxav; uint32_t friend_number; + bool rtp_receive_active; /* if this is set to false then incoming rtp packets will not be processed by handle_rtp_packet() */ BWController *bwc; void *cs; rtp_m_cb *mcb; } RTPSession; + +void handle_rtp_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data); + /** * Serialise an RTPHeader to bytes to be sent over the network. * @@ -183,13 +192,16 @@ size_t rtp_header_pack(uint8_t *rdata, const struct RTPHeader *header); */ size_t rtp_header_unpack(const uint8_t *data, struct RTPHeader *header); -RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnumber, +RTPSession *rtp_new(const Logger *log, int payload_type, Tox *tox, ToxAV *toxav, uint32_t friendnumber, BWController *bwc, void *cs, rtp_m_cb *mcb); -void rtp_kill(RTPSession *session); -int rtp_allow_receiving(RTPSession *session); -int rtp_stop_receiving(RTPSession *session); +void rtp_kill(const Logger *log, RTPSession *session); +void rtp_allow_receiving_mark(RTPSession *session); +void rtp_stop_receiving_mark(RTPSession *session); +void rtp_allow_receiving(Tox *tox); +void rtp_stop_receiving(Tox *tox); + /** - * Send a frame of audio or video data, chunked in @ref RTPMessage instances. + * @brief Send a frame of audio or video data, chunked in @ref RTPMessage instances. * * @param session The A/V session to send the data for. * @param data A byte array of length @p length. @@ -197,8 +209,8 @@ int rtp_stop_receiving(RTPSession *session); * @param is_keyframe Whether this video frame is a key frame. If it is an * audio frame, this parameter is ignored. */ -int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length, - bool is_keyframe, const Logger *log); +int rtp_send_data(const Logger *log, RTPSession *session, const uint8_t *data, uint32_t length, + bool is_keyframe); #ifdef __cplusplus } /* extern "C" */ diff --git a/toxav/toxav.c b/toxav/toxav.c index 6bae7a91d1..dcb4597d66 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c @@ -12,11 +12,15 @@ #include "msi.h" #include "rtp.h" +#include "toxav_hacks.h" -#include "../toxcore/Messenger.h" #include "../toxcore/ccompat.h" #include "../toxcore/logger.h" #include "../toxcore/mono_time.h" +#include "../toxcore/net_crypto.h" +#include "../toxcore/network.h" +#include "../toxcore/tox.h" +#include "../toxcore/tox_private.h" #include "../toxcore/tox_struct.h" #include "../toxcore/util.h" @@ -36,7 +40,12 @@ // iteration interval that is used when no call is active #define IDLE_ITERATION_INTERVAL_MS 200 -typedef struct ToxAVCall { +#ifndef TOXAV_CALL_DEFINED +#define TOXAV_CALL_DEFINED +typedef struct ToxAVCall ToxAVCall; +#endif /* TOXAV_CALL_DEFINED */ + +struct ToxAVCall { ToxAV *av; pthread_mutex_t mutex_audio[1]; @@ -63,7 +72,7 @@ typedef struct ToxAVCall { struct ToxAVCall *prev; struct ToxAVCall *next; -} ToxAVCall; +}; /** Decode time statistics */ typedef struct DecodeTimeStats { @@ -79,8 +88,8 @@ typedef struct DecodeTimeStats { } DecodeTimeStats; struct ToxAV { + Logger *log; Tox *tox; - Messenger *m; MSISession *msi; /* Two-way storage: first is array of calls and second is list of calls with head and tail */ @@ -111,8 +120,8 @@ struct ToxAV { /* keep track of decode times for audio and video */ DecodeTimeStats audio_stats; DecodeTimeStats video_stats; - /** ToxAV's own mono_time instance */ - Mono_Time *toxav_mono_time; + + Mono_Time *toxav_mono_time; // ToxAV's own mono_time instance }; static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *user_data); @@ -127,11 +136,55 @@ static bool audio_bit_rate_invalid(uint32_t bit_rate); static bool video_bit_rate_invalid(uint32_t bit_rate); static bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state); static ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, Toxav_Err_Call *error); -static ToxAVCall *call_get(ToxAV *av, uint32_t friend_number); static ToxAVCall *call_remove(ToxAVCall *call); static bool call_prepare_transmission(ToxAVCall *call); static void call_kill_transmission(ToxAVCall *call); +MSISession *tox_av_msi_get(const ToxAV *av) +{ + if (av == nullptr) { + return nullptr; + } + + return av->msi; +} + +ToxAVCall *call_get(ToxAV *av, uint32_t friend_number) +{ + if (av == nullptr) { + return nullptr; + } + + /* Assumes mutex locked */ + if (av->calls == nullptr || av->calls_tail < friend_number) { + return nullptr; + } + + return av->calls[friend_number]; +} + +RTPSession *rtp_session_get(ToxAVCall *call, int payload_type) +{ + if (call == nullptr) { + return nullptr; + } + + if (payload_type == RTP_TYPE_VIDEO) { + return call->video_rtp; + } else { + return call->audio_rtp; + } +} + +BWController *bwc_controller_get(const ToxAVCall *call) +{ + if (call == nullptr) { + return nullptr; + } + + return call->bwc; +} + /** * @brief initialize d with default values * @param d struct to be initialized, must not be nullptr @@ -155,33 +208,26 @@ ToxAV *toxav_new(Tox *tox, Toxav_Err_New *error) goto RETURN; } - // TODO(iphydf): Don't rely on toxcore internals. - Messenger *m; - m = tox->m; - - if (m->msi_packet != nullptr) { - rc = TOXAV_ERR_NEW_MULTIPLE; - goto RETURN; - } - av = (ToxAV *)calloc(1, sizeof(ToxAV)); if (av == nullptr) { - LOGGER_WARNING(m->log, "Allocation failed!"); rc = TOXAV_ERR_NEW_MALLOC; goto RETURN; } if (create_recursive_mutex(av->mutex) != 0) { - LOGGER_WARNING(m->log, "Mutex creation failed!"); rc = TOXAV_ERR_NEW_MALLOC; goto RETURN; } + av->log = tox->m->log; av->tox = tox; - av->m = m; + av->msi = msi_new(av->log, av->tox); + + rtp_allow_receiving(av->tox); + bwc_allow_receiving(av->tox); + av->toxav_mono_time = mono_time_new(tox->sys.mem, nullptr, nullptr); - av->msi = msi_new(av->m); if (av->msi == nullptr) { pthread_mutex_destroy(av->mutex); @@ -193,6 +239,9 @@ ToxAV *toxav_new(Tox *tox, Toxav_Err_New *error) init_decode_time_stats(&av->video_stats); av->msi->av = av; + // save ToxAV object into toxcore + tox_set_av_object(av->tox, av); + msi_callback_invite(av->msi, callback_invite); msi_callback_start(av->msi, callback_start); msi_callback_end(av->msi, callback_end); @@ -207,12 +256,15 @@ ToxAV *toxav_new(Tox *tox, Toxav_Err_New *error) } if (rc != TOXAV_ERR_NEW_OK) { - free(av); - av = nullptr; + if (av != nullptr) { + free(av); + av = nullptr; + } } return av; } + void toxav_kill(ToxAV *av) { if (av == nullptr) { @@ -221,8 +273,16 @@ void toxav_kill(ToxAV *av) pthread_mutex_lock(av->mutex); + // unregister callbacks + for (uint8_t i = PACKET_ID_RANGE_LOSSY_AV_START; i <= PACKET_ID_RANGE_LOSSY_AV_END; ++i) { + tox_callback_friend_lossy_packet_per_pktid(av->tox, nullptr, i); + } + + rtp_stop_receiving(av->tox); + bwc_stop_receiving(av->tox); + /* To avoid possible deadlocks */ - while (av->msi != nullptr && msi_kill(av->msi, av->m->log) != 0) { + while (av->msi != nullptr && msi_kill(av->log, av->tox, av->msi) != 0) { pthread_mutex_unlock(av->mutex); pthread_mutex_lock(av->mutex); } @@ -243,13 +303,22 @@ void toxav_kill(ToxAV *av) pthread_mutex_unlock(av->mutex); pthread_mutex_destroy(av->mutex); + // set ToxAV object to NULL in toxcore, to signal ToxAV has been shutdown + tox_set_av_object(av->tox, nullptr); + free(av); } + Tox *toxav_get_tox(const ToxAV *av) { return av->tox; } +const Logger *toxav_get_logger(const ToxAV *av) +{ + return av->log; +} + uint32_t toxav_audio_iteration_interval(const ToxAV *av) { return av->calls != nullptr ? av->audio_stats.interval : IDLE_ITERATION_INTERVAL_MS; @@ -276,10 +345,11 @@ uint32_t toxav_iteration_interval(const ToxAV *av) static void calc_interval(ToxAV *av, DecodeTimeStats *stats, int32_t frame_time, uint64_t start_time) { stats->interval = frame_time < stats->average ? 0 : (frame_time - stats->average); - stats->total += current_time_monotonic(av->m->mono_time) - start_time; + stats->total += current_time_monotonic(av->toxav_mono_time) - start_time; if (++stats->count == 3) { - stats->average = stats->total / 3 + 5; /* NOTE: Magic Offset for precision */ + /* NOTE: Magic Offset for precision */ + stats->average = stats->total / 3 + 5; stats->count = 0; stats->total = 0; } @@ -300,7 +370,6 @@ static void iterate_common(ToxAV *av, bool audio) } const uint64_t start = current_time_monotonic(av->toxav_mono_time); - // time until the first audio or video frame is over int32_t frame_time = IDLE_ITERATION_INTERVAL_MS; for (ToxAVCall *i = av->calls[av->calls_head]; i != nullptr; i = i->next) { @@ -311,6 +380,15 @@ static void iterate_common(ToxAV *av, bool audio) pthread_mutex_lock(i->toxav_call_mutex); pthread_mutex_unlock(av->mutex); + const uint32_t fid = i->friend_number; + const bool is_offline = check_peer_offline_status(av->log, av->tox, i->msi_call->session, fid); + + if (is_offline) { + pthread_mutex_unlock(i->toxav_call_mutex); + pthread_mutex_lock(av->mutex); + break; + } + if (audio) { ac_iterate(i->audio); @@ -329,8 +407,6 @@ static void iterate_common(ToxAV *av, bool audio) } } - const uint32_t fid = i->friend_number; - pthread_mutex_unlock(i->toxav_call_mutex); pthread_mutex_lock(av->mutex); @@ -342,8 +418,10 @@ static void iterate_common(ToxAV *av, bool audio) DecodeTimeStats *stats = audio ? &av->audio_stats : &av->video_stats; calc_interval(av, stats, frame_time, start); + pthread_mutex_unlock(av->mutex); } + void toxav_audio_iterate(ToxAV *av) { iterate_common(av, true); @@ -388,7 +466,7 @@ bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint call->previous_self_capabilities |= audio_bit_rate > 0 ? MSI_CAP_S_AUDIO : 0; call->previous_self_capabilities |= video_bit_rate > 0 ? MSI_CAP_S_VIDEO : 0; - if (msi_invite(av->msi, &call->msi_call, friend_number, call->previous_self_capabilities) != 0) { + if (msi_invite(av->log, av->msi, &call->msi_call, friend_number, call->previous_self_capabilities) != 0) { call_remove(call); rc = TOXAV_ERR_CALL_SYNC; goto RETURN; @@ -405,6 +483,7 @@ bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint return rc == TOXAV_ERR_CALL_OK; } + void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data) { pthread_mutex_lock(av->mutex); @@ -412,6 +491,7 @@ void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data) av->ccb_user_data = user_data; pthread_mutex_unlock(av->mutex); } + bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, Toxav_Err_Answer *error) { @@ -420,7 +500,7 @@ bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, ui Toxav_Err_Answer rc = TOXAV_ERR_ANSWER_OK; ToxAVCall *call; - if (!m_friend_exists(av->m, friend_number)) { + if (!tox_friend_exists(av->tox, friend_number)) { rc = TOXAV_ERR_ANSWER_FRIEND_NOT_FOUND; goto RETURN; } @@ -452,7 +532,7 @@ bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, ui call->previous_self_capabilities |= audio_bit_rate > 0 ? MSI_CAP_S_AUDIO : 0; call->previous_self_capabilities |= video_bit_rate > 0 ? MSI_CAP_S_VIDEO : 0; - if (msi_answer(call->msi_call, call->previous_self_capabilities) != 0) { + if (msi_answer(av->log, call->msi_call, call->previous_self_capabilities) != 0) { rc = TOXAV_ERR_ANSWER_SYNC; } @@ -465,6 +545,7 @@ bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, ui return rc == TOXAV_ERR_ANSWER_OK; } + void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *user_data) { pthread_mutex_lock(av->mutex); @@ -472,6 +553,7 @@ void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *u av->scb_user_data = user_data; pthread_mutex_unlock(av->mutex); } + static Toxav_Err_Call_Control call_control_handle_resume(const ToxAVCall *call) { /* Only act if paused and had media transfer active before */ @@ -479,12 +561,13 @@ static Toxav_Err_Call_Control call_control_handle_resume(const ToxAVCall *call) return TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; } - if (msi_change_capabilities(call->msi_call, call->previous_self_capabilities) == -1) { + if (msi_change_capabilities(call->av->log, call->msi_call, + call->previous_self_capabilities) == -1) { return TOXAV_ERR_CALL_CONTROL_SYNC; } - rtp_allow_receiving(call->audio_rtp); - rtp_allow_receiving(call->video_rtp); + rtp_allow_receiving_mark(call->audio_rtp); + rtp_allow_receiving_mark(call->video_rtp); return TOXAV_ERR_CALL_CONTROL_OK; } @@ -497,12 +580,12 @@ static Toxav_Err_Call_Control call_control_handle_pause(ToxAVCall *call) call->previous_self_capabilities = call->msi_call->self_capabilities; - if (msi_change_capabilities(call->msi_call, 0) == -1) { + if (msi_change_capabilities(call->av->log, call->msi_call, 0) == -1) { return TOXAV_ERR_CALL_CONTROL_SYNC; } - rtp_stop_receiving(call->audio_rtp); - rtp_stop_receiving(call->video_rtp); + rtp_stop_receiving_mark(call->audio_rtp); + rtp_stop_receiving_mark(call->video_rtp); return TOXAV_ERR_CALL_CONTROL_OK; } @@ -511,7 +594,7 @@ static Toxav_Err_Call_Control call_control_handle_cancel(ToxAVCall *call) /* Hang up */ pthread_mutex_lock(call->toxav_call_mutex); - if (msi_hangup(call->msi_call) != 0) { + if (msi_hangup(call->av->log, call->msi_call) != 0) { pthread_mutex_unlock(call->toxav_call_mutex); return TOXAV_ERR_CALL_CONTROL_SYNC; } @@ -531,13 +614,13 @@ static Toxav_Err_Call_Control call_control_handle_mute_audio(const ToxAVCall *ca return TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; } - if (msi_change_capabilities(call->msi_call, call-> + if (msi_change_capabilities(call->av->log, call->msi_call, call-> msi_call->self_capabilities ^ MSI_CAP_R_AUDIO) == -1) { return TOXAV_ERR_CALL_CONTROL_SYNC; } - rtp_stop_receiving(call->audio_rtp); + rtp_stop_receiving_mark(call->audio_rtp); return TOXAV_ERR_CALL_CONTROL_OK; } static Toxav_Err_Call_Control call_control_handle_unmute_audio(const ToxAVCall *call) @@ -546,12 +629,12 @@ static Toxav_Err_Call_Control call_control_handle_unmute_audio(const ToxAVCall * return TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; } - if (msi_change_capabilities(call->msi_call, call-> + if (msi_change_capabilities(call->av->log, call->msi_call, call-> msi_call->self_capabilities | MSI_CAP_R_AUDIO) == -1) { return TOXAV_ERR_CALL_CONTROL_SYNC; } - rtp_allow_receiving(call->audio_rtp); + rtp_allow_receiving_mark(call->audio_rtp); return TOXAV_ERR_CALL_CONTROL_OK; } static Toxav_Err_Call_Control call_control_handle_hide_video(const ToxAVCall *call) @@ -560,12 +643,12 @@ static Toxav_Err_Call_Control call_control_handle_hide_video(const ToxAVCall *ca return TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; } - if (msi_change_capabilities(call->msi_call, call-> + if (msi_change_capabilities(call->av->log, call->msi_call, call-> msi_call->self_capabilities ^ MSI_CAP_R_VIDEO) == -1) { return TOXAV_ERR_CALL_CONTROL_SYNC; } - rtp_stop_receiving(call->video_rtp); + rtp_stop_receiving_mark(call->video_rtp); return TOXAV_ERR_CALL_CONTROL_OK; } static Toxav_Err_Call_Control call_control_handle_show_video(const ToxAVCall *call) @@ -574,12 +657,12 @@ static Toxav_Err_Call_Control call_control_handle_show_video(const ToxAVCall *ca return TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; } - if (msi_change_capabilities(call->msi_call, call-> + if (msi_change_capabilities(call->av->log, call->msi_call, call-> msi_call->self_capabilities | MSI_CAP_R_VIDEO) == -1) { return TOXAV_ERR_CALL_CONTROL_SYNC; } - rtp_allow_receiving(call->video_rtp); + rtp_allow_receiving_mark(call->video_rtp); return TOXAV_ERR_CALL_CONTROL_OK; } static Toxav_Err_Call_Control call_control_handle(ToxAVCall *call, Toxav_Call_Control control) @@ -611,7 +694,7 @@ static Toxav_Err_Call_Control call_control_handle(ToxAVCall *call, Toxav_Call_Co } static Toxav_Err_Call_Control call_control(ToxAV *av, uint32_t friend_number, Toxav_Call_Control control) { - if (!m_friend_exists(av->m, friend_number)) { + if (!tox_friend_exists(av->tox, friend_number)) { return TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_FOUND; } @@ -637,13 +720,14 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, Toxav_Call_Control co return rc == TOXAV_ERR_CALL_CONTROL_OK; } + bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_rate, Toxav_Err_Bit_Rate_Set *error) { Toxav_Err_Bit_Rate_Set rc = TOXAV_ERR_BIT_RATE_SET_OK; ToxAVCall *call; - if (!m_friend_exists(av->m, friend_number)) { + if (!tox_friend_exists(av->tox, friend_number)) { rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND; goto RETURN; } @@ -662,14 +746,14 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra goto RETURN; } - LOGGER_DEBUG(av->m->log, "Setting new audio bitrate to: %d", bit_rate); + LOGGER_DEBUG(av->log, "Setting new audio bitrate to: %d", bit_rate); if (call->audio_bit_rate == bit_rate) { - LOGGER_DEBUG(av->m->log, "Audio bitrate already set to: %d", bit_rate); + LOGGER_DEBUG(av->log, "Audio bitrate already set to: %d", bit_rate); } else if (bit_rate == 0) { - LOGGER_DEBUG(av->m->log, "Turned off audio sending"); + LOGGER_DEBUG(av->log, "Turned off audio sending"); - if (msi_change_capabilities(call->msi_call, call->msi_call-> + if (msi_change_capabilities(av->log, call->msi_call, call->msi_call-> self_capabilities ^ MSI_CAP_S_AUDIO) != 0) { pthread_mutex_unlock(av->mutex); rc = TOXAV_ERR_BIT_RATE_SET_SYNC; @@ -682,10 +766,10 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra pthread_mutex_lock(call->toxav_call_mutex); if (call->audio_bit_rate == 0) { - LOGGER_DEBUG(av->m->log, "Turned on audio sending"); + LOGGER_DEBUG(av->log, "Turned on audio sending"); /* The audio has been turned off before this */ - if (msi_change_capabilities(call->msi_call, call-> + if (msi_change_capabilities(av->log, call->msi_call, call-> msi_call->self_capabilities | MSI_CAP_S_AUDIO) != 0) { pthread_mutex_unlock(call->toxav_call_mutex); pthread_mutex_unlock(av->mutex); @@ -693,7 +777,7 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra goto RETURN; } } else { - LOGGER_DEBUG(av->m->log, "Set new audio bit rate %d", bit_rate); + LOGGER_DEBUG(av->log, "Set new audio bit rate %d", bit_rate); } call->audio_bit_rate = bit_rate; @@ -709,13 +793,14 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra return rc == TOXAV_ERR_BIT_RATE_SET_OK; } + bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_rate, Toxav_Err_Bit_Rate_Set *error) { Toxav_Err_Bit_Rate_Set rc = TOXAV_ERR_BIT_RATE_SET_OK; ToxAVCall *call; - if (!m_friend_exists(av->m, friend_number)) { + if (!tox_friend_exists(av->tox, friend_number)) { rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND; goto RETURN; } @@ -734,15 +819,15 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra goto RETURN; } - LOGGER_DEBUG(av->m->log, "Setting new video bitrate to: %d", bit_rate); + LOGGER_DEBUG(av->log, "Setting new video bitrate to: %d", bit_rate); if (call->video_bit_rate == bit_rate) { - LOGGER_DEBUG(av->m->log, "Video bitrate already set to: %d", bit_rate); + LOGGER_DEBUG(av->log, "Video bitrate already set to: %d", bit_rate); } else if (bit_rate == 0) { - LOGGER_DEBUG(av->m->log, "Turned off video sending"); + LOGGER_DEBUG(av->log, "Turned off video sending"); /* Video sending is turned off; notify peer */ - if (msi_change_capabilities(call->msi_call, call->msi_call-> + if (msi_change_capabilities(av->log, call->msi_call, call->msi_call-> self_capabilities ^ MSI_CAP_S_VIDEO) != 0) { pthread_mutex_unlock(av->mutex); rc = TOXAV_ERR_BIT_RATE_SET_SYNC; @@ -754,10 +839,10 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra pthread_mutex_lock(call->toxav_call_mutex); if (call->video_bit_rate == 0) { - LOGGER_DEBUG(av->m->log, "Turned on video sending"); + LOGGER_DEBUG(av->log, "Turned on video sending"); /* The video has been turned off before this */ - if (msi_change_capabilities(call->msi_call, call-> + if (msi_change_capabilities(av->log, call->msi_call, call-> msi_call->self_capabilities | MSI_CAP_S_VIDEO) != 0) { pthread_mutex_unlock(call->toxav_call_mutex); pthread_mutex_unlock(av->mutex); @@ -765,7 +850,7 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra goto RETURN; } } else { - LOGGER_DEBUG(av->m->log, "Set new video bit rate %d", bit_rate); + LOGGER_DEBUG(av->log, "Set new video bit rate %d", bit_rate); } call->video_bit_rate = bit_rate; @@ -781,6 +866,7 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra return rc == TOXAV_ERR_BIT_RATE_SET_OK; } + void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback, void *user_data) { pthread_mutex_lock(av->mutex); @@ -788,6 +874,7 @@ void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback, av->abcb_user_data = user_data; pthread_mutex_unlock(av->mutex); } + void toxav_callback_video_bit_rate(ToxAV *av, toxav_video_bit_rate_cb *callback, void *user_data) { pthread_mutex_lock(av->mutex); @@ -795,13 +882,14 @@ void toxav_callback_video_bit_rate(ToxAV *av, toxav_video_bit_rate_cb *callback, av->vbcb_user_data = user_data; pthread_mutex_unlock(av->mutex); } + bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pcm, size_t sample_count, uint8_t channels, uint32_t sampling_rate, Toxav_Err_Send_Frame *error) { Toxav_Err_Send_Frame rc = TOXAV_ERR_SEND_FRAME_OK; ToxAVCall *call; - if (!m_friend_exists(av->m, friend_number)) { + if (!tox_friend_exists(av->tox, friend_number)) { rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND; goto RETURN; } @@ -859,14 +947,14 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc dest + sizeof(sampling_rate), dest_size - sizeof(sampling_rate)); if (vrc < 0) { - LOGGER_WARNING(av->m->log, "Failed to encode frame %s", opus_strerror(vrc)); + LOGGER_WARNING(av->log, "Failed to encode frame %s", opus_strerror(vrc)); pthread_mutex_unlock(call->mutex_audio); rc = TOXAV_ERR_SEND_FRAME_INVALID; goto RETURN; } - if (rtp_send_data(call->audio_rtp, dest, vrc + sizeof(sampling_rate), false, av->m->log) != 0) { - LOGGER_WARNING(av->m->log, "Failed to send audio packet"); + if (rtp_send_data(av->log, call->audio_rtp, dest, vrc + sizeof(sampling_rate), false) != 0) { + LOGGER_WARNING(av->log, "Failed to send audio packet"); rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED; } } @@ -882,7 +970,7 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc return rc == TOXAV_ERR_SEND_FRAME_OK; } -static Toxav_Err_Send_Frame send_frames(const Logger *log, ToxAVCall *call) +static Toxav_Err_Send_Frame send_frames(const ToxAV *av, ToxAVCall *call) { vpx_codec_iter_t iter = nullptr; @@ -900,20 +988,15 @@ static Toxav_Err_Send_Frame send_frames(const Logger *log, ToxAVCall *call) const uint32_t frame_length_in_bytes = pkt->data.frame.sz; const int res = rtp_send_data( + av->log, call->video_rtp, (const uint8_t *)pkt->data.frame.buf, frame_length_in_bytes, - is_keyframe, - log); - - LOGGER_DEBUG(log, "+ _sending_FRAME_TYPE_==%s bytes=%d frame_len=%d", is_keyframe ? "K" : ".", - (int)pkt->data.frame.sz, (int)frame_length_in_bytes); - const uint8_t *const buf = (const uint8_t *)pkt->data.frame.buf; - LOGGER_DEBUG(log, "+ _sending_FRAME_ b0=%d b1=%d", buf[0], buf[1]); + is_keyframe); if (res < 0) { char *netstrerror = net_new_strerror(net_error()); - LOGGER_WARNING(log, "Could not send video frame: %s", netstrerror); + LOGGER_WARNING(av->log, "Could not send video frame: %s", netstrerror); net_kill_strerror(netstrerror); return TOXAV_ERR_SEND_FRAME_RTP_FAILED; } @@ -930,7 +1013,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u int vpx_encode_flags = 0; - if (!m_friend_exists(av->m, friend_number)) { + if (!tox_friend_exists(av->tox, friend_number)) { rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND; goto RETURN; } @@ -965,7 +1048,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u goto RETURN; } - if (vc_reconfigure_encoder(call->video, call->video_bit_rate * 1000, width, height, -1) != 0) { + if (vc_reconfigure_encoder(call->video, call->video_bit_rate, width, height, -1) != 0) { pthread_mutex_unlock(call->mutex_video); rc = TOXAV_ERR_SEND_FRAME_INVALID; goto RETURN; @@ -974,13 +1057,13 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u if (call->video_rtp->ssrc < VIDEO_SEND_X_KEYFRAMES_FIRST) { // Key frame flag for first frames vpx_encode_flags = VPX_EFLAG_FORCE_KF; - LOGGER_DEBUG(av->m->log, "I_FRAME_FLAG:%d only-i-frame mode", call->video_rtp->ssrc); + LOGGER_DEBUG(av->log, "I_FRAME_FLAG:%d only-i-frame mode", call->video_rtp->ssrc); ++call->video_rtp->ssrc; } else if (call->video_rtp->ssrc == VIDEO_SEND_X_KEYFRAMES_FIRST) { // normal keyframe placement vpx_encode_flags = 0; - LOGGER_DEBUG(av->m->log, "I_FRAME_FLAG:%d normal mode", call->video_rtp->ssrc); + LOGGER_DEBUG(av->log, "I_FRAME_FLAG:%d normal mode", call->video_rtp->ssrc); ++call->video_rtp->ssrc; } @@ -1009,7 +1092,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u if (vrc != VPX_CODEC_OK) { pthread_mutex_unlock(call->mutex_video); - LOGGER_ERROR(av->m->log, "Could not encode video frame: %s", vpx_codec_err_to_string(vrc)); + LOGGER_ERROR(av->log, "Could not encode video frame: %s", vpx_codec_err_to_string(vrc)); rc = TOXAV_ERR_SEND_FRAME_INVALID; goto RETURN; } @@ -1017,7 +1100,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u ++call->video->frame_counter; - rc = send_frames(av->m->log, call); + rc = send_frames(av, call); pthread_mutex_unlock(call->mutex_video); @@ -1063,7 +1146,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, ToxAVCall *call = (ToxAVCall *)user_data; assert(call != nullptr); - LOGGER_DEBUG(call->av->m->log, "Reported loss of %f%%", (double)loss * 100); + LOGGER_DEBUG(call->av->log, "Reported loss of %f%%", (double)loss * 100); /* if less than 10% data loss we do nothing! */ if (loss < 0.1F) { @@ -1075,7 +1158,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, if (call->video_bit_rate != 0) { if (call->av->vbcb == nullptr) { pthread_mutex_unlock(call->av->mutex); - LOGGER_WARNING(call->av->m->log, "No callback to report loss on"); + LOGGER_WARNING(call->av->log, "No callback to report loss on"); return; } @@ -1085,7 +1168,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, } else if (call->audio_bit_rate != 0) { if (call->av->abcb == nullptr) { pthread_mutex_unlock(call->av->mutex); - LOGGER_WARNING(call->av->m->log, "No callback to report loss on"); + LOGGER_WARNING(call->av->log, "No callback to report loss on"); return; } @@ -1096,6 +1179,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, pthread_mutex_unlock(call->av->mutex); } + static int callback_invite(void *object, MSICall *call) { ToxAV *toxav = (ToxAV *)object; @@ -1104,7 +1188,7 @@ static int callback_invite(void *object, MSICall *call) ToxAVCall *av_call = call_new(toxav, call->friend_number, nullptr); if (av_call == nullptr) { - LOGGER_WARNING(toxav->m->log, "Failed to initialize call..."); + LOGGER_WARNING(toxav->log, "Failed to initialize call..."); pthread_mutex_unlock(toxav->mutex); return -1; } @@ -1124,6 +1208,7 @@ static int callback_invite(void *object, MSICall *call) pthread_mutex_unlock(toxav->mutex); return 0; } + static int callback_start(void *object, MSICall *call) { ToxAV *toxav = (ToxAV *)object; @@ -1152,6 +1237,7 @@ static int callback_start(void *object, MSICall *call) pthread_mutex_unlock(toxav->mutex); return 0; } + static int callback_end(void *object, MSICall *call) { ToxAV *toxav = (ToxAV *)object; @@ -1167,6 +1253,7 @@ static int callback_end(void *object, MSICall *call) pthread_mutex_unlock(toxav->mutex); return 0; } + static int callback_error(void *object, MSICall *call) { ToxAV *toxav = (ToxAV *)object; @@ -1182,21 +1269,22 @@ static int callback_error(void *object, MSICall *call) pthread_mutex_unlock(toxav->mutex); return 0; } + static int callback_capabilites(void *object, MSICall *call) { ToxAV *toxav = (ToxAV *)object; pthread_mutex_lock(toxav->mutex); if ((call->peer_capabilities & MSI_CAP_S_AUDIO) != 0) { - rtp_allow_receiving(call->av_call->audio_rtp); + rtp_allow_receiving_mark(call->av_call->audio_rtp); } else { - rtp_stop_receiving(call->av_call->audio_rtp); + rtp_stop_receiving_mark(call->av_call->audio_rtp); } if ((call->peer_capabilities & MSI_CAP_S_VIDEO) != 0) { - rtp_allow_receiving(call->av_call->video_rtp); + rtp_allow_receiving_mark(call->av_call->video_rtp); } else { - rtp_stop_receiving(call->av_call->video_rtp); + rtp_stop_receiving_mark(call->av_call->video_rtp); } invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities); @@ -1204,6 +1292,7 @@ static int callback_capabilites(void *object, MSICall *call) pthread_mutex_unlock(toxav->mutex); return 0; } + static bool audio_bit_rate_invalid(uint32_t bit_rate) { /* Opus RFC 6716 section-2.1.1 dictates the following: @@ -1211,6 +1300,7 @@ static bool audio_bit_rate_invalid(uint32_t bit_rate) */ return bit_rate < 6 || bit_rate > 510; } + static bool video_bit_rate_invalid(uint32_t bit_rate) { /* https://www.webmproject.org/docs/webm-sdk/structvpx__codec__enc__cfg.html shows the following: @@ -1222,6 +1312,7 @@ static bool video_bit_rate_invalid(uint32_t bit_rate) */ return bit_rate > UINT32_MAX; } + static bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state) { if (av->scb != nullptr) { @@ -1239,12 +1330,17 @@ static ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, Toxav_Err_Call *er Toxav_Err_Call rc = TOXAV_ERR_CALL_OK; ToxAVCall *call = nullptr; - if (!m_friend_exists(av->m, friend_number)) { + Tox_Err_Friend_Query f_con_query_error; + Tox_Connection f_con_status = TOX_CONNECTION_NONE; + + if (!tox_friend_exists(av->tox, friend_number)) { rc = TOXAV_ERR_CALL_FRIEND_NOT_FOUND; goto RETURN; } - if (m_get_friend_connectionstatus(av->m, friend_number) < 1) { + f_con_status = tox_friend_get_connection_status(av->tox, friend_number, &f_con_query_error); + + if (f_con_status == TOX_CONNECTION_NONE) { rc = TOXAV_ERR_CALL_FRIEND_NOT_CONNECTED; goto RETURN; } @@ -1323,16 +1419,6 @@ static ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, Toxav_Err_Call *er return call; } -static ToxAVCall *call_get(ToxAV *av, uint32_t friend_number) -{ - /* Assumes mutex locked */ - if (av->calls == nullptr || av->calls_tail < friend_number) { - return nullptr; - } - - return av->calls[friend_number]; -} - static ToxAVCall *call_remove(ToxAVCall *call) { if (call == nullptr) { @@ -1399,7 +1485,7 @@ static bool call_prepare_transmission(ToxAVCall *call) } if (call->active) { - LOGGER_WARNING(av->m->log, "Call already active!"); + LOGGER_WARNING(av->log, "Call already active!"); return true; } @@ -1412,43 +1498,37 @@ static bool call_prepare_transmission(ToxAVCall *call) } /* Prepare bwc */ - call->bwc = bwc_new(av->m, av->tox, call->friend_number, callback_bwc, call, av->toxav_mono_time); - - if (call->bwc == nullptr) { - LOGGER_ERROR(av->m->log, "Failed to create new bwc"); - goto FAILURE; - } + call->bwc = bwc_new(av->log, av->tox, call->friend_number, callback_bwc, call, av->toxav_mono_time); - { /* Prepare audio */ - call->audio = ac_new(av->toxav_mono_time, av->m->log, av, call->friend_number, av->acb, av->acb_user_data); + { /* Prepare audio */ + call->audio = ac_new(av->toxav_mono_time, av->log, av, call->friend_number, av->acb, av->acb_user_data); if (call->audio == nullptr) { - LOGGER_ERROR(av->m->log, "Failed to create audio codec session"); + LOGGER_ERROR(av->log, "Failed to create audio codec session"); goto FAILURE; } - call->audio_rtp = rtp_new(RTP_TYPE_AUDIO, av->m, av->tox, call->friend_number, call->bwc, + call->audio_rtp = rtp_new(av->log, RTP_TYPE_AUDIO, av->tox, av, call->friend_number, call->bwc, call->audio, ac_queue_message); if (call->audio_rtp == nullptr) { - LOGGER_ERROR(av->m->log, "Failed to create audio rtp session"); + LOGGER_ERROR(av->log, "Failed to create audio rtp session"); goto FAILURE; } } - - { /* Prepare video */ - call->video = vc_new(av->toxav_mono_time, av->m->log, av, call->friend_number, av->vcb, av->vcb_user_data); + { /* Prepare video */ + call->video = vc_new(av->log, av->toxav_mono_time, av, call->friend_number, av->vcb, av->vcb_user_data); if (call->video == nullptr) { - LOGGER_ERROR(av->m->log, "Failed to create video codec session"); + LOGGER_ERROR(av->log, "Failed to create video codec session"); goto FAILURE; } - call->video_rtp = rtp_new(RTP_TYPE_VIDEO, av->m, av->tox, call->friend_number, call->bwc, + call->video_rtp = rtp_new(av->log, RTP_TYPE_VIDEO, av->tox, av, call->friend_number, call->bwc, call->video, vc_queue_message); if (call->video_rtp == nullptr) { - LOGGER_ERROR(av->m->log, "Failed to create video rtp session"); + LOGGER_ERROR(av->log, "Failed to create video rtp session"); goto FAILURE; } } @@ -1458,11 +1538,11 @@ static bool call_prepare_transmission(ToxAVCall *call) FAILURE: bwc_kill(call->bwc); - rtp_kill(call->audio_rtp); + rtp_kill(av->log, call->audio_rtp); ac_kill(call->audio); call->audio_rtp = nullptr; call->audio = nullptr; - rtp_kill(call->video_rtp); + rtp_kill(av->log, call->video_rtp); vc_kill(call->video); call->video_rtp = nullptr; call->video = nullptr; @@ -1489,12 +1569,14 @@ static void call_kill_transmission(ToxAVCall *call) bwc_kill(call->bwc); - rtp_kill(call->audio_rtp); + const ToxAV *av = call->av; + + rtp_kill(av->log, call->audio_rtp); ac_kill(call->audio); call->audio_rtp = nullptr; call->audio = nullptr; - rtp_kill(call->video_rtp); + rtp_kill(av->log, call->video_rtp); vc_kill(call->video); call->video_rtp = nullptr; call->video = nullptr; @@ -1502,3 +1584,12 @@ static void call_kill_transmission(ToxAVCall *call) pthread_mutex_destroy(call->mutex_audio); pthread_mutex_destroy(call->mutex_video); } + +Mono_Time *toxav_get_av_mono_time(const ToxAV *av) +{ + if (av == nullptr) { + return nullptr; + } + + return av->toxav_mono_time; +} diff --git a/toxav/toxav.h b/toxav/toxav.h index 3b4bd09c23..a9e3485b67 100644 --- a/toxav/toxav.h +++ b/toxav/toxav.h @@ -73,6 +73,8 @@ typedef struct Tox Tox; #endif /* !TOX_DEFINED */ #endif /* !APIGEN_IGNORE */ +#ifndef TOXAV_DEFINED +#define TOXAV_DEFINED /** * @brief The ToxAV instance type. * @@ -83,6 +85,7 @@ typedef struct Tox Tox; * notifying peers. */ typedef struct ToxAV ToxAV; +#endif /* TOXAV_DEFINED */ /** @{ * @brief Creation and destruction @@ -246,9 +249,9 @@ typedef enum Toxav_Err_Call { * receiving are both enabled by default. * * @param friend_number The friend number of the friend that should be called. - * @param audio_bit_rate Audio bit rate in Kb/sec. Set this to 0 to disable + * @param audio_bit_rate Audio bit rate in kbit/sec. Set this to 0 to disable * audio sending. - * @param video_bit_rate Video bit rate in Kb/sec. Set this to 0 to disable + * @param video_bit_rate Video bit rate in kbit/sec. Set this to 0 to disable * video sending. */ bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, @@ -315,9 +318,9 @@ typedef enum Toxav_Err_Answer { * enabled by default. * * @param friend_number The friend number of the friend that is calling. - * @param audio_bit_rate Audio bit rate in Kb/sec. Set this to 0 to disable + * @param audio_bit_rate Audio bit rate in kbit/sec. Set this to 0 to disable * audio sending. - * @param video_bit_rate Video bit rate in Kb/sec. Set this to 0 to disable + * @param video_bit_rate Video bit rate in kbit/sec. Set this to 0 to disable * video sending. */ bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, @@ -597,11 +600,11 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t pcm uint8_t channels, uint32_t sampling_rate, Toxav_Err_Send_Frame *error); /** - * Set the bit rate to be used in subsequent video frames. + * Set the bit rate to be used in subsequent audio frames. * * @param friend_number The friend number of the friend for which to set the * bit rate. - * @param bit_rate The new audio bit rate in Kb/sec. Set to 0 to disable. + * @param bit_rate The new audio bit rate in kbit/sec. Set to 0 to disable. * * @return true on success. */ @@ -614,7 +617,7 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra * * @param friend_number The friend number of the friend for which to set the * bit rate. - * @param audio_bit_rate Suggested maximum audio bit rate in Kb/sec. + * @param audio_bit_rate Suggested maximum audio bit rate in kbit/sec. */ typedef void toxav_audio_bit_rate_cb(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, void *user_data); @@ -627,9 +630,10 @@ void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback, /** * Send a video frame to a friend. * - * Y - plane should be of size: `height * width` - * U - plane should be of size: `(height/2) * (width/2)` - * V - plane should be of size: `(height/2) * (width/2)` + * The video frame needs to be planar YUV420. + * Y - plane should be of size: `width * height` + * U - plane should be of size: `(width/2) * (height/2)` + * V - plane should be of size: `(width/2) * (height/2)` * * @param friend_number The friend number of the friend to which to send a video * frame. @@ -641,9 +645,9 @@ void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback, */ bool toxav_video_send_frame( ToxAV *av, uint32_t friend_number, uint16_t width, uint16_t height, - const uint8_t y[/*! height * width */], - const uint8_t u[/*! height/2 * width/2 */], - const uint8_t v[/*! height/2 * width/2 */], + const uint8_t y[/*! width * height */], + const uint8_t u[/*! width/2 * height/2 */], + const uint8_t v[/*! width/2 * height/2 */], Toxav_Err_Send_Frame *error); /** @@ -651,7 +655,7 @@ bool toxav_video_send_frame( * * @param friend_number The friend number of the friend for which to set the * bit rate. - * @param bit_rate The new video bit rate in Kb/sec. Set to 0 to disable. + * @param bit_rate The new video bit rate in kbit/sec. Set to 0 to disable. * * @return true on success. */ @@ -664,7 +668,7 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra * * @param friend_number The friend number of the friend for which to set the * bit rate. - * @param video_bit_rate Suggested maximum video bit rate in Kb/sec. + * @param video_bit_rate Suggested maximum video bit rate in kbit/sec. */ typedef void toxav_video_bit_rate_cb(ToxAV *av, uint32_t friend_number, uint32_t video_bit_rate, void *user_data); diff --git a/toxav/toxav_hacks.h b/toxav/toxav_hacks.h new file mode 100644 index 0000000000..2b0382d080 --- /dev/null +++ b/toxav/toxav_hacks.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013-2015 Tox project. + */ +#ifndef C_TOXCORE_TOXAV_HACKS_H +#define C_TOXCORE_TOXAV_HACKS_H + +#include "bwcontroller.h" +#include "msi.h" +#include "rtp.h" + +#ifndef TOXAV_CALL_DEFINED +#define TOXAV_CALL_DEFINED +typedef struct ToxAVCall ToxAVCall; +#endif /* TOXAV_CALL_DEFINED */ + +non_null() +ToxAVCall *call_get(ToxAV *av, uint32_t friend_number); + +non_null() +RTPSession *rtp_session_get(ToxAVCall *call, int payload_type); + +non_null() +MSISession *tox_av_msi_get(const ToxAV *av); + +non_null() +BWController *bwc_controller_get(const ToxAVCall *call); + +non_null() +Mono_Time *toxav_get_av_mono_time(const ToxAV *av); + +non_null() +const Logger *toxav_get_logger(const ToxAV *av); + +#endif /* C_TOXCORE_TOXAV_HACKS_H */ diff --git a/toxav/video.c b/toxav/video.c index 301400b02f..4d1d5a9415 100644 --- a/toxav/video.c +++ b/toxav/video.c @@ -143,7 +143,7 @@ static void vc_init_encoder_cfg(const Logger *log, vpx_codec_enc_cfg_t *cfg, int #endif /* 0 */ } -VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t friend_number, +VCSession *vc_new(const Logger *log, Mono_Time *mono_time, ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb, void *cb_data) { VCSession *vc = (VCSession *)calloc(1, sizeof(VCSession)); @@ -216,7 +216,7 @@ VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t f /* Set encoder to some initial values */ - vpx_codec_enc_cfg_t cfg; + vpx_codec_enc_cfg_t cfg; vc_init_encoder_cfg(log, &cfg, 1); LOGGER_DEBUG(log, "Using VP8 codec for encoder (0.1)"); @@ -250,6 +250,7 @@ VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t f } #endif /* 0 */ + vc->linfts = current_time_monotonic(mono_time); vc->lcfd = 60; vc->vcb = cb; @@ -258,12 +259,14 @@ VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t f vc->av = av; vc->log = log; return vc; + BASE_CLEANUP_1: vpx_codec_destroy(vc->decoder); BASE_CLEANUP: pthread_mutex_destroy(vc->queue_mutex); rb_kill(vc->vbuf_raw); free(vc); + return nullptr; } diff --git a/toxav/video.h b/toxav/video.h index 57db74ac66..7bd54fa631 100644 --- a/toxav/video.h +++ b/toxav/video.h @@ -33,7 +33,6 @@ typedef struct VCSession { uint64_t linfts; /* Last received frame time stamp */ uint32_t lcfd; /* Last calculated frame duration for incoming video payload */ - const Logger *log; ToxAV *av; uint32_t friend_number; @@ -42,9 +41,10 @@ typedef struct VCSession { void *vcb_user_data; pthread_mutex_t queue_mutex[1]; + const Logger *log; } VCSession; -VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t friend_number, +VCSession *vc_new(const Logger *log, Mono_Time *mono_time, ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb, void *cb_data); void vc_kill(VCSession *vc); void vc_iterate(VCSession *vc); diff --git a/toxcore/BUILD.bazel b/toxcore/BUILD.bazel index 0f313e2af5..916c6221b2 100644 --- a/toxcore/BUILD.bazel +++ b/toxcore/BUILD.bazel @@ -6,7 +6,7 @@ exports_files( "tox.h", "tox_private.h", ], - visibility = ["//c-toxcore:__pkg__"], + visibility = ["//c-toxcore:__subpackages__"], ) cc_library( @@ -661,7 +661,10 @@ cc_library( name = "net_crypto", srcs = ["net_crypto.c"], hdrs = ["net_crypto.h"], - visibility = ["//c-toxcore/auto_tests:__pkg__"], + visibility = [ + "//c-toxcore/auto_tests:__pkg__", + "//c-toxcore/toxav:__pkg__", + ], deps = [ ":DHT", ":LAN_discovery", diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 2567d1b5a8..89c85c3463 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -380,12 +380,12 @@ int dht_create_packet(const Memory *mem, const Random *rng, const int encrypted_length = encrypt_data_symmetric(shared_key, nonce, plain, plain_length, encrypted); - if (encrypted_length == -1) { + if (encrypted_length < 0) { mem_delete(mem, encrypted); return -1; } - if (length < 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length) { + if (length < 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + (size_t)encrypted_length) { mem_delete(mem, encrypted); return -1; } @@ -1347,15 +1347,15 @@ static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t plain[0] = num_nodes; memcpy(plain + 1 + nodes_length, sendback_data, length); - const uint32_t crypto_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE; - const uint32_t data_size = 1 + nodes_length + length + crypto_size; + const uint16_t crypto_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE; + const uint16_t data_size = 1 + nodes_length + length + crypto_size; VLA(uint8_t, data, data_size); const int len = dht_create_packet(dht->mem, dht->rng, dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6, plain, 1 + nodes_length + length, data, data_size); - if (len != data_size) { + if (len < 0 || (uint32_t)len != data_size) { return -1; } diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 391c2431eb..96b332f579 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -472,10 +472,6 @@ int m_delfriend(Messenger *m, int32_t friendnumber) return -1; } - if (m->friend_connectionstatuschange_internal != nullptr) { - m->friend_connectionstatuschange_internal(m, friendnumber, false, m->friend_connectionstatuschange_internal_userdata); - } - clear_receipts(m, friendnumber); remove_request_received(m->fr, m->friendlist[friendnumber].real_pk); friend_connection_callbacks(m->fr_c, m->friendlist[friendnumber].friendcon_id, MESSENGER_CALLBACK_INDEX, nullptr, @@ -1027,13 +1023,6 @@ void m_callback_core_connection(Messenger *m, m_self_connection_status_cb *funct m->core_connection_change = function; } -void m_callback_connectionstatus_internal_av(Messenger *m, m_friend_connectionstatuschange_internal_cb *function, - void *userdata) -{ - m->friend_connectionstatuschange_internal = function; - m->friend_connectionstatuschange_internal_userdata = userdata; -} - non_null(1) nullable(3) static void check_friend_tcp_udp(Messenger *m, int32_t friendnumber, void *userdata) { @@ -1081,11 +1070,6 @@ static void check_friend_connectionstatus(Messenger *m, int32_t friendnumber, ui m->friendlist[friendnumber].status = status; check_friend_tcp_udp(m, friendnumber, userdata); - - if (m->friend_connectionstatuschange_internal != nullptr) { - m->friend_connectionstatuschange_internal(m, friendnumber, is_online, - m->friend_connectionstatuschange_internal_userdata); - } } } @@ -1855,23 +1839,6 @@ static int handle_filecontrol(Messenger *m, int32_t friendnumber, bool outbound, } } -/** @brief Set the callback for msi packets. */ -void m_callback_msi_packet(Messenger *m, m_msi_packet_cb *function, void *userdata) -{ - m->msi_packet = function; - m->msi_packet_userdata = userdata; -} - -/** @brief Send an msi packet. - * - * @retval true on success - * @retval false on failure - */ -bool m_msi_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length) -{ - return write_cryptpacket_id(m, friendnumber, PACKET_ID_MSI, data, length, false); -} - static int m_handle_lossy_packet(void *object, int friendcon_id, const uint8_t *data, uint16_t length, void *userdata) { @@ -1881,17 +1848,6 @@ static int m_handle_lossy_packet(void *object, int friendcon_id, const uint8_t * return 1; } - if (data[0] <= PACKET_ID_RANGE_LOSSY_AV_END) { - const RTP_Packet_Handler *const ph = - &m->friendlist[friendcon_id].lossy_rtp_packethandlers[data[0] % PACKET_ID_RANGE_LOSSY_AV_SIZE]; - - if (ph->function != nullptr) { - return ph->function(m, friendcon_id, data, length, ph->object); - } - - return 1; - } - if (m->lossy_packethandler != nullptr) { m->lossy_packethandler(m, friendcon_id, data[0], data, length, userdata); } @@ -1904,38 +1860,6 @@ void custom_lossy_packet_registerhandler(Messenger *m, m_friend_lossy_packet_cb m->lossy_packethandler = lossy_packethandler; } -int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte, m_lossy_rtp_packet_cb *function, - void *object) -{ - if (!m_friend_exists(m, friendnumber)) { - return -1; - } - - if (byte < PACKET_ID_RANGE_LOSSY_AV_START || byte > PACKET_ID_RANGE_LOSSY_AV_END) { - return -1; - } - - m->friendlist[friendnumber].lossy_rtp_packethandlers[byte % PACKET_ID_RANGE_LOSSY_AV_SIZE].function = function; - m->friendlist[friendnumber].lossy_rtp_packethandlers[byte % PACKET_ID_RANGE_LOSSY_AV_SIZE].object = object; - return 0; -} - -/** @brief High level function to send custom lossy packets. - * - * TODO(oxij): this name is confusing, because this function sends both av and custom lossy packets. - * Meanwhile, m_handle_lossy_packet routes custom packets to custom_lossy_packet_registerhandler - * as you would expect from its name. - * - * I.e. custom_lossy_packet_registerhandler's "custom lossy packet" and this "custom lossy packet" - * are not the same set of packets. - * - * @retval -1 if friend invalid. - * @retval -2 if length wrong. - * @retval -3 if first byte invalid. - * @retval -4 if friend offline. - * @retval -5 if packet failed to send because of other error. - * @retval 0 on success. - */ int m_send_custom_lossy_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint32_t length) { if (!m_friend_exists(m, friendnumber)) { @@ -1946,7 +1870,6 @@ int m_send_custom_lossy_packet(const Messenger *m, int32_t friendnumber, const u return -2; } - // TODO(oxij): send_lossy_cryptpacket makes this check already, similarly for other similar places if (data[0] < PACKET_ID_RANGE_LOSSY_START || data[0] > PACKET_ID_RANGE_LOSSY_END) { return -3; } @@ -1974,7 +1897,10 @@ static int handle_custom_lossless_packet(void *object, int friend_num, const uin } if (packet[0] < PACKET_ID_RANGE_LOSSLESS_CUSTOM_START || packet[0] > PACKET_ID_RANGE_LOSSLESS_CUSTOM_END) { - return -1; + // allow PACKET_ID_MSI packets to be handled by custom packet handler + if (packet[0] != PACKET_ID_MSI) { + return -1; + } } if (m->lossless_packethandler != nullptr) { @@ -2356,20 +2282,6 @@ static int m_handle_packet_file_data(Messenger *m, const int friendcon_id, const return 0; } -non_null(1, 3) nullable(5) -static int m_handle_packet_msi(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata) -{ - if (data_length == 0) { - return 0; - } - - if (m->msi_packet != nullptr) { - m->msi_packet(m, friendcon_id, data, data_length, m->msi_packet_userdata); - } - - return 0; -} - non_null(1, 3) nullable(5) static int m_handle_packet_invite_groupchat(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata) { @@ -2443,7 +2355,7 @@ static int m_handle_packet(void *object, int friendcon_id, const uint8_t *data, case PACKET_ID_FILE_DATA: return m_handle_packet_file_data(m, friendcon_id, payload, payload_length, userdata); case PACKET_ID_MSI: - return m_handle_packet_msi(m, friendcon_id, payload, payload_length, userdata); + return handle_custom_lossless_packet(object, friendcon_id, data, length, userdata); case PACKET_ID_INVITE_GROUPCHAT: return m_handle_packet_invite_groupchat(m, friendcon_id, payload, payload_length, userdata); } diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 33897449a8..ca940687e7 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -201,20 +201,10 @@ typedef void m_friend_lossy_packet_cb(Messenger *m, uint32_t friend_number, uint size_t length, void *user_data); typedef void m_friend_lossless_packet_cb(Messenger *m, uint32_t friend_number, uint8_t packet_id, const uint8_t *data, size_t length, void *user_data); -typedef void m_friend_connectionstatuschange_internal_cb(Messenger *m, uint32_t friend_number, - bool is_online, void *user_data); typedef void m_conference_invite_cb(Messenger *m, uint32_t friend_number, const uint8_t *cookie, uint16_t length, void *user_data); typedef void m_group_invite_cb(const Messenger *m, uint32_t friend_number, const uint8_t *invite_data, size_t length, const uint8_t *group_name, size_t group_name_length, void *user_data); -typedef void m_msi_packet_cb(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, - void *user_data); -typedef int m_lossy_rtp_packet_cb(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object); - -typedef struct RTP_Packet_Handler { - m_lossy_rtp_packet_cb *function; - void *object; -} RTP_Packet_Handler; typedef struct Friend { uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE]; @@ -244,8 +234,6 @@ typedef struct Friend { uint32_t num_sending_files; struct File_Transfers file_receiving[MAX_CONCURRENT_FILE_PIPES]; - RTP_Packet_Handler lossy_rtp_packethandlers[PACKET_ID_RANGE_LOSSY_AV_SIZE]; - struct Receipts *receipts_start; struct Receipts *receipts_end; } Friend; @@ -302,8 +290,6 @@ struct Messenger { m_friend_typing_cb *friend_typingchange; m_friend_read_receipt_cb *read_receipt; m_friend_connection_status_cb *friend_connectionstatuschange; - m_friend_connectionstatuschange_internal_cb *friend_connectionstatuschange_internal; - void *friend_connectionstatuschange_internal_userdata; struct Group_Chats *conferences_object; m_conference_invite_cb *conference_invite; @@ -315,9 +301,6 @@ struct Messenger { m_file_recv_chunk_cb *file_filedata; m_file_chunk_request_cb *file_reqchunk; - m_msi_packet_cb *msi_packet; - void *msi_packet_userdata; - m_friend_lossy_packet_cb *lossy_packethandler; m_friend_lossless_packet_cb *lossless_packethandler; @@ -615,10 +598,6 @@ non_null() void m_callback_read_receipt(Messenger *m, m_friend_read_receipt_cb * */ non_null() void m_callback_connectionstatus(Messenger *m, m_friend_connection_status_cb *function); -/** Same as previous but for internal A/V core usage only */ -non_null() void m_callback_connectionstatus_internal_av( - Messenger *m, m_friend_connectionstatuschange_internal_cb *function, void *userdata); - /** @brief Set the callback for typing changes. */ non_null() void m_callback_core_connection(Messenger *m, m_self_connection_status_cb *function); @@ -732,42 +711,12 @@ non_null(1) nullable(5) int send_file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uint64_t position, const uint8_t *data, uint16_t length); -/*** A/V related */ - -/** @brief Set the callback for msi packets. */ -non_null(1) nullable(2, 3) -void m_callback_msi_packet(Messenger *m, m_msi_packet_cb *function, void *userdata); - -/** @brief Send an msi packet. - * - * @retval true on success - * @retval false on failure - */ -non_null() -bool m_msi_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length); - -/** @brief Set handlers for lossy rtp packets. - * - * @retval -1 on failure. - * @retval 0 on success. - */ -non_null(1) nullable(4, 5) -int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte, - m_lossy_rtp_packet_cb *function, void *object); - /*** CUSTOM PACKETS */ /** @brief Set handlers for custom lossy packets. */ non_null() void custom_lossy_packet_registerhandler(Messenger *m, m_friend_lossy_packet_cb *lossy_packethandler); /** @brief High level function to send custom lossy packets. - * - * TODO(oxij): this name is confusing, because this function sends both av and custom lossy packets. - * Meanwhile, m_handle_lossy_packet routes custom packets to custom_lossy_packet_registerhandler - * as you would expect from its name. - * - * I.e. custom_lossy_packet_registerhandler's "custom lossy packet" and this "custom lossy packet" - * are not the same set of packets. * * @retval -1 if friend invalid. * @retval -2 if length wrong. diff --git a/toxcore/announce.c b/toxcore/announce.c index b983cb0574..7bda993232 100644 --- a/toxcore/announce.c +++ b/toxcore/announce.c @@ -579,7 +579,7 @@ static int create_reply(Announcements *announce, const IP_Port *source, const int plain_reply_max_len = (int)reply_max_length - (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE); - if (plain_reply_max_len < sizeof(uint64_t)) { + if (plain_reply_max_len < (int)sizeof(uint64_t)) { return -1; } diff --git a/toxcore/events/conference_connected.c b/toxcore/events/conference_connected.c index dbd9e4b51a..8aeb17204b 100644 --- a/toxcore/events/conference_connected.c +++ b/toxcore/events/conference_connected.c @@ -109,7 +109,10 @@ static Tox_Event_Conference_Connected *tox_events_add_conference_connected(Tox_E event.type = TOX_EVENT_CONFERENCE_CONNECTED; event.data.conference_connected = conference_connected; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_conference_connected_free(conference_connected, mem); + return nullptr; + } return conference_connected; } diff --git a/toxcore/events/conference_invite.c b/toxcore/events/conference_invite.c index fb1f794bf3..c9b8d14bc1 100644 --- a/toxcore/events/conference_invite.c +++ b/toxcore/events/conference_invite.c @@ -177,7 +177,10 @@ static Tox_Event_Conference_Invite *tox_events_add_conference_invite(Tox_Events event.type = TOX_EVENT_CONFERENCE_INVITE; event.data.conference_invite = conference_invite; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_conference_invite_free(conference_invite, mem); + return nullptr; + } return conference_invite; } diff --git a/toxcore/events/conference_message.c b/toxcore/events/conference_message.c index 74e1123e01..e509827e45 100644 --- a/toxcore/events/conference_message.c +++ b/toxcore/events/conference_message.c @@ -193,7 +193,10 @@ static Tox_Event_Conference_Message *tox_events_add_conference_message(Tox_Event event.type = TOX_EVENT_CONFERENCE_MESSAGE; event.data.conference_message = conference_message; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_conference_message_free(conference_message, mem); + return nullptr; + } return conference_message; } diff --git a/toxcore/events/conference_peer_list_changed.c b/toxcore/events/conference_peer_list_changed.c index 050bfb08f8..f7efd3f806 100644 --- a/toxcore/events/conference_peer_list_changed.c +++ b/toxcore/events/conference_peer_list_changed.c @@ -109,7 +109,10 @@ static Tox_Event_Conference_Peer_List_Changed *tox_events_add_conference_peer_li event.type = TOX_EVENT_CONFERENCE_PEER_LIST_CHANGED; event.data.conference_peer_list_changed = conference_peer_list_changed; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_conference_peer_list_changed_free(conference_peer_list_changed, mem); + return nullptr; + } return conference_peer_list_changed; } diff --git a/toxcore/events/conference_peer_name.c b/toxcore/events/conference_peer_name.c index fc6c255791..930065631f 100644 --- a/toxcore/events/conference_peer_name.c +++ b/toxcore/events/conference_peer_name.c @@ -175,7 +175,10 @@ static Tox_Event_Conference_Peer_Name *tox_events_add_conference_peer_name(Tox_E event.type = TOX_EVENT_CONFERENCE_PEER_NAME; event.data.conference_peer_name = conference_peer_name; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_conference_peer_name_free(conference_peer_name, mem); + return nullptr; + } return conference_peer_name; } diff --git a/toxcore/events/conference_title.c b/toxcore/events/conference_title.c index d761f51285..d8e269032e 100644 --- a/toxcore/events/conference_title.c +++ b/toxcore/events/conference_title.c @@ -175,7 +175,10 @@ static Tox_Event_Conference_Title *tox_events_add_conference_title(Tox_Events *e event.type = TOX_EVENT_CONFERENCE_TITLE; event.data.conference_title = conference_title; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_conference_title_free(conference_title, mem); + return nullptr; + } return conference_title; } diff --git a/toxcore/events/dht_get_nodes_response.c b/toxcore/events/dht_get_nodes_response.c index 6e03b73ea4..f637b9c93a 100644 --- a/toxcore/events/dht_get_nodes_response.c +++ b/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/toxcore/events/file_chunk_request.c b/toxcore/events/file_chunk_request.c index 4117ef3c4b..23e5f5bf18 100644 --- a/toxcore/events/file_chunk_request.c +++ b/toxcore/events/file_chunk_request.c @@ -162,7 +162,10 @@ static Tox_Event_File_Chunk_Request *tox_events_add_file_chunk_request(Tox_Event event.type = TOX_EVENT_FILE_CHUNK_REQUEST; event.data.file_chunk_request = file_chunk_request; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_file_chunk_request_free(file_chunk_request, mem); + return nullptr; + } return file_chunk_request; } diff --git a/toxcore/events/file_recv.c b/toxcore/events/file_recv.c index 45cec44b0d..389ce59830 100644 --- a/toxcore/events/file_recv.c +++ b/toxcore/events/file_recv.c @@ -207,7 +207,10 @@ static Tox_Event_File_Recv *tox_events_add_file_recv(Tox_Events *events, const M event.type = TOX_EVENT_FILE_RECV; event.data.file_recv = file_recv; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_file_recv_free(file_recv, mem); + return nullptr; + } return file_recv; } diff --git a/toxcore/events/file_recv_chunk.c b/toxcore/events/file_recv_chunk.c index 2edf7c5a7b..619011a4af 100644 --- a/toxcore/events/file_recv_chunk.c +++ b/toxcore/events/file_recv_chunk.c @@ -191,7 +191,10 @@ static Tox_Event_File_Recv_Chunk *tox_events_add_file_recv_chunk(Tox_Events *eve event.type = TOX_EVENT_FILE_RECV_CHUNK; event.data.file_recv_chunk = file_recv_chunk; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_file_recv_chunk_free(file_recv_chunk, mem); + return nullptr; + } return file_recv_chunk; } diff --git a/toxcore/events/file_recv_control.c b/toxcore/events/file_recv_control.c index 14a34aaf3b..3c575c09a6 100644 --- a/toxcore/events/file_recv_control.c +++ b/toxcore/events/file_recv_control.c @@ -148,7 +148,10 @@ static Tox_Event_File_Recv_Control *tox_events_add_file_recv_control(Tox_Events event.type = TOX_EVENT_FILE_RECV_CONTROL; event.data.file_recv_control = file_recv_control; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_file_recv_control_free(file_recv_control, mem); + return nullptr; + } return file_recv_control; } diff --git a/toxcore/events/friend_connection_status.c b/toxcore/events/friend_connection_status.c index 330554b05e..68c48695ad 100644 --- a/toxcore/events/friend_connection_status.c +++ b/toxcore/events/friend_connection_status.c @@ -132,7 +132,10 @@ static Tox_Event_Friend_Connection_Status *tox_events_add_friend_connection_stat event.type = TOX_EVENT_FRIEND_CONNECTION_STATUS; event.data.friend_connection_status = friend_connection_status; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_friend_connection_status_free(friend_connection_status, mem); + return nullptr; + } return friend_connection_status; } diff --git a/toxcore/events/friend_lossless_packet.c b/toxcore/events/friend_lossless_packet.c index 17e8fad926..b783e332f0 100644 --- a/toxcore/events/friend_lossless_packet.c +++ b/toxcore/events/friend_lossless_packet.c @@ -159,7 +159,10 @@ static Tox_Event_Friend_Lossless_Packet *tox_events_add_friend_lossless_packet(T event.type = TOX_EVENT_FRIEND_LOSSLESS_PACKET; event.data.friend_lossless_packet = friend_lossless_packet; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_friend_lossless_packet_free(friend_lossless_packet, mem); + return nullptr; + } return friend_lossless_packet; } diff --git a/toxcore/events/friend_lossy_packet.c b/toxcore/events/friend_lossy_packet.c index 6b2e9ed2b0..e3a6ad5f59 100644 --- a/toxcore/events/friend_lossy_packet.c +++ b/toxcore/events/friend_lossy_packet.c @@ -159,7 +159,10 @@ static Tox_Event_Friend_Lossy_Packet *tox_events_add_friend_lossy_packet(Tox_Eve event.type = TOX_EVENT_FRIEND_LOSSY_PACKET; event.data.friend_lossy_packet = friend_lossy_packet; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_friend_lossy_packet_free(friend_lossy_packet, mem); + return nullptr; + } return friend_lossy_packet; } diff --git a/toxcore/events/friend_message.c b/toxcore/events/friend_message.c index befcc74a24..dfd1daea39 100644 --- a/toxcore/events/friend_message.c +++ b/toxcore/events/friend_message.c @@ -177,7 +177,10 @@ static Tox_Event_Friend_Message *tox_events_add_friend_message(Tox_Events *event event.type = TOX_EVENT_FRIEND_MESSAGE; event.data.friend_message = friend_message; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_friend_message_free(friend_message, mem); + return nullptr; + } return friend_message; } diff --git a/toxcore/events/friend_name.c b/toxcore/events/friend_name.c index dfa9b39608..b5a5129724 100644 --- a/toxcore/events/friend_name.c +++ b/toxcore/events/friend_name.c @@ -159,7 +159,10 @@ static Tox_Event_Friend_Name *tox_events_add_friend_name(Tox_Events *events, con event.type = TOX_EVENT_FRIEND_NAME; event.data.friend_name = friend_name; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_friend_name_free(friend_name, mem); + return nullptr; + } return friend_name; } diff --git a/toxcore/events/friend_read_receipt.c b/toxcore/events/friend_read_receipt.c index e5f2f9db52..88808b5825 100644 --- a/toxcore/events/friend_read_receipt.c +++ b/toxcore/events/friend_read_receipt.c @@ -130,7 +130,10 @@ static Tox_Event_Friend_Read_Receipt *tox_events_add_friend_read_receipt(Tox_Eve event.type = TOX_EVENT_FRIEND_READ_RECEIPT; event.data.friend_read_receipt = friend_read_receipt; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_friend_read_receipt_free(friend_read_receipt, mem); + return nullptr; + } return friend_read_receipt; } diff --git a/toxcore/events/friend_request.c b/toxcore/events/friend_request.c index b492c15147..6cd8ac66c7 100644 --- a/toxcore/events/friend_request.c +++ b/toxcore/events/friend_request.c @@ -152,7 +152,10 @@ static Tox_Event_Friend_Request *tox_events_add_friend_request(Tox_Events *event event.type = TOX_EVENT_FRIEND_REQUEST; event.data.friend_request = friend_request; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_friend_request_free(friend_request, mem); + return nullptr; + } return friend_request; } diff --git a/toxcore/events/friend_status.c b/toxcore/events/friend_status.c index 3d7499722b..5af2d451d7 100644 --- a/toxcore/events/friend_status.c +++ b/toxcore/events/friend_status.c @@ -132,7 +132,10 @@ static Tox_Event_Friend_Status *tox_events_add_friend_status(Tox_Events *events, event.type = TOX_EVENT_FRIEND_STATUS; event.data.friend_status = friend_status; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_friend_status_free(friend_status, mem); + return nullptr; + } return friend_status; } diff --git a/toxcore/events/friend_status_message.c b/toxcore/events/friend_status_message.c index ad0519911e..178342f292 100644 --- a/toxcore/events/friend_status_message.c +++ b/toxcore/events/friend_status_message.c @@ -159,7 +159,10 @@ static Tox_Event_Friend_Status_Message *tox_events_add_friend_status_message(Tox event.type = TOX_EVENT_FRIEND_STATUS_MESSAGE; event.data.friend_status_message = friend_status_message; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_friend_status_message_free(friend_status_message, mem); + return nullptr; + } return friend_status_message; } diff --git a/toxcore/events/friend_typing.c b/toxcore/events/friend_typing.c index 692b07fb88..96c719570f 100644 --- a/toxcore/events/friend_typing.c +++ b/toxcore/events/friend_typing.c @@ -130,7 +130,10 @@ static Tox_Event_Friend_Typing *tox_events_add_friend_typing(Tox_Events *events, event.type = TOX_EVENT_FRIEND_TYPING; event.data.friend_typing = friend_typing; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_friend_typing_free(friend_typing, mem); + return nullptr; + } return friend_typing; } diff --git a/toxcore/events/group_custom_packet.c b/toxcore/events/group_custom_packet.c index f7a879aa92..eb4d49d594 100644 --- a/toxcore/events/group_custom_packet.c +++ b/toxcore/events/group_custom_packet.c @@ -175,7 +175,10 @@ static Tox_Event_Group_Custom_Packet *tox_events_add_group_custom_packet(Tox_Eve event.type = TOX_EVENT_GROUP_CUSTOM_PACKET; event.data.group_custom_packet = group_custom_packet; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_custom_packet_free(group_custom_packet, mem); + return nullptr; + } return group_custom_packet; } diff --git a/toxcore/events/group_custom_private_packet.c b/toxcore/events/group_custom_private_packet.c index 751724c8ee..f7c1634120 100644 --- a/toxcore/events/group_custom_private_packet.c +++ b/toxcore/events/group_custom_private_packet.c @@ -175,7 +175,10 @@ static Tox_Event_Group_Custom_Private_Packet *tox_events_add_group_custom_privat event.type = TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET; event.data.group_custom_private_packet = group_custom_private_packet; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_custom_private_packet_free(group_custom_private_packet, mem); + return nullptr; + } return group_custom_private_packet; } diff --git a/toxcore/events/group_invite.c b/toxcore/events/group_invite.c index c2035c18d1..6372eb598c 100644 --- a/toxcore/events/group_invite.c +++ b/toxcore/events/group_invite.c @@ -203,7 +203,10 @@ static Tox_Event_Group_Invite *tox_events_add_group_invite(Tox_Events *events, c event.type = TOX_EVENT_GROUP_INVITE; event.data.group_invite = group_invite; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_invite_free(group_invite, mem); + return nullptr; + } return group_invite; } diff --git a/toxcore/events/group_join_fail.c b/toxcore/events/group_join_fail.c index b85896858b..7b95454b84 100644 --- a/toxcore/events/group_join_fail.c +++ b/toxcore/events/group_join_fail.c @@ -132,7 +132,10 @@ static Tox_Event_Group_Join_Fail *tox_events_add_group_join_fail(Tox_Events *eve event.type = TOX_EVENT_GROUP_JOIN_FAIL; event.data.group_join_fail = group_join_fail; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_join_fail_free(group_join_fail, mem); + return nullptr; + } return group_join_fail; } diff --git a/toxcore/events/group_message.c b/toxcore/events/group_message.c index 96b6bce64c..9ed07e43a6 100644 --- a/toxcore/events/group_message.c +++ b/toxcore/events/group_message.c @@ -209,7 +209,10 @@ static Tox_Event_Group_Message *tox_events_add_group_message(Tox_Events *events, event.type = TOX_EVENT_GROUP_MESSAGE; event.data.group_message = group_message; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_message_free(group_message, mem); + return nullptr; + } return group_message; } diff --git a/toxcore/events/group_moderation.c b/toxcore/events/group_moderation.c index ba510d5b2a..eb8d3ba41e 100644 --- a/toxcore/events/group_moderation.c +++ b/toxcore/events/group_moderation.c @@ -164,7 +164,10 @@ static Tox_Event_Group_Moderation *tox_events_add_group_moderation(Tox_Events *e event.type = TOX_EVENT_GROUP_MODERATION; event.data.group_moderation = group_moderation; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_moderation_free(group_moderation, mem); + return nullptr; + } return group_moderation; } diff --git a/toxcore/events/group_password.c b/toxcore/events/group_password.c index 2e937e9a22..14bda0f766 100644 --- a/toxcore/events/group_password.c +++ b/toxcore/events/group_password.c @@ -159,7 +159,10 @@ static Tox_Event_Group_Password *tox_events_add_group_password(Tox_Events *event event.type = TOX_EVENT_GROUP_PASSWORD; event.data.group_password = group_password; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_password_free(group_password, mem); + return nullptr; + } return group_password; } diff --git a/toxcore/events/group_peer_exit.c b/toxcore/events/group_peer_exit.c index 16d1eba7a6..405b4b6c16 100644 --- a/toxcore/events/group_peer_exit.c +++ b/toxcore/events/group_peer_exit.c @@ -237,7 +237,10 @@ static Tox_Event_Group_Peer_Exit *tox_events_add_group_peer_exit(Tox_Events *eve event.type = TOX_EVENT_GROUP_PEER_EXIT; event.data.group_peer_exit = group_peer_exit; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_peer_exit_free(group_peer_exit, mem); + return nullptr; + } return group_peer_exit; } diff --git a/toxcore/events/group_peer_join.c b/toxcore/events/group_peer_join.c index af0d006e87..8dc34befee 100644 --- a/toxcore/events/group_peer_join.c +++ b/toxcore/events/group_peer_join.c @@ -130,7 +130,10 @@ static Tox_Event_Group_Peer_Join *tox_events_add_group_peer_join(Tox_Events *eve event.type = TOX_EVENT_GROUP_PEER_JOIN; event.data.group_peer_join = group_peer_join; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_peer_join_free(group_peer_join, mem); + return nullptr; + } return group_peer_join; } diff --git a/toxcore/events/group_peer_limit.c b/toxcore/events/group_peer_limit.c index 5e2e23558c..157827c560 100644 --- a/toxcore/events/group_peer_limit.c +++ b/toxcore/events/group_peer_limit.c @@ -130,7 +130,10 @@ static Tox_Event_Group_Peer_Limit *tox_events_add_group_peer_limit(Tox_Events *e event.type = TOX_EVENT_GROUP_PEER_LIMIT; event.data.group_peer_limit = group_peer_limit; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_peer_limit_free(group_peer_limit, mem); + return nullptr; + } return group_peer_limit; } diff --git a/toxcore/events/group_peer_name.c b/toxcore/events/group_peer_name.c index 3d3722d73a..063a6ab9a3 100644 --- a/toxcore/events/group_peer_name.c +++ b/toxcore/events/group_peer_name.c @@ -175,7 +175,10 @@ static Tox_Event_Group_Peer_Name *tox_events_add_group_peer_name(Tox_Events *eve event.type = TOX_EVENT_GROUP_PEER_NAME; event.data.group_peer_name = group_peer_name; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_peer_name_free(group_peer_name, mem); + return nullptr; + } return group_peer_name; } diff --git a/toxcore/events/group_peer_status.c b/toxcore/events/group_peer_status.c index 4165d90ec2..d646caec8c 100644 --- a/toxcore/events/group_peer_status.c +++ b/toxcore/events/group_peer_status.c @@ -148,7 +148,10 @@ static Tox_Event_Group_Peer_Status *tox_events_add_group_peer_status(Tox_Events event.type = TOX_EVENT_GROUP_PEER_STATUS; event.data.group_peer_status = group_peer_status; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_peer_status_free(group_peer_status, mem); + return nullptr; + } return group_peer_status; } diff --git a/toxcore/events/group_privacy_state.c b/toxcore/events/group_privacy_state.c index 1c683c255c..3fa081c20a 100644 --- a/toxcore/events/group_privacy_state.c +++ b/toxcore/events/group_privacy_state.c @@ -132,7 +132,10 @@ static Tox_Event_Group_Privacy_State *tox_events_add_group_privacy_state(Tox_Eve event.type = TOX_EVENT_GROUP_PRIVACY_STATE; event.data.group_privacy_state = group_privacy_state; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_privacy_state_free(group_privacy_state, mem); + return nullptr; + } return group_privacy_state; } diff --git a/toxcore/events/group_private_message.c b/toxcore/events/group_private_message.c index ec40b2c18c..9b7f95aa3d 100644 --- a/toxcore/events/group_private_message.c +++ b/toxcore/events/group_private_message.c @@ -209,7 +209,10 @@ static Tox_Event_Group_Private_Message *tox_events_add_group_private_message(Tox event.type = TOX_EVENT_GROUP_PRIVATE_MESSAGE; event.data.group_private_message = group_private_message; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_private_message_free(group_private_message, mem); + return nullptr; + } return group_private_message; } diff --git a/toxcore/events/group_self_join.c b/toxcore/events/group_self_join.c index 0745e975f8..6cc3080aa6 100644 --- a/toxcore/events/group_self_join.c +++ b/toxcore/events/group_self_join.c @@ -109,7 +109,10 @@ static Tox_Event_Group_Self_Join *tox_events_add_group_self_join(Tox_Events *eve event.type = TOX_EVENT_GROUP_SELF_JOIN; event.data.group_self_join = group_self_join; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_self_join_free(group_self_join, mem); + return nullptr; + } return group_self_join; } diff --git a/toxcore/events/group_topic.c b/toxcore/events/group_topic.c index 9c95d01ae0..7588d43f7f 100644 --- a/toxcore/events/group_topic.c +++ b/toxcore/events/group_topic.c @@ -175,7 +175,10 @@ static Tox_Event_Group_Topic *tox_events_add_group_topic(Tox_Events *events, con event.type = TOX_EVENT_GROUP_TOPIC; event.data.group_topic = group_topic; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_topic_free(group_topic, mem); + return nullptr; + } return group_topic; } diff --git a/toxcore/events/group_topic_lock.c b/toxcore/events/group_topic_lock.c index 36fb49393a..431ff38159 100644 --- a/toxcore/events/group_topic_lock.c +++ b/toxcore/events/group_topic_lock.c @@ -132,7 +132,10 @@ static Tox_Event_Group_Topic_Lock *tox_events_add_group_topic_lock(Tox_Events *e event.type = TOX_EVENT_GROUP_TOPIC_LOCK; event.data.group_topic_lock = group_topic_lock; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_topic_lock_free(group_topic_lock, mem); + return nullptr; + } return group_topic_lock; } diff --git a/toxcore/events/group_voice_state.c b/toxcore/events/group_voice_state.c index fba0300389..d9c592b882 100644 --- a/toxcore/events/group_voice_state.c +++ b/toxcore/events/group_voice_state.c @@ -132,7 +132,10 @@ static Tox_Event_Group_Voice_State *tox_events_add_group_voice_state(Tox_Events event.type = TOX_EVENT_GROUP_VOICE_STATE; event.data.group_voice_state = group_voice_state; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_group_voice_state_free(group_voice_state, mem); + return nullptr; + } return group_voice_state; } diff --git a/toxcore/events/self_connection_status.c b/toxcore/events/self_connection_status.c index 8d8bc803ea..b79d70b408 100644 --- a/toxcore/events/self_connection_status.c +++ b/toxcore/events/self_connection_status.c @@ -111,7 +111,10 @@ static Tox_Event_Self_Connection_Status *tox_events_add_self_connection_status(T event.type = TOX_EVENT_SELF_CONNECTION_STATUS; event.data.self_connection_status = self_connection_status; - tox_events_add(events, &event); + if (!tox_events_add(events, &event)) { + tox_event_self_connection_status_free(self_connection_status, mem); + return nullptr; + } return self_connection_status; } diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c index 33bfa40d34..f017b08888 100644 --- a/toxcore/friend_connection.c +++ b/toxcore/friend_connection.c @@ -1032,6 +1032,11 @@ void kill_friend_connections(Friend_Connections *fr_c) kill_friend_connection(fr_c, i); } + // there might be allocated NONE connections + if (fr_c->conns != nullptr) { + free(fr_c->conns); + } + lan_discovery_kill(fr_c->broadcast); free(fr_c); } diff --git a/toxcore/group.c b/toxcore/group.c index 14e61e6ffc..3d96b962de 100644 --- a/toxcore/group.c +++ b/toxcore/group.c @@ -2520,7 +2520,7 @@ static int handle_send_peers(Group_Chats *g_c, uint32_t groupnumber, const uint8 non_null(1, 3) nullable(6) static void handle_direct_packet(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *data, uint16_t length, - int connection_index, void *userdata) + uint32_t connection_index, void *userdata) { if (length == 0) { return; @@ -2832,7 +2832,7 @@ static bool check_message_info(uint32_t message_number, uint8_t message_id, Grou non_null(1, 3) nullable(6) static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *data, uint16_t length, - int connection_index, void *userdata) + uint32_t connection_index, void *userdata) { if (length < sizeof(uint16_t) + sizeof(uint32_t) + 1) { return; diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index 03077d0806..2d64ae60ec 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c @@ -8353,7 +8353,7 @@ bool gc_group_is_valid(const GC_Chat *chat) /** Return true if `group_number` designates an active group in session `c`. */ static bool group_number_valid(const GC_Session *c, int group_number) { - if (group_number < 0 || group_number >= c->chats_index) { + if (group_number < 0 || (uint32_t)group_number >= c->chats_index) { return false; } diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index c2976f265e..1c91f6da31 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -52,7 +52,7 @@ typedef enum Crypto_Conn_State { } Crypto_Conn_State; typedef struct Crypto_Connection { - /* (Currently) all used for both non-Noise and Noise handshakes/connections */ + /* (Currently) all used for both non-Noise and Noise handshakes/connections */ uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The real public key of the peer. */ uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */ uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */ @@ -63,7 +63,7 @@ typedef struct Crypto_Connection { Crypto_Conn_State status; /* See Crypto_Conn_State documentation */ uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */ - + bool noise_handshake_enabled; /* Necessary for Noise handshake backwards compatibility */ Noise_Handshake *noise_handshake; /* NoiseIK handshake information */ uint8_t send_key[CRYPTO_SHARED_KEY_SIZE]; /* Symmetric key used to encrypt outgoing packets after NoiseIK handshake */ @@ -136,9 +136,6 @@ typedef struct Crypto_Connection { bool maximum_speed_reached; - /* Must be a pointer, because the struct is moved in memory */ - pthread_mutex_t *mutex; - dht_pk_cb *dht_pk_callback; void *dht_pk_callback_object; uint32_t dht_pk_callback_number; @@ -157,10 +154,6 @@ struct Net_Crypto { TCP_Connections *tcp_c; Crypto_Connection *crypto_connections; - pthread_mutex_t tcp_mutex; - - pthread_mutex_t connections_mutex; - unsigned int connection_use_counter; uint32_t crypto_connections_length; /* Length of connections array. */ @@ -593,7 +586,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_INITIATOR]; memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); - /* Noise: Cookie from RESPONDER */ + /* Noise: Cookie from RESPONDER */ memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); uint8_t cookie_plain[COOKIE_DATA_LENGTH]; @@ -676,7 +669,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; memcpy(handshake_payload_plain, nonce, CRYPTO_NONCE_SIZE); - /* Noise: Cookie from INITIATOR */ + /* Noise: Cookie from INITIATOR */ memcpy(handshake_payload_plain + CRYPTO_NONCE_SIZE, cookie, COOKIE_LENGTH); /* Nonce for payload encryption is _always_ 0 in case of ChaCha20-Poly1305 */ @@ -801,7 +794,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t /* es */ uint8_t noise_handshake_temp_key[CRYPTO_SHARED_KEY_SIZE]; noise_mix_key(noise_handshake->chaining_key, noise_handshake_temp_key, noise_handshake->static_private, noise_handshake->remote_ephemeral); - + /* s */ /* Nonce for static pub key decryption is _always_ 0 in case of ChaCha20-Poly1305 */ if (noise_decrypt_and_hash(noise_handshake->remote_static, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE, @@ -842,14 +835,14 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } - /* received base nonce (from INITIATOR) */ + /* received base nonce (from INITIATOR) */ memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); - /* cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ + /* cookie necessary for Noise RESPONDER, used afterwards in create_send_handshake() */ memcpy(cookie, handshake_payload_plain + CRYPTO_NONCE_SIZE + COOKIE_LENGTH, COOKIE_LENGTH); /* Noise: not necessary for Noise (=remote static), but necessary for friend_connection.c->handle_new_connections() */ //TODO: check for nullptr when called via handle_packet_crypto_hs() (not necessary there)? memcpy(peer_real_pk, noise_handshake->remote_static, CRYPTO_PUBLIC_KEY_SIZE); - /* necessary */ + /* necessary */ memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); //TODO: memzero packet, unwatend side effects? TODO: not possible currently because const // crypto_memzero(packet, length); @@ -900,7 +893,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t //TODO: Remove // bytes2string(log_temp_key, sizeof(log_temp_key), noise_handshake_temp_key, CRYPTO_SHARED_KEY_SIZE, c->log); // LOGGER_DEBUG(c->log, "INITIATOR se temp_key: %s", log_temp_key); - + /* Payload decryption */ uint8_t handshake_payload_plain[NOISE_HANDSHAKE_PAYLOAD_PLAIN_LENGTH_RESPONDER]; @@ -922,7 +915,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t return false; } - /* neccessary, base nonce (from Noise RESPONDER) */ + /* neccessary, base nonce (from Noise RESPONDER) */ memcpy(nonce, handshake_payload_plain, CRYPTO_NONCE_SIZE); /* necessary */ memcpy(dht_public_key, cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); @@ -1111,7 +1104,6 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t bool direct_send_attempt = false; - pthread_mutex_lock(conn->mutex); const IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); // TODO(irungentoo): on bad networks, direct connections might not last indefinitely. @@ -1123,11 +1115,9 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t if (direct_connected) { if ((uint32_t)sendpacket(dht_get_net(c->dht), &ip_port, data, length) == length) { - pthread_mutex_unlock(conn->mutex); return 0; } - pthread_mutex_unlock(conn->mutex); LOGGER_WARNING(c->log, "sending packet of length %d failed", length); return -1; } @@ -1144,22 +1134,12 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t } } - //TODO: remove - // LOGGER_DEBUG(c->log, "send_packet_to() => TCP"); - - pthread_mutex_unlock(conn->mutex); - pthread_mutex_lock(&c->tcp_mutex); const int ret = send_packet_tcp_connection(c->tcp_c, conn->connection_number_tcp, data, length); - pthread_mutex_unlock(&c->tcp_mutex); - - pthread_mutex_lock(conn->mutex); if (ret == 0) { conn->last_tcp_sent = current_time_monotonic(c->mono_time); } - pthread_mutex_unlock(conn->mutex); - if (direct_send_attempt) { return 0; } @@ -1525,7 +1505,6 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ return -1; } - pthread_mutex_lock(conn->mutex); const uint16_t packet_size = 1 + sizeof(uint16_t) + length + CRYPTO_MAC_SIZE; VLA(uint8_t, packet, packet_size); packet[0] = NET_PACKET_CRYPTO_DATA; @@ -1547,16 +1526,14 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ } else { /* Case non-Noise handshake */ len = encrypt_data_symmetric(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); - pthread_mutex_unlock(conn->mutex); return -1; } increment_nonce(conn->sent_nonce); - pthread_mutex_unlock(conn->mutex); return send_packet_to(c, crypt_connection_id, packet, packet_size); } @@ -1652,9 +1629,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons dt.sent_time = 0; dt.length = length; memcpy(dt.data, data, length); - pthread_mutex_lock(conn->mutex); const int64_t packet_num = add_data_end_of_buffer(c->log, c->mem, &conn->send_array, &dt); - pthread_mutex_unlock(conn->mutex); if (packet_num == -1) { return -1; @@ -1745,7 +1720,7 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint length - (1 + sizeof(uint16_t)), data); } - + //TODO: remove // LOGGER_DEBUG(c->log, "data packet decrypt len: %d", len); @@ -2046,18 +2021,7 @@ static void connection_kill(Net_Crypto *c, int crypt_connection_id, void *userda false, userdata); } - while (true) { /* TODO(irungentoo): is this really the best way to do this? */ - pthread_mutex_lock(&c->connections_mutex); - - if (c->connection_use_counter == 0) { - break; - } - - pthread_mutex_unlock(&c->connections_mutex); - } - crypto_kill(c, crypt_connection_id); - pthread_mutex_unlock(&c->connections_mutex); } /** @brief Handle a received data packet. @@ -2142,7 +2106,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const LOGGER_DEBUG(c->log, "CRYPTO_CONN_ESTABLISHED"); - /* Noise: noise_handshake not necessary anymore => memzero and free */ + /* Noise: noise_handshake not necessary anymore => memzero and free */ crypto_memzero(conn->noise_handshake, sizeof(Noise_Handshake)); mem_delete(c->mem, conn->noise_handshake); conn->noise_handshake = nullptr; @@ -2180,9 +2144,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const } while (true) { - pthread_mutex_lock(conn->mutex); const int ret = read_data_beg_buffer(c->mem, &conn->recv_array, &dt); - pthread_mutex_unlock(conn->mutex); if (ret == -1) { break; @@ -2261,7 +2223,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, return -1; } - /* Noise: only necessary if Cookie response was successful */ + /* Noise: only necessary if Cookie response was successful */ if (conn->noise_handshake_enabled && noise_handshake_init(conn->noise_handshake, c->self_secret_key, conn->public_key, true, nullptr, 0) != 0) { return -1; } @@ -2323,9 +2285,9 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const // return -1; // } - /* necessary for Noise and non-Noise */ + /* necessary for Noise and non-Noise */ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; - /* necessary for Noise RESPONDER and non-Noise */ + /* necessary for Noise RESPONDER and non-Noise */ uint8_t cookie[COOKIE_LENGTH]; if (length != HANDSHAKE_PACKET_LENGTH) { @@ -2409,7 +2371,7 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const /* non-Noise handshake */ else { LOGGER_DEBUG(c->log, "non-Noise handshake"); - /* necessary only for non-Noise */ + /* necessary only for non-Noise */ uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE]; if (!handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie, packet, length, conn->public_key, nullptr)) { @@ -2458,10 +2420,10 @@ static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const return -1; } // } - /* Backwards compatibility: necessary for non-Noise handshake */ + /* Backwards compatibility: necessary for non-Noise handshake */ encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); //TODO: why here and not before? => set before, in case of dht_pk_callback there is a new crypto connection created anyway - /* Backwards compatibility: necessary for non-Noise handshake */ + /* Backwards compatibility: necessary for non-Noise handshake */ conn->status = CRYPTO_CONN_NOT_CONFIRMED; } } else { @@ -2571,16 +2533,6 @@ static int create_crypto_connection(Net_Crypto *c) //TODO: remove LOGGER_DEBUG(c->log, "ENTERING"); - while (true) { /* TODO(irungentoo): is this really the best way to do this? */ - pthread_mutex_lock(&c->connections_mutex); - - if (c->connection_use_counter == 0) { - break; - } - - pthread_mutex_unlock(&c->connections_mutex); - } - int id = -1; for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { @@ -2603,25 +2555,10 @@ static int create_crypto_connection(Net_Crypto *c) } if (id != -1) { - pthread_mutex_t *mutex = (pthread_mutex_t *)mem_alloc(c->mem, sizeof(pthread_mutex_t)); - - if (mutex == nullptr) { - pthread_mutex_unlock(&c->connections_mutex); - return -1; - } - - if (pthread_mutex_init(mutex, nullptr) != 0) { - mem_delete(c->mem, mutex); - pthread_mutex_unlock(&c->connections_mutex); - return -1; - } - c->crypto_connections[id].noise_handshake = (Noise_Handshake *) mem_alloc(c->mem, sizeof(Noise_Handshake)); if (c->crypto_connections[id].noise_handshake == nullptr) { LOGGER_ERROR(c->log, "failed to alloc noise_handshake"); - mem_delete(c->mem, c->crypto_connections[id].mutex); - pthread_mutex_unlock(&c->connections_mutex); return -1; } @@ -2631,15 +2568,14 @@ static int create_crypto_connection(Net_Crypto *c) c->crypto_connections[id].last_packets_left_rem = 0.0; c->crypto_connections[id].packet_send_rate_requested = 0.0; c->crypto_connections[id].last_packets_left_requested_rem = 0.0; - c->crypto_connections[id].mutex = mutex; + + // TODO(Green-Sky): This enum is likely unneeded and the same as FREE. c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION; } //TODO: Remove // c->crypto_connections[id].handshake_send_interval = CRYPTO_SEND_PACKET_INTERVAL + (rand() % 800); // LOGGER_DEBUG(c->log, "handshake_send_interval: %d", c->crypto_connections[id].handshake_send_interval); - - pthread_mutex_unlock(&c->connections_mutex); return id; } @@ -2672,9 +2608,6 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) uint32_t i; - pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex); - mem_delete(c->mem, c->crypto_connections[crypt_connection_id].mutex); - /* Noise: necessary for backwards compatibility and because after CRYPTO_CONN_ESTABLISHED noise_handshake is already memzeroed/freed */ if (c->crypto_connections[crypt_connection_id].noise_handshake != nullptr) { crypto_memzero(c->crypto_connections[crypt_connection_id].noise_handshake, sizeof(Noise_Handshake)); @@ -2798,10 +2731,10 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, n_c.cookie_length = COOKIE_LENGTH; - /* Backwards comptability: Differention between non-Noise and Noise-based handshake based on received HS packet length */ + /* Backwards comptability: Differention between non-Noise and Noise-based handshake based on received HS packet length */ if (length != HANDSHAKE_PACKET_LENGTH) { //TODO: adapt static allocation? - n_c.noise_handshake = &n_c.noise_handshake_data; + n_c.noise_handshake = &n_c.noise_handshake_data; if (noise_handshake_init(n_c.noise_handshake, c->self_secret_key, nullptr, false, nullptr, 0) != 0) { crypto_memzero(n_c.noise_handshake, sizeof(Noise_Handshake)); n_c.noise_handshake = nullptr; @@ -2956,9 +2889,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) return -1; } - pthread_mutex_lock(&c->tcp_mutex); const int connection_number_tcp = new_tcp_connection_to(c->tcp_c, n_c->dht_public_key, crypt_connection_id); - pthread_mutex_unlock(&c->tcp_mutex); if (connection_number_tcp == -1) { wipe_crypto_connection(c, crypt_connection_id); @@ -2989,9 +2920,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) conn->status = CRYPTO_CONN_NOT_CONFIRMED; if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) { - pthread_mutex_lock(&c->tcp_mutex); kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - pthread_mutex_unlock(&c->tcp_mutex); wipe_crypto_connection(c, crypt_connection_id); return -1; } @@ -3004,9 +2933,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) //TODO: here correct? crypto_memzero(n_c->noise_handshake, sizeof(Noise_Handshake)); } else { - pthread_mutex_lock(&c->tcp_mutex); kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - pthread_mutex_unlock(&c->tcp_mutex); wipe_crypto_connection(c, crypt_connection_id); return -1; } @@ -3025,16 +2952,12 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c) conn->status = CRYPTO_CONN_NOT_CONFIRMED; if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) { - pthread_mutex_lock(&c->tcp_mutex); kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - pthread_mutex_unlock(&c->tcp_mutex); wipe_crypto_connection(c, crypt_connection_id); return -1; } } else { - pthread_mutex_lock(&c->tcp_mutex); kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - pthread_mutex_unlock(&c->tcp_mutex); wipe_crypto_connection(c, crypt_connection_id); return -1; } @@ -3083,9 +3006,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id]; - pthread_mutex_lock(&c->tcp_mutex); const int connection_number_tcp = new_tcp_connection_to(c->tcp_c, dht_public_key, crypt_connection_id); - pthread_mutex_unlock(&c->tcp_mutex); if (connection_number_tcp == -1) { wipe_crypto_connection(c, crypt_connection_id); @@ -3115,9 +3036,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number, conn->shared_key) != sizeof(cookie_request) || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) { - pthread_mutex_lock(&c->tcp_mutex); kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - pthread_mutex_unlock(&c->tcp_mutex); wipe_crypto_connection(c, crypt_connection_id); return -1; } @@ -3196,11 +3115,7 @@ static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_ return tcp_handle_cookie_request(c, conn->connection_number_tcp, packet, length); } - // This unlocks the mutex that at this point is locked by do_tcp before - // calling do_tcp_connections. - pthread_mutex_unlock(&c->tcp_mutex); const int ret = handle_packet_connection(c, crypt_connection_id, packet, length, false, userdata); - pthread_mutex_lock(&c->tcp_mutex); if (ret != 0) { return -1; @@ -3253,10 +3168,7 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip return -1; } - pthread_mutex_lock(&c->tcp_mutex); - const int ret = add_tcp_relay_connection(c->tcp_c, conn->connection_number_tcp, ip_port, public_key); - pthread_mutex_unlock(&c->tcp_mutex); - return ret; + return add_tcp_relay_connection(c->tcp_c, conn->connection_number_tcp, ip_port, public_key); } /** @brief Add a tcp relay to the array. @@ -3266,10 +3178,7 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip */ int add_tcp_relay(Net_Crypto *c, const IP_Port *ip_port, const uint8_t *public_key) { - pthread_mutex_lock(&c->tcp_mutex); - const int ret = add_tcp_relay_global(c->tcp_c, ip_port, public_key); - pthread_mutex_unlock(&c->tcp_mutex); - return ret; + return add_tcp_relay_global(c->tcp_c, ip_port, public_key); } /** @brief Return a random TCP connection number for use in send_tcp_onion_request. @@ -3280,13 +3189,9 @@ int add_tcp_relay(Net_Crypto *c, const IP_Port *ip_port, const uint8_t *public_k * return TCP connection number on success. * return -1 on failure. */ -int get_random_tcp_con_number(Net_Crypto *c) +int get_random_tcp_con_number(const Net_Crypto *c) { - pthread_mutex_lock(&c->tcp_mutex); - const int ret = get_random_tcp_onion_conn_number(c->tcp_c); - pthread_mutex_unlock(&c->tcp_mutex); - - return ret; + return get_random_tcp_onion_conn_number(c->tcp_c); } /** @brief Put IP_Port of a random onion TCP connection in ip_port. @@ -3294,13 +3199,9 @@ int get_random_tcp_con_number(Net_Crypto *c) * return true on success. * return false on failure. */ -bool get_random_tcp_conn_ip_port(Net_Crypto *c, IP_Port *ip_port) +bool get_random_tcp_conn_ip_port(const Net_Crypto *c, IP_Port *ip_port) { - pthread_mutex_lock(&c->tcp_mutex); - const bool ret = tcp_get_random_conn_ip_port(c->tcp_c, ip_port); - pthread_mutex_unlock(&c->tcp_mutex); - - return ret; + return tcp_get_random_conn_ip_port(c->tcp_c, ip_port); } /** @brief Send an onion packet via the TCP relay corresponding to tcp_connections_number. @@ -3310,11 +3211,7 @@ bool get_random_tcp_conn_ip_port(Net_Crypto *c, IP_Port *ip_port) */ int send_tcp_onion_request(Net_Crypto *c, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length) { - pthread_mutex_lock(&c->tcp_mutex); - const int ret = tcp_send_onion_request(c->tcp_c, tcp_connections_number, data, length); - pthread_mutex_unlock(&c->tcp_mutex); - - return ret; + return tcp_send_onion_request(c->tcp_c, tcp_connections_number, data, length); } /** @@ -3329,12 +3226,8 @@ int send_tcp_forward_request(const Logger *logger, Net_Crypto *c, const IP_Port const uint8_t *chain_keys, uint16_t chain_length, const uint8_t *data, uint16_t data_length) { - pthread_mutex_lock(&c->tcp_mutex); - const int ret = tcp_send_forward_request(logger, c->tcp_c, tcp_forwarder, dht_node, - chain_keys, chain_length, data, data_length); - pthread_mutex_unlock(&c->tcp_mutex); - - return ret; + return tcp_send_forward_request(logger, c->tcp_c, tcp_forwarder, dht_node, + chain_keys, chain_length, data, data_length); } /** @brief Copy a maximum of num random TCP relays we are connected to to tcp_relays. @@ -3344,38 +3237,28 @@ int send_tcp_forward_request(const Logger *logger, Net_Crypto *c, const IP_Port * return number of relays copied to tcp_relays on success. * return 0 on failure. */ -unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num) +unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num) { if (num == 0) { return 0; } - pthread_mutex_lock(&c->tcp_mutex); - const unsigned int ret = tcp_copy_connected_relays(c->tcp_c, tcp_relays, num); - pthread_mutex_unlock(&c->tcp_mutex); - - return ret; + return tcp_copy_connected_relays(c->tcp_c, tcp_relays, num); } -uint32_t copy_connected_tcp_relays_index(Net_Crypto *c, Node_format *tcp_relays, uint16_t num, uint32_t idx) +uint32_t copy_connected_tcp_relays_index(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num, uint32_t idx) { if (num == 0) { return 0; } - pthread_mutex_lock(&c->tcp_mutex); - const uint32_t ret = tcp_copy_connected_relays_index(c->tcp_c, tcp_relays, num, idx); - pthread_mutex_unlock(&c->tcp_mutex); - - return ret; + return tcp_copy_connected_relays_index(c->tcp_c, tcp_relays, num, idx); } non_null() static void do_tcp(Net_Crypto *c, void *userdata) { - pthread_mutex_lock(&c->tcp_mutex); do_tcp_connections(c->log, c->tcp_c, userdata); - pthread_mutex_unlock(&c->tcp_mutex); for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { const Crypto_Connection *conn = get_crypto_connection(c, i); @@ -3394,9 +3277,7 @@ static void do_tcp(Net_Crypto *c, void *userdata) continue; } - pthread_mutex_lock(&c->tcp_mutex); set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, !direct_connected); - pthread_mutex_unlock(&c->tcp_mutex); } } @@ -3566,16 +3447,12 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t return -1; } - pthread_mutex_lock(conn->mutex); - if (net_family_is_ipv4(source->ip.family)) { conn->direct_lastrecv_timev4 = mono_time_get(c->mono_time); } else { conn->direct_lastrecv_timev6 = mono_time_get(c->mono_time); } - pthread_mutex_unlock(conn->mutex); - return 0; } @@ -3989,26 +3866,16 @@ int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t return -1; } - pthread_mutex_lock(&c->connections_mutex); - ++c->connection_use_counter; - pthread_mutex_unlock(&c->connections_mutex); - Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); int ret = -1; if (conn != nullptr) { - pthread_mutex_lock(conn->mutex); const uint32_t buffer_start = conn->recv_array.buffer_start; const uint32_t buffer_end = conn->send_array.buffer_end; - pthread_mutex_unlock(conn->mutex); ret = send_data_packet_helper(c, crypt_connection_id, buffer_start, buffer_end, data, length); } - pthread_mutex_lock(&c->connections_mutex); - --c->connection_use_counter; - pthread_mutex_unlock(&c->connections_mutex); - return ret; } @@ -4030,9 +3897,7 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id) send_kill_packet(c, crypt_connection_id); } - pthread_mutex_lock(&c->tcp_mutex); kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); - pthread_mutex_unlock(&c->tcp_mutex); bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv4, crypt_connection_id); bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv6, crypt_connection_id); @@ -4134,13 +3999,6 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r /* Sets backwards compatibility to non-Noise handshake to true or false */ temp->noise_compatibility_enabled = noise_compatibility_enabled; - if (create_recursive_mutex(&temp->tcp_mutex) != 0 || - pthread_mutex_init(&temp->connections_mutex, nullptr) != 0) { - kill_tcp_connections(temp->tcp_c); - mem_delete(mem, temp); - return nullptr; - } - temp->dht = dht; new_keys(temp); @@ -4221,9 +4079,6 @@ void kill_net_crypto(Net_Crypto *c) crypto_kill(c, i); } - pthread_mutex_destroy(&c->tcp_mutex); - pthread_mutex_destroy(&c->connections_mutex); - kill_tcp_connections(c->tcp_c); bs_list_free(&c->ip_port_list); networking_registerhandler(dht_get_net(c->dht), NET_PACKET_COOKIE_REQUEST, nullptr, nullptr); diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index b185881b8d..3a9c7b78b7 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -40,7 +40,6 @@ /** Packets in this range are reserved for AV use. */ #define PACKET_ID_RANGE_LOSSY_START 192 #define PACKET_ID_RANGE_LOSSY_AV_START 192 -#define PACKET_ID_RANGE_LOSSY_AV_SIZE 8 #define PACKET_ID_RANGE_LOSSY_AV_END 199 /** Packets in this range can be used for anything. */ #define PACKET_ID_RANGE_LOSSY_CUSTOM_START 200 @@ -322,7 +321,7 @@ int add_tcp_relay(Net_Crypto *c, const IP_Port *ip_port, const uint8_t *public_k * return -1 on failure. */ non_null() -int get_random_tcp_con_number(Net_Crypto *c); +int get_random_tcp_con_number(const Net_Crypto *c); /** @brief Put IP_Port of a random onion TCP connection in ip_port. * @@ -330,7 +329,7 @@ int get_random_tcp_con_number(Net_Crypto *c); * return false on failure. */ non_null() -bool get_random_tcp_conn_ip_port(Net_Crypto *c, IP_Port *ip_port); +bool get_random_tcp_conn_ip_port(const Net_Crypto *c, IP_Port *ip_port); /** @brief Send an onion packet via the TCP relay corresponding to tcp_connections_number. * @@ -362,7 +361,7 @@ int send_tcp_forward_request(const Logger *logger, Net_Crypto *c, const IP_Port * return 0 on failure. */ non_null() -unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num); +unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num); /** * Copy a maximum of `max_num` TCP relays we are connected to starting at the index in the TCP relay array @@ -371,7 +370,7 @@ unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, u * Returns the number of relays successfully copied. */ non_null() -uint32_t copy_connected_tcp_relays_index(Net_Crypto *c, Node_format *tcp_relays, uint16_t num, uint32_t idx); +uint32_t copy_connected_tcp_relays_index(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num, uint32_t idx); /** @brief Kill a crypto connection. * diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index 9b0ac96102..326575963b 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -955,7 +955,7 @@ static int handle_announce_response(void *object, const IP_Port *source, const u } uint8_t plain[1 + ONION_PING_ID_SIZE + ONION_ANNOUNCE_RESPONSE_MAX_SIZE - ONION_ANNOUNCE_RESPONSE_MIN_SIZE]; - const int plain_size = 1 + ONION_PING_ID_SIZE + length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE; + const uint32_t plain_size = 1 + ONION_PING_ID_SIZE + length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE; int len; const uint16_t nonce_start = 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH; const uint16_t ciphertext_start = nonce_start + CRYPTO_NONCE_SIZE; diff --git a/toxcore/tox.c b/toxcore/tox.c index c6a4e99bce..8c1c2a2a24 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -1059,7 +1059,7 @@ void tox_kill(Tox *tox) } tox_lock(tox); - LOGGER_ASSERT(tox->m->log, tox->m->msi_packet == nullptr, "Attempted to kill tox while toxav is still alive"); + LOGGER_ASSERT(tox->m->log, tox->toxav_object == nullptr, "Attempted to kill tox while toxav is still alive"); kill_groupchats(tox->m->conferences_object); kill_messenger(tox->m); mono_time_free(tox->sys.mem, tox->mono_time); @@ -2552,6 +2552,12 @@ uint32_t tox_conference_join(Tox *tox, uint32_t friend_number, const uint8_t *co Tox_Err_Conference_Join *error) { assert(tox != nullptr); + + if (cookie == nullptr) { + SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_JOIN_NULL); + return UINT32_MAX; + } + tox_lock(tox); const int ret = join_groupchat(tox->m->conferences_object, friend_number, GROUPCHAT_TYPE_TEXT, cookie, length); tox_unlock(tox); @@ -4264,6 +4270,11 @@ uint32_t tox_group_invite_accept(Tox *tox, uint32_t friend_number, const uint8_t { assert(tox != nullptr); + if (invite_data == nullptr || name == nullptr) { + SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_INVITE_ACCEPT_NULL); + return UINT32_MAX; + } + tox_lock(tox); const int ret = gc_accept_invite(tox->m->group_handler, friend_number, invite_data, length, name, name_length, password, password_length); diff --git a/toxcore/tox.h b/toxcore/tox.h index aa75201284..88e460135c 100644 --- a/toxcore/tox.h +++ b/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); @@ -2905,6 +2905,11 @@ typedef enum Tox_Err_Conference_Join { */ TOX_ERR_CONFERENCE_JOIN_FAIL_SEND, + /** + * The cookie passed was NULL. + */ + TOX_ERR_CONFERENCE_JOIN_NULL, + } Tox_Err_Conference_Join; const char *tox_err_conference_join_to_string(Tox_Err_Conference_Join value); @@ -3230,9 +3235,9 @@ typedef enum Tox_Err_Friend_Custom_Packet { TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_CONNECTED, /** - * The first byte of data was not in the specified range for the packet - * type. This range is 192-254 for lossy, and 69, 160-191 for lossless - * packets. + * The first byte of data was not one of the permitted values; + * for lossy packets the first byte must be in the range 192-254, + * and for lossless packets it must be either 69 or in the range 160-191. */ TOX_ERR_FRIEND_CUSTOM_PACKET_INVALID, @@ -3283,7 +3288,7 @@ bool tox_friend_send_lossy_packet( /** * @brief Send a custom lossless packet to a friend. * - * The first byte of data must be in the range 69, 160-191. Maximum length of a + * The first byte of data must be either 69 or in the range 160-191. Maximum length of a * custom packet is TOX_MAX_CUSTOM_PACKET_SIZE. * * Lossless packet behaviour is comparable to TCP (reliability, arrive in order) @@ -3302,6 +3307,9 @@ bool tox_friend_send_lossless_packet( Tox_Err_Friend_Custom_Packet *error); /** + * tox_callback_friend_lossy_packet is the compatibility function to + * set the callback for all packet IDs except those reserved for ToxAV. + * * @param friend_number The friend number of the friend who sent a lossy packet. * @param data A byte array containing the received packet data. * @param length The length of the packet data byte array. @@ -5006,6 +5014,11 @@ typedef enum Tox_Err_Group_Invite_Accept { */ TOX_ERR_GROUP_INVITE_ACCEPT_FAIL_SEND, + /** + * Invite data or name is NULL. + */ + TOX_ERR_GROUP_INVITE_ACCEPT_NULL, + } Tox_Err_Group_Invite_Accept; const char *tox_err_group_invite_accept_to_string(Tox_Err_Group_Invite_Accept value); diff --git a/toxcore/tox_api.c b/toxcore/tox_api.c index 375bc792c2..3cf7a1e213 100644 --- a/toxcore/tox_api.c +++ b/toxcore/tox_api.c @@ -897,6 +897,9 @@ const char *tox_err_conference_join_to_string(Tox_Err_Conference_Join value) case TOX_ERR_CONFERENCE_JOIN_FAIL_SEND: return "TOX_ERR_CONFERENCE_JOIN_FAIL_SEND"; + + case TOX_ERR_CONFERENCE_JOIN_NULL: + return "TOX_ERR_CONFERENCE_JOIN_NULL"; } return ""; @@ -1458,6 +1461,9 @@ const char *tox_err_group_invite_accept_to_string(Tox_Err_Group_Invite_Accept va case TOX_ERR_GROUP_INVITE_ACCEPT_FAIL_SEND: return "TOX_ERR_GROUP_INVITE_ACCEPT_FAIL_SEND"; + + case TOX_ERR_GROUP_INVITE_ACCEPT_NULL: + return "TOX_ERR_GROUP_INVITE_ACCEPT_NULL"; } return ""; diff --git a/toxcore/tox_private.h b/toxcore/tox_private.h index fe86479a5d..c872bfea47 100644 --- a/toxcore/tox_private.h +++ b/toxcore/tox_private.h @@ -155,17 +155,15 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip const uint8_t *target_public_key, Tox_Err_Dht_Get_Nodes *error); /** - * This function returns the ratio of close dht nodes that are known to support - * announce/store. This function returns the number of DHT nodes in the - * closelist. + * This function returns the number of DHT nodes in the closelist. * * @return number */ uint16_t tox_dht_get_num_closelist(const Tox *tox); /** - * This function returns the number of DHT nodes in the closelist, - * that are capable to store announce data (introduced in version 0.2.18). + * This function returns the number of DHT nodes in the closelist + * that are capable of storing announce data (introduced in version 0.2.18). * * @return number */ diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c index f3b88770c1..b785c26732 100644 --- a/toxencryptsave/toxencryptsave.c +++ b/toxencryptsave/toxencryptsave.c @@ -231,8 +231,8 @@ bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t plaintext[], si ciphertext += crypto_box_NONCEBYTES; /* now encrypt */ - if (encrypt_data_symmetric(key->key, nonce, plaintext, plaintext_len, ciphertext) - != plaintext_len + crypto_box_MACBYTES) { + const int32_t encrypted_len = encrypt_data_symmetric(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,8 +316,8 @@ bool tox_pass_key_decrypt(const Tox_Pass_Key *key, const uint8_t ciphertext[], s ciphertext += crypto_box_NONCEBYTES; /* decrypt the ciphertext */ - if (decrypt_data_symmetric(key->key, nonce, ciphertext, decrypt_length + crypto_box_MACBYTES, plaintext) - != decrypt_length) { + const int32_t decrypted_len = decrypt_data_symmetric(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; }