Compare commits

..

28 Commits

Author SHA1 Message Date
037ae18d53 indicate have all on ft 2024-12-12 01:05:14 +01:00
9ab3e84433 fix bad cherry-pick 2024-12-04 11:57:06 +01:00
03633e41a2 Merge commit 'ff3512a77e6690b0fa2bdaf691cca5317eb32367' into net_prof 2024-12-04 11:41:10 +01:00
ff3512a77e Squashed 'external/toxcore/c-toxcore/' changes from 55752a2e2ef..f785959eace
f785959eace chore: add to_string functions for netprof enums
a95b7957288 cleanup: Heap allocate network profile objects
a3c80149edd feat: Implement Tox network profiler
ac812871a2e feat: implement the last 2 missing network struct functions and make use of them
29d1043be0b test: friend request test now tests min/max message sizes
93aafd78c1f fix: friend requests with very long messages are no longer dropped
819aa2b2618 feat: Add option to disable DNS lookups in toxcore.
0ac23cee035 fix: windows use of REUSEADDR
7d2811d302d chore(ci): make bazel server shutdown faster
1dc399ba20d chore: Use vcpkg instead of conan in the MSVC build.
14d823165d9 chore: Migrate to conan 2.
bdd17c16787 cleanup: Allocate logger using tox memory allocator.
b396c061515 chore(deps): bump third_party/cmp from `2ac6bca` to `52bfcfa`
2e94da60d09 feat(net): add missing connect to network struct
41fb1839c7b chore: Add check to ensure version numbers agree.
934a8301113 chore: Release 0.2.20
3acef4bf044 fix: Add missing free in dht_get_nodes_response event.

git-subtree-dir: external/toxcore/c-toxcore
git-subtree-split: f785959eacebc59590f756b133b52601c335a1d1
2024-12-04 11:41:10 +01:00
1679883328 netprof privapi + ui (wip histograms) 2024-12-04 11:32:46 +01:00
c68a9a2245 improve tox joining code and add 2 common groups to join
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-12-02 00:51:00 +01:00
1a12447804 more allocation optimizations
Some checks are pending
ContinuousDelivery / linux-ubuntu (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / linux (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
2024-12-01 12:52:39 +01:00
02600a3bc6 fix taking as copy instead of ref
Some checks are pending
ContinuousDelivery / linux-ubuntu (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / linux (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
major cause for temporary allocations
2024-11-30 16:01:29 +01:00
1faa7e5510 light cg reformatting 2024-11-29 19:25:45 +01:00
a0cc3c3fe7 fix webp encoder memory leak 2024-11-29 18:34:44 +01:00
f97134b841 compress debug info on *ix systems in cd
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
100mib -> 40mib
2024-11-20 12:57:05 +01:00
8777539c2c add download priority (does not seem to work yet) 2024-11-20 12:55:46 +01:00
5708a83ba6 ft duration human readable
Some checks are pending
ContinuousDelivery / linux-ubuntu (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / linux (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
lower video bitrate to 1400kbits
2024-11-19 17:28:02 +01:00
2d54a3111c update SDL 2024-11-15 23:17:32 +01:00
1cd1390901 windows breakpad 2024-11-15 16:25:32 +01:00
3fbbf80e8c enable breakpad in cd on linux 2024-11-15 12:04:01 +01:00
281e681bf8 add breakpad support on linux 2024-11-15 12:04:01 +01:00
9277ef34f6 change some labels and display tox status in main menu bar
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
based on user feedback
2024-11-15 00:07:15 +01:00
9bf9753bd1 remove video bitrate hack following toxcore fix
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-11-09 14:21:24 +01:00
cae0ab9c5c Squashed 'external/toxcore/c-toxcore/' changes from 03e9fbf3703..55752a2e2ef
55752a2e2ef fix(toxav): pass video bit rate as kbit Previously we unintentionally made it Mbit.
7e573280a75 docs(toxav): fix docs of toxav.h - fix units to be more readable - use width before height consistently - video -> audio typo
5f88a084e8c fix: friend_connections leak on allocation failure clean up when it only contains connections in the NONE state
6d27a1ae178 fix: wrong comment for closelist
ce4f29e8036 cleanup: Fix all `-Wsign-compare` warnings.
4d4251c397f chore: lower cirrus ci timeout drastically
40676284507 fix: events leak that can occur if allocation fails rare in practice, found by fuzzing
9610ac31c5f fix: Return an error instead of crashing on nullptr args in NGC.
a57c2c8f956 refactor: Make ToxAV independent of toxcore internals.
5752fc29f86 refactor: Make tox-bootstrapd use bool instead of int
df675786eb2 chore: Add release-drafter github action.
03fd7a69dcf chore: Use toktok's cmp instead of upstream.
350c0ba1205 cleanup: Sort apk/apt install commands in Dockerfiles.
8c1bda502cb chore(deps): bump golang.org/x/net
ddb9d3210da chore: Upgrade to FreeBSD 14.1 in cirrus build.
e9076f45bd3 chore(cmake): set options changes as cache and with force

git-subtree-dir: external/toxcore/c-toxcore
git-subtree-split: 55752a2e2ef894bfa6d7a2a21a0278e3f2bede7d
2024-11-09 13:44:30 +01:00
326d72a965 update toxcore, toxav fixes merged
Some checks are pending
ContinuousDelivery / linux-ubuntu (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / linux (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
Merge commit 'cae0ab9c5c75eda665d21dc36cfeef48c1e04b53'
2024-11-09 13:44:30 +01:00
765340a727 update to new tox interface
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-11-06 10:52:33 +01:00
72d3575670 more human readable
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-10-28 23:17:52 +01:00
31352ed06a forgot to write id
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-10-27 15:32:04 +01:00
2d96139d4a prep message serl for file objects
Some checks are pending
ContinuousDelivery / linux-ubuntu (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / linux (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
2024-10-27 15:09:06 +01:00
92740c8dbe use sr
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-10-25 13:46:00 +02:00
a9d8c070bc enable arm32 in the ci/cd
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-10-19 11:24:09 +02:00
f93602e524 update sdl to latest
Some checks are pending
ContinuousDelivery / linux-ubuntu (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / linux (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
2024-10-18 17:46:52 +02:00
193 changed files with 3986 additions and 1824 deletions

View File

@ -25,7 +25,7 @@ jobs:
run: sudo apt update && sudo apt -y install libsodium-dev cmake libvpx-dev libopus-dev run: sudo apt update && sudo apt -y install libsodium-dev cmake libvpx-dev libopus-dev
- name: Configure CMake - name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DTOMATO_TOX_AV=ON run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DTOMATO_BREAKPAD=ON -DTOMATO_TOX_AV=ON -DCMAKE_EXE_LINKER_FLAGS=-gz
- name: Build - name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato
@ -64,6 +64,8 @@ jobs:
strategy: strategy:
matrix: matrix:
platform: platform:
- vcpkg_toolkit: arm-neon-android
ndk_abi: armeabi-v7a
- vcpkg_toolkit: arm64-android - vcpkg_toolkit: arm64-android
ndk_abi: arm64-v8a ndk_abi: arm64-v8a
- vcpkg_toolkit: x64-android - vcpkg_toolkit: x64-android
@ -101,7 +103,7 @@ jobs:
- name: Configure CMake - name: Configure CMake
env: env:
ANDROID_NDK_HOME: ${{steps.setup_ndk.outputs.ndk-path}} ANDROID_NDK_HOME: ${{steps.setup_ndk.outputs.ndk-path}}
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=${{matrix.platform.vcpkg_toolkit}} -DANDROID=1 -DANDROID_PLATFORM=23 -DANDROID_ABI=${{matrix.platform.ndk_abi}} -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{steps.setup_ndk.outputs.ndk-path}}/build/cmake/android.toolchain.cmake -DSDLIMAGE_JPG_SHARED=OFF -DSDLIMAGE_PNG_SHARED=OFF -DTOMATO_MAIN_SO=ON -DTOMATO_TOX_AV=ON run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=${{matrix.platform.vcpkg_toolkit}} -DANDROID=1 -DANDROID_PLATFORM=23 -DANDROID_ABI=${{matrix.platform.ndk_abi}} -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{steps.setup_ndk.outputs.ndk-path}}/build/cmake/android.toolchain.cmake -DSDLIMAGE_JPG_SHARED=OFF -DSDLIMAGE_PNG_SHARED=OFF -DTOMATO_MAIN_SO=ON -DTOMATO_TOX_AV=ON -DCMAKE_EXE_LINKER_FLAGS=-gz
- name: Build (tomato) - name: Build (tomato)
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato
@ -164,7 +166,7 @@ jobs:
#- uses: ilammy/setup-nasm@v1 #- uses: ilammy/setup-nasm@v1
- name: Configure CMake - name: Configure CMake
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DSDLIMAGE_VENDORED=ON -DSDLIMAGE_DEPS_SHARED=ON -DSDLIMAGE_JXL=OFF -DSDLIMAGE_AVIF=OFF -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe -DTOMATO_TOX_AV=ON run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DSDLIMAGE_VENDORED=ON -DSDLIMAGE_DEPS_SHARED=ON -DSDLIMAGE_JXL=OFF -DSDLIMAGE_AVIF=OFF -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe -DTOMATO_BREAKPAD=ON -DTOMATO_TOX_AV=ON
- name: Build - name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -t tomato run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -t tomato

View File

@ -38,6 +38,8 @@ jobs:
strategy: strategy:
matrix: matrix:
platform: platform:
- vcpkg_toolkit: arm-neon-android
ndk_abi: armeabi-v7a
- vcpkg_toolkit: arm64-android - vcpkg_toolkit: arm64-android
ndk_abi: arm64-v8a ndk_abi: arm64-v8a
- vcpkg_toolkit: x64-android - vcpkg_toolkit: x64-android
@ -59,9 +61,9 @@ jobs:
distribution: 'temurin' distribution: 'temurin'
java-version: '17' java-version: '17'
- name: update vcpkg #- name: update vcpkg
run: | # run: |
git clone https://github.com/microsoft/vcpkg.git # git clone https://github.com/microsoft/vcpkg.git
- name: Install Dependencies (host) - name: Install Dependencies (host)
run: sudo apt update && sudo apt -y install cmake pkg-config nasm run: sudo apt update && sudo apt -y install cmake pkg-config nasm
@ -69,7 +71,8 @@ jobs:
- name: Install Dependencies (target) - name: Install Dependencies (target)
env: env:
ANDROID_NDK_HOME: ${{steps.setup_ndk.outputs.ndk-path}} ANDROID_NDK_HOME: ${{steps.setup_ndk.outputs.ndk-path}}
run: vcpkg install --triplet ${{matrix.platform.vcpkg_toolkit}} --overlay-ports=vcpkg/ports libsodium opus libvpx libpng libjpeg-turbo #run: vcpkg install --triplet ${{matrix.platform.vcpkg_toolkit}} --overlay-ports=vcpkg/ports libsodium opus libvpx libpng libjpeg-turbo
run: vcpkg install --triplet ${{matrix.platform.vcpkg_toolkit}} libsodium opus libvpx libpng libjpeg-turbo
# vcpkg scripts root /usr/local/share/vcpkg/scripts # vcpkg scripts root /usr/local/share/vcpkg/scripts
- name: Configure CMake - name: Configure CMake

View File

@ -20,9 +20,9 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
option(TOMATO_MAIN_SO "Build tomato as a shared object (for eg android apps)" ANDROID) option(TOMATO_MAIN_SO "Build tomato as a shared object (for eg android apps)" ANDROID)
option(TOMATO_ASAN "Build tomato with asan (gcc/clang/msvc)" OFF) option(TOMATO_ASAN "Build tomato with asan (gcc/clang/msvc)" OFF)
option(TOMATO_BREAKPAD "Build tomato with breakpad crash dumping" OFF)
option(TOMATO_TOX_AV "Build tomato with ToxAV" OFF) option(TOMATO_TOX_AV "Build tomato with ToxAV" OFF)
message("II TOMATO_TOX_AV: ${TOMATO_TOX_AV}")
if (TOMATO_ASAN) if (TOMATO_ASAN)
if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
@ -43,6 +43,17 @@ if (TOMATO_ASAN)
endif() endif()
endif() endif()
message("II TOMATO_BREAKPAD: ${TOMATO_BREAKPAD}")
if (TOMATO_BREAKPAD)
if (LINUX) # TODO: test if android
# HACK: workaround an ugly cmake bug,
# where subdirs can now propergate enable_language upwards
enable_language(ASM)
endif()
endif()
message("II TOMATO_TOX_AV: ${TOMATO_TOX_AV}")
# uggly, but it needs to be defined for all of tomato. # uggly, but it needs to be defined for all of tomato.
# but this also means that we can not compile tomato in the same cmake as plugins # but this also means that we can not compile tomato in the same cmake as plugins
add_compile_definitions(ENTT_API_EXPORT) add_compile_definitions(ENTT_API_EXPORT)

View File

@ -24,3 +24,7 @@ add_subdirectory(./libwebp)
add_subdirectory(./qoi) add_subdirectory(./qoi)
add_subdirectory(./sdl_image) add_subdirectory(./sdl_image)
if (TOMATO_BREAKPAD)
add_subdirectory(./breakpad)
endif()

139
external/breakpad/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,139 @@
cmake_minimum_required(VERSION 3.16...3.24 FATAL_ERROR)
include(FetchContent)
if (NOT TARGET breakpad_client)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Android")
if (NOT TARGET lss)
FetchContent_Declare(lss
GIT_REPOSITORY https://chromium.googlesource.com/linux-syscall-support/
GIT_TAG 9719c1e1e676814c456b55f5f070eabad6709d31
FIND_PACKAGE_ARGS # for the future
)
FetchContent_GetProperties(lss)
if(NOT lss_POPULATED)
FetchContent_Populate(lss)
# HACK: breakpad expects this at a specific path
configure_file(
${lss_SOURCE_DIR}/linux_syscall_support.h
${CMAKE_CURRENT_BINARY_DIR}/third_party/lss/linux_syscall_support.h
@ONLY
)
add_library(lss INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/third_party/lss/linux_syscall_support.h)
target_include_directories(lss INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
endif()
endif()
endif()
FetchContent_Declare(breakpad
GIT_REPOSITORY https://chromium.googlesource.com/breakpad/breakpad
GIT_TAG v2023.06.01
FIND_PACKAGE_ARGS # for the future
)
FetchContent_GetProperties(breakpad)
if(NOT breakpad_POPULATED)
FetchContent_Populate(breakpad)
add_library(breakpad_common STATIC
${breakpad_SOURCE_DIR}/src/common/convert_UTF.h
${breakpad_SOURCE_DIR}/src/common/convert_UTF.cc
${breakpad_SOURCE_DIR}/src/common/md5.h
${breakpad_SOURCE_DIR}/src/common/md5.cc
${breakpad_SOURCE_DIR}/src/common/string_conversion.h
${breakpad_SOURCE_DIR}/src/common/string_conversion.cc
)
target_include_directories(breakpad_common PUBLIC "${breakpad_SOURCE_DIR}/src")
if (WIN32)
target_sources(breakpad_common PUBLIC
${breakpad_SOURCE_DIR}/src/common/windows/guid_string.h
${breakpad_SOURCE_DIR}/src/common/windows/guid_string.cc
)
add_library(breakpad_client STATIC)
target_sources(breakpad_client
PUBLIC
${breakpad_SOURCE_DIR}/src/client/windows/handler/exception_handler.h
${breakpad_SOURCE_DIR}/src/client/windows/common/ipc_protocol.h
${breakpad_SOURCE_DIR}/src/client/windows/crash_generation/crash_generation_client.h
${breakpad_SOURCE_DIR}/src/client/windows/crash_generation/minidump_generator.h
PRIVATE
${breakpad_SOURCE_DIR}/src/client/windows/handler/exception_handler.cc
${breakpad_SOURCE_DIR}/src/client/windows/crash_generation/crash_generation_client.cc
${breakpad_SOURCE_DIR}/src/client/windows/crash_generation/minidump_generator.cc
)
target_compile_definitions(breakpad_client PRIVATE UNICODE)
#elseif() # TODO: mac, ios and any other platform
else() # assume linux
enable_language(ASM) # mostly to document, needs to be set in parent
target_sources(breakpad_common PUBLIC
${breakpad_SOURCE_DIR}/src/common/linux/elf_core_dump.cc
${breakpad_SOURCE_DIR}/src/common/linux/elfutils.h
${breakpad_SOURCE_DIR}/src/common/linux/elfutils.cc
${breakpad_SOURCE_DIR}/src/common/linux/file_id.h
${breakpad_SOURCE_DIR}/src/common/linux/file_id.cc
${breakpad_SOURCE_DIR}/src/common/linux/guid_creator.h
${breakpad_SOURCE_DIR}/src/common/linux/guid_creator.cc
${breakpad_SOURCE_DIR}/src/common/linux/linux_libc_support.cc
${breakpad_SOURCE_DIR}/src/common/linux/memory_mapped_file.cc
${breakpad_SOURCE_DIR}/src/common/linux/safe_readlink.cc
${breakpad_SOURCE_DIR}/src/common/linux/breakpad_getcontext.h
${breakpad_SOURCE_DIR}/src/common/linux/breakpad_getcontext.S
)
#set_property(SOURCE ${breakpad_SOURCE_DIR}/src/common/linux/breakpad_getcontext.S APPEND PROPERTY COMPILE_OPTIONS "-x" "assembler-with-cpp")
add_library(breakpad_client STATIC)
target_sources(breakpad_client
PUBLIC
${breakpad_SOURCE_DIR}/src/client/linux/handler/exception_handler.h
${breakpad_SOURCE_DIR}/src/client/linux/handler/minidump_descriptor.h
${breakpad_SOURCE_DIR}/src/client/linux/crash_generation/crash_generation_client.h
${breakpad_SOURCE_DIR}/src/client/linux/log/log.h
${breakpad_SOURCE_DIR}/src/client/linux/microdump_writer/microdump_writer.h
${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/minidump_writer.h
${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/pe_file.h
${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/pe_structs.h
${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/proc_cpuinfo_reader.h
PRIVATE
${breakpad_SOURCE_DIR}/src/client/linux/handler/exception_handler.cc
${breakpad_SOURCE_DIR}/src/client/linux/handler/minidump_descriptor.cc
${breakpad_SOURCE_DIR}/src/client/linux/crash_generation/crash_generation_client.cc
${breakpad_SOURCE_DIR}/src/client/linux/crash_generation/crash_generation_server.cc
${breakpad_SOURCE_DIR}/src/client/linux/log/log.cc
${breakpad_SOURCE_DIR}/src/client/linux/microdump_writer/microdump_writer.cc
${breakpad_SOURCE_DIR}/src/client/linux/dump_writer_common/thread_info.cc
${breakpad_SOURCE_DIR}/src/client/linux/dump_writer_common/ucontext_reader.cc
${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/minidump_writer.cc
${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/linux_core_dumper.cc
${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/linux_dumper.cc
${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/linux_ptrace_dumper.cc
${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/pe_file.cc
)
endif()
if (TARGET lss)
target_link_libraries(breakpad_common PUBLIC lss)
target_link_libraries(breakpad_client PUBLIC lss)
endif()
if (TARGET breakpad_client)
if (NOT WIN32)
target_sources(breakpad_client PUBLIC
${breakpad_SOURCE_DIR}/src/client/minidump_file_writer-inl.h
${breakpad_SOURCE_DIR}/src/client/minidump_file_writer.h
${breakpad_SOURCE_DIR}/src/client/minidump_file_writer.cc
)
endif()
target_link_libraries(breakpad_client PUBLIC breakpad_common)
target_include_directories(breakpad_client PUBLIC "${breakpad_SOURCE_DIR}/src")
target_compile_features(breakpad_client PUBLIC cxx_std_11)
endif()
endif()
#FetchContent_MakeAvailable(breakpad)
endif()

View File

@ -9,8 +9,7 @@ if (NOT TARGET SDL3::SDL3)
set(SDL_DISABLE_ANDROID_JAR OFF CACHE INTERNAL "") set(SDL_DISABLE_ANDROID_JAR OFF CACHE INTERNAL "")
FetchContent_Declare(SDL3 FetchContent_Declare(SDL3
#GIT_REPOSITORY https://github.com/libsdl-org/SDL GIT_REPOSITORY https://github.com/libsdl-org/SDL
GIT_REPOSITORY https://github.com/Semphriss/SDL
#GIT_TAG 0429f5d6a36fc35b551bcc2acd4a40c2db6dab82 # tip when looking #GIT_TAG 0429f5d6a36fc35b551bcc2acd4a40c2db6dab82 # tip when looking
#GIT_TAG 14f584a94bfd49cf1524db75bf3c419fdf9436cd # tip 26-04-2024 #GIT_TAG 14f584a94bfd49cf1524db75bf3c419fdf9436cd # tip 26-04-2024
#GIT_TAG 06d6f2cb2518622593570985589700910cf4399f # 13-05-2024 - before #GIT_TAG 06d6f2cb2518622593570985589700910cf4399f # 13-05-2024 - before
@ -27,7 +26,8 @@ if (NOT TARGET SDL3::SDL3)
#GIT_TAG 9dd8859240703d886941733ad32c1dc6f50d64f0 # tip 19-09-2024 #GIT_TAG 9dd8859240703d886941733ad32c1dc6f50d64f0 # tip 19-09-2024
#GIT_TAG afdf325fb4090e93a124519d1a3bc1fbe0ba9025 # bad #GIT_TAG afdf325fb4090e93a124519d1a3bc1fbe0ba9025 # bad
#GIT_TAG e292d1f5ace469f718d7b6b4dec8c28e37dcaa0e # tip 05-10-2024 (3.1.3) #GIT_TAG e292d1f5ace469f718d7b6b4dec8c28e37dcaa0e # tip 05-10-2024 (3.1.3)
GIT_TAG c523f0bcfeb5700ee233b7fae3c2b036822b8627 #GIT_TAG 2654d5d48b8f764148a7c246fea85b32b1133578 # tip 18-10-2024
GIT_TAG f8468d580d903e106640800034a4721aca24264c # tip 15-11-2024
FIND_PACKAGE_ARGS # for the future FIND_PACKAGE_ARGS # for the future
) )

View File

@ -4,14 +4,15 @@ version: 2
workflows: workflows:
version: 2 version: 2
program-analysis: program-analysis:
# TODO(iphydf): Re-enable tsan when it's fixed.
jobs: jobs:
# Dynamic analysis in the Bazel build # Dynamic analysis in the Bazel build
- bazel-asan - bazel-asan
- bazel-msan - bazel-msan
- bazel-tsan # - bazel-tsan
# Dynamic analysis with CMake # Dynamic analysis with CMake
- asan - asan
- tsan # - tsan
- ubsan - ubsan
# Static analysis # Static analysis
- clang-analyze - clang-analyze

View File

@ -1,5 +1,6 @@
--- ---
bazel-opt_task: bazel-opt_task:
timeout_in: 5m
container: container:
image: toxchat/toktok-stack:latest-release image: toxchat/toktok-stack:latest-release
cpu: 2 cpu: 2
@ -7,9 +8,11 @@ bazel-opt_task:
configure_script: configure_script:
- git submodule update --init --recursive - git submodule update --init --recursive
- /src/workspace/tools/inject-repo c-toxcore - /src/workspace/tools/inject-repo c-toxcore
- sed -i -e 's/build --config=remote/#&/' /src/workspace/.bazelrc.local
test_all_script: test_all_script:
- cd /src/workspace && bazel test -k - cd /src/workspace && bazel
--max_idle_secs=5
test -k
--remote_cache=http://$CIRRUS_HTTP_CACHE_HOST
--build_tag_filters=-haskell --build_tag_filters=-haskell
--test_tag_filters=-haskell --test_tag_filters=-haskell
-- --
@ -17,6 +20,7 @@ bazel-opt_task:
-//c-toxcore/auto_tests:tcp_relay_test # Cirrus doesn't allow external network connections. -//c-toxcore/auto_tests:tcp_relay_test # Cirrus doesn't allow external network connections.
bazel-dbg_task: bazel-dbg_task:
timeout_in: 5m
container: container:
image: toxchat/toktok-stack:latest-debug image: toxchat/toktok-stack:latest-debug
cpu: 2 cpu: 2
@ -25,15 +29,18 @@ bazel-dbg_task:
- git submodule update --init --recursive - git submodule update --init --recursive
- /src/workspace/tools/inject-repo c-toxcore - /src/workspace/tools/inject-repo c-toxcore
test_all_script: test_all_script:
- cd /src/workspace && bazel test -k - cd /src/workspace && bazel
--max_idle_secs=5
test -k
--remote_cache=http://$CIRRUS_HTTP_CACHE_HOST
--build_tag_filters=-haskell --build_tag_filters=-haskell
--test_tag_filters=-haskell --test_tag_filters=-haskell
--remote_http_cache=http://$CIRRUS_HTTP_CACHE_HOST
-- --
//c-toxcore/... //c-toxcore/...
-//c-toxcore/auto_tests:tcp_relay_test # Cirrus doesn't allow external network connections. -//c-toxcore/auto_tests:tcp_relay_test # Cirrus doesn't allow external network connections.
cimple_task: cimple_task:
timeout_in: 5m
container: container:
image: toxchat/toktok-stack:latest-release image: toxchat/toktok-stack:latest-release
cpu: 2 cpu: 2
@ -41,17 +48,20 @@ cimple_task:
configure_script: configure_script:
- git submodule update --init --recursive - git submodule update --init --recursive
- /src/workspace/tools/inject-repo c-toxcore - /src/workspace/tools/inject-repo c-toxcore
- sed -i -e 's/build --config=remote/#&/' /src/workspace/.bazelrc.local
test_all_script: test_all_script:
- cd /src/workspace && bazel test -k - cd /src/workspace && bazel
--max_idle_secs=5
test -k
--remote_cache=http://$CIRRUS_HTTP_CACHE_HOST
--build_tag_filters=haskell --build_tag_filters=haskell
--test_tag_filters=haskell --test_tag_filters=haskell
-- --
//c-toxcore/... //c-toxcore/...
freebsd_task: freebsd_task:
timeout_in: 5m
freebsd_instance: freebsd_instance:
image_family: freebsd-14-0 image_family: freebsd-14-1
configure_script: configure_script:
- PAGER=cat ASSUME_ALWAYS_YES=YES pkg install - PAGER=cat ASSUME_ALWAYS_YES=YES pkg install
cmake cmake

View File

@ -36,9 +36,6 @@ add_flag -Wno-padded
# This warns on things like _XOPEN_SOURCE, which we currently need (we # This warns on things like _XOPEN_SOURCE, which we currently need (we
# probably won't need these in the future). # probably won't need these in the future).
add_flag -Wno-reserved-id-macro 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 # We don't want to have default cases, we want to explicitly define all cases
add_flag -Wno-switch-default add_flag -Wno-switch-default
# __attribute__((nonnull)) causes this warning on defensive null checks. # __attribute__((nonnull)) causes this warning on defensive null checks.

View File

@ -47,8 +47,7 @@ add_flag -Wunused-value
# struct Foo foo = {0}; is a common idiom. # struct Foo foo = {0}; is a common idiom.
add_flag -Wno-missing-field-initializers add_flag -Wno-missing-field-initializers
# TODO(iphydf): Clean these up. They are likely not bugs, but still # Checked by clang, but gcc is warning when it's not necessary.
# potential issues and probably confusing.
add_flag -Wno-sign-compare add_flag -Wno-sign-compare
# File transfer code has this. # File transfer code has this.
add_flag -Wno-type-limits add_flag -Wno-type-limits

View File

@ -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

View File

@ -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

View File

@ -36,6 +36,7 @@ testing/data
# Vim # Vim
*.swp *.swp
*.nvimlog
# Object files # Object files
*.o *.o

View File

@ -1,3 +1,3 @@
[submodule "third_party/cmp"] [submodule "third_party/cmp"]
path = third_party/cmp path = third_party/cmp
url = https://github.com/camgunz/cmp url = https://github.com/TokTok/cmp

View File

@ -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 ## v0.2.19
### Merged PRs: ### Merged PRs:
@ -30,6 +60,7 @@
- [#2697](https://github.com/TokTok/c-toxcore/pull/2697) test: Build toxcore on NetBSD (VM). - [#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 - [#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. - [#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. - [#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. - [#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 - [#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 - [#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 - [#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 - [#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 - [#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 - [#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 - [#2335](https://github.com/TokTok/c-toxcore/issues/2335) ipv6 disabled on kernel cmdline disrupts Tox = most tests fail

View File

@ -44,7 +44,7 @@ set_source_files_properties(
# versions in a synchronised way. # versions in a synchronised way.
set(PROJECT_VERSION_MAJOR "0") set(PROJECT_VERSION_MAJOR "0")
set(PROJECT_VERSION_MINOR "2") 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(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
# set .so library version / following libtool scheme # 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) option(BOOTSTRAP_DAEMON "Enable building of tox-bootstrapd" ON)
if(BOOTSTRAP_DAEMON AND WIN32) if(BOOTSTRAP_DAEMON AND WIN32)
message(WARNING "Building tox-bootstrapd for Windows is not supported, disabling") message(WARNING "Building tox-bootstrapd for Windows is not supported, disabling")
set(BOOTSTRAP_DAEMON OFF) set(BOOTSTRAP_DAEMON OFF CACHE BOOL "" FORCE)
endif() endif()
option(BUILD_FUZZ_TESTS "Build fuzzing harnesses" OFF) option(BUILD_FUZZ_TESTS "Build fuzzing harnesses" OFF)
@ -177,6 +177,7 @@ include(Dependencies)
if(MUST_BUILD_TOXAV) if(MUST_BUILD_TOXAV)
set(NO_TOXAV_ERROR_TYPE SEND_ERROR) set(NO_TOXAV_ERROR_TYPE SEND_ERROR)
set(BUILD_TOXAV ON CACHE BOOL "" FORCE)
else() else()
set(NO_TOXAV_ERROR_TYPE WARNING) set(NO_TOXAV_ERROR_TYPE WARNING)
endif() endif()
@ -184,11 +185,11 @@ endif()
if(BUILD_TOXAV) if(BUILD_TOXAV)
if(NOT OPUS_FOUND) if(NOT OPUS_FOUND)
message(${NO_TOXAV_ERROR_TYPE} "Option BUILD_TOXAV is enabled but required library OPUS was not 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() endif()
if(NOT VPX_FOUND) if(NOT VPX_FOUND)
message(${NO_TOXAV_ERROR_TYPE} "Option BUILD_TOXAV is enabled but required library VPX was not 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()
endif() endif()
@ -308,6 +309,8 @@ set(toxcore_SOURCES
toxcore/mono_time.h toxcore/mono_time.h
toxcore/net_crypto.c toxcore/net_crypto.c
toxcore/net_crypto.h toxcore/net_crypto.h
toxcore/net_profile.c
toxcore/net_profile.h
toxcore/network.c toxcore/network.c
toxcore/network.h toxcore/network.h
toxcore/onion_announce.c toxcore/onion_announce.c
@ -351,7 +354,9 @@ set(toxcore_SOURCES
toxcore/tox_unpack.h toxcore/tox_unpack.h
toxcore/util.c toxcore/util.c
toxcore/util.h) toxcore/util.h)
if(TARGET unofficial-sodium::sodium) if(TARGET libsodium::libsodium)
set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} libsodium::libsodium)
elseif(TARGET unofficial-sodium::sodium)
set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} unofficial-sodium::sodium) set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} unofficial-sodium::sodium)
else() else()
set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} ${LIBSODIUM_LIBRARIES}) set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} ${LIBSODIUM_LIBRARIES})
@ -391,13 +396,16 @@ if(BUILD_TOXAV)
toxav/rtp.h toxav/rtp.h
toxav/toxav.c toxav/toxav.c
toxav/toxav.h toxav/toxav.h
toxav/toxav_hacks.h
toxav/toxav_old.c toxav/toxav_old.c
toxav/video.c toxav/video.c
toxav/video.h) toxav/video.h)
set(toxcore_API_HEADERS ${toxcore_API_HEADERS} set(toxcore_API_HEADERS ${toxcore_API_HEADERS}
${toxcore_SOURCE_DIR}/toxav/toxav.h^toxav) ${toxcore_SOURCE_DIR}/toxav/toxav.h^toxav)
if(MSVC) if(TARGET Opus::opus AND TARGET libvpx::libvpx)
set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} Opus::opus libvpx::libvpx)
elseif(TARGET PkgConfig::OPUS AND TARGET PkgConfig::VPX)
set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} PkgConfig::OPUS PkgConfig::VPX) set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} PkgConfig::OPUS PkgConfig::VPX)
else() else()
set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} ${OPUS_LIBRARIES} ${VPX_LIBRARIES}) set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} ${OPUS_LIBRARIES} ${VPX_LIBRARIES})
@ -450,7 +458,9 @@ if(SOCKET_LIBRARIES)
set(toxcore_PKGCONFIG_LIBS ${toxcore_PKGCONFIG_LIBS} -lsocket) set(toxcore_PKGCONFIG_LIBS ${toxcore_PKGCONFIG_LIBS} -lsocket)
endif() endif()
if(TARGET PThreads4W::PThreads4W) if(TARGET pthreads4w::pthreads4w)
set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} pthreads4w::pthreads4w)
elseif(TARGET PThreads4W::PThreads4W)
set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} PThreads4W::PThreads4W) set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} PThreads4W::PThreads4W)
elseif(TARGET Threads::Threads) elseif(TARGET Threads::Threads)
set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} Threads::Threads) set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} Threads::Threads)
@ -508,17 +518,19 @@ install_module(toxcore DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/tox)
# #
################################################################################ ################################################################################
add_library(test_util STATIC if(UNITTEST)
toxcore/DHT_test_util.cc add_library(test_util STATIC
toxcore/DHT_test_util.hh toxcore/DHT_test_util.cc
toxcore/crypto_core_test_util.cc toxcore/DHT_test_util.hh
toxcore/crypto_core_test_util.hh toxcore/crypto_core_test_util.cc
toxcore/mem_test_util.cc toxcore/crypto_core_test_util.hh
toxcore/mem_test_util.hh toxcore/mem_test_util.cc
toxcore/network_test_util.cc toxcore/mem_test_util.hh
toxcore/network_test_util.hh toxcore/network_test_util.cc
toxcore/test_util.cc toxcore/network_test_util.hh
toxcore/test_util.hh) toxcore/test_util.cc
toxcore/test_util.hh)
endif()
function(unit_test subdir target) function(unit_test subdir target)
add_executable(unit_${target}_test ${subdir}/${target}_test.cc) add_executable(unit_${target}_test ${subdir}/${target}_test.cc)
@ -528,6 +540,13 @@ function(unit_test subdir target)
else() else()
target_link_libraries(unit_${target}_test PRIVATE toxcore_shared) target_link_libraries(unit_${target}_test PRIVATE toxcore_shared)
endif() endif()
if(TARGET pthreads4w::pthreads4w)
target_link_libraries(unit_${target}_test PRIVATE pthreads4w::pthreads4w)
elseif(TARGET PThreads4W::PThreads4W)
target_link_libraries(unit_${target}_test PRIVATE PThreads4W::PThreads4W)
elseif(TARGET Threads::Threads)
target_link_libraries(unit_${target}_test PRIVATE Threads::Threads)
endif()
target_link_libraries(unit_${target}_test PRIVATE GTest::gtest GTest::gtest_main GTest::gmock) target_link_libraries(unit_${target}_test PRIVATE GTest::gtest GTest::gtest_main GTest::gmock)
set_target_properties(unit_${target}_test PROPERTIES COMPILE_FLAGS "${TEST_CXX_FLAGS}") set_target_properties(unit_${target}_test PROPERTIES COMPILE_FLAGS "${TEST_CXX_FLAGS}")
add_test(NAME ${target} COMMAND ${CROSSCOMPILING_EMULATOR} unit_${target}_test) add_test(NAME ${target} COMMAND ${CROSSCOMPILING_EMULATOR} unit_${target}_test)
@ -581,10 +600,14 @@ if(DHT_BOOTSTRAP)
target_link_libraries(DHT_bootstrap PRIVATE toxcore_shared) target_link_libraries(DHT_bootstrap PRIVATE toxcore_shared)
endif() endif()
target_link_libraries(DHT_bootstrap PRIVATE misc_tools) target_link_libraries(DHT_bootstrap PRIVATE misc_tools)
if(TARGET unofficial-sodium::sodium) if(TARGET libsodium::libsodium)
target_link_libraries(DHT_bootstrap PRIVATE libsodium::libsodium)
elseif(TARGET unofficial-sodium::sodium)
target_link_libraries(DHT_bootstrap PRIVATE unofficial-sodium::sodium) target_link_libraries(DHT_bootstrap PRIVATE unofficial-sodium::sodium)
endif() endif()
if(TARGET PThreads4W::PThreads4W) if(TARGET pthreads4w::pthreads4w)
target_link_libraries(DHT_bootstrap PRIVATE pthreads4w::pthreads4w)
elseif(TARGET PThreads4W::PThreads4W)
target_link_libraries(DHT_bootstrap PRIVATE PThreads4W::PThreads4W) target_link_libraries(DHT_bootstrap PRIVATE PThreads4W::PThreads4W)
elseif(TARGET Threads::Threads) elseif(TARGET Threads::Threads)
target_link_libraries(DHT_bootstrap PRIVATE Threads::Threads) target_link_libraries(DHT_bootstrap PRIVATE Threads::Threads)
@ -597,7 +620,7 @@ if(BOOTSTRAP_DAEMON)
add_subdirectory(other/bootstrap_daemon) add_subdirectory(other/bootstrap_daemon)
else() else()
message(WARNING "Option BOOTSTRAP_DAEMON is enabled but required library LIBCONFIG was not found.") 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()
endif() endif()

View File

@ -7,6 +7,7 @@
"cacheVariables": { "cacheVariables": {
"ENABLE_SHARED": true, "ENABLE_SHARED": true,
"ENABLE_STATIC": true, "ENABLE_STATIC": true,
"FLAT_OUTPUT_STRUCTURE": true,
"AUTOTEST": true, "AUTOTEST": true,
"BUILD_MISC_TESTS": true, "BUILD_MISC_TESTS": true,
"BOOTSTRAP_DAEMON": false, "BOOTSTRAP_DAEMON": false,
@ -17,5 +18,19 @@
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
} }
} }
],
"buildPresets": [
{
"name": "windows-default",
"configurePreset": "windows-default",
"description": "Build for Windows using default settings"
}
],
"testPresets": [
{
"name": "windows-default",
"configurePreset": "windows-default",
"description": "Run tests for Windows using default settings"
}
] ]
} }

View File

@ -9,7 +9,9 @@ if(TARGET toxcore_static)
else() else()
target_link_libraries(auto_test_support PRIVATE toxcore_shared) target_link_libraries(auto_test_support PRIVATE toxcore_shared)
endif() endif()
if(TARGET PThreads4W::PThreads4W) if(TARGET pthreads4w::pthreads4w)
target_link_libraries(auto_test_support PRIVATE pthreads4w::pthreads4w)
elseif(TARGET PThreads4W::PThreads4W)
target_link_libraries(auto_test_support PRIVATE PThreads4W::PThreads4W) target_link_libraries(auto_test_support PRIVATE PThreads4W::PThreads4W)
elseif(TARGET Threads::Threads) elseif(TARGET Threads::Threads)
target_link_libraries(auto_test_support PRIVATE Threads::Threads) target_link_libraries(auto_test_support PRIVATE Threads::Threads)
@ -23,7 +25,9 @@ function(auto_test target)
else() else()
target_link_libraries(auto_${target}_test PRIVATE toxcore_shared) target_link_libraries(auto_${target}_test PRIVATE toxcore_shared)
endif() endif()
if(TARGET PThreads4W::PThreads4W) if(TARGET pthreads4w::pthreads4w)
target_link_libraries(auto_${target}_test PRIVATE pthreads4w::pthreads4w)
elseif(TARGET PThreads4W::PThreads4W)
target_link_libraries(auto_${target}_test PRIVATE PThreads4W::PThreads4W) target_link_libraries(auto_${target}_test PRIVATE PThreads4W::PThreads4W)
elseif(TARGET Threads::Threads) elseif(TARGET Threads::Threads)
target_link_libraries(auto_${target}_test PRIVATE Threads::Threads) target_link_libraries(auto_${target}_test PRIVATE Threads::Threads)
@ -67,6 +71,7 @@ auto_test(invalid_udp_proxy)
auto_test(lan_discovery) auto_test(lan_discovery)
auto_test(lossless_packet) auto_test(lossless_packet)
auto_test(lossy_packet) auto_test(lossy_packet)
auto_test(netprof)
auto_test(network) auto_test(network)
auto_test(onion) auto_test(onion)
auto_test(overflow_recvq) auto_test(overflow_recvq)
@ -98,7 +103,10 @@ if(BUILD_TOXAV)
auto_test(toxav_basic) auto_test(toxav_basic)
auto_test(toxav_many) auto_test(toxav_many)
if(MSVC) if(TARGET libvpx::libvpx)
target_link_libraries(auto_toxav_basic_test PRIVATE libvpx::libvpx)
target_link_libraries(auto_toxav_many_test PRIVATE libvpx::libvpx)
elseif(TARGET PkgConfig::VPX)
target_link_libraries(auto_toxav_basic_test PRIVATE PkgConfig::VPX) target_link_libraries(auto_toxav_basic_test PRIVATE PkgConfig::VPX)
target_link_libraries(auto_toxav_many_test PRIVATE PkgConfig::VPX) target_link_libraries(auto_toxav_many_test PRIVATE PkgConfig::VPX)
else() else()

View File

@ -53,7 +53,7 @@ static void test_basic(void)
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new(); Logger *logger = logger_new(mem);
logger_callback_log(logger, print_debug_logger, nullptr, nullptr); logger_callback_log(logger, print_debug_logger, nullptr, nullptr);
// Attempt to create a new TCP_Server instance. // Attempt to create a new TCP_Server instance.
@ -74,7 +74,7 @@ static void test_basic(void)
for (uint8_t i = 0; i < NUM_PORTS; i++) { for (uint8_t i = 0; i < NUM_PORTS; i++) {
sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP); sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP);
localhost.port = net_htons(ports[i]); localhost.port = net_htons(ports[i]);
bool ret = net_connect(mem, logger, sock, &localhost); bool ret = net_connect(ns, mem, logger, sock, &localhost);
ck_assert_msg(ret, "Failed to connect to created TCP relay server on port %d (%d).", ports[i], errno); ck_assert_msg(ret, "Failed to connect to created TCP relay server on port %d (%d).", ports[i], errno);
// Leave open one connection for the next test. // Leave open one connection for the next test.
@ -111,12 +111,12 @@ static void test_basic(void)
// Sending the handshake // Sending the handshake
ck_assert_msg(net_send(ns, logger, sock, handshake, TCP_CLIENT_HANDSHAKE_SIZE - 1, ck_assert_msg(net_send(ns, logger, sock, handshake, TCP_CLIENT_HANDSHAKE_SIZE - 1,
&localhost) == TCP_CLIENT_HANDSHAKE_SIZE - 1, &localhost, nullptr) == TCP_CLIENT_HANDSHAKE_SIZE - 1,
"An attempt to send the initial handshake minus last byte failed."); "An attempt to send the initial handshake minus last byte failed.");
do_tcp_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost) == 1, ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost, nullptr) == 1,
"The attempt to send the last byte of handshake failed."); "The attempt to send the last byte of handshake failed.");
free(handshake); free(handshake);
@ -155,7 +155,7 @@ static void test_basic(void)
msg_length = sizeof(r_req) - i; msg_length = sizeof(r_req) - i;
} }
ck_assert_msg(net_send(ns, logger, sock, r_req + i, msg_length, &localhost) == msg_length, ck_assert_msg(net_send(ns, logger, sock, r_req + i, msg_length, &localhost, nullptr) == msg_length,
"Failed to send request after completing the handshake."); "Failed to send request after completing the handshake.");
i += msg_length; i += msg_length;
@ -213,7 +213,7 @@ static struct sec_TCP_con *new_tcp_con(const Logger *logger, const Memory *mem,
localhost.ip = get_loopback(); localhost.ip = get_loopback();
localhost.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); localhost.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
bool ok = net_connect(mem, logger, sock, &localhost); bool ok = net_connect(ns, mem, logger, sock, &localhost);
ck_assert_msg(ok, "Failed to connect to the test TCP relay server."); ck_assert_msg(ok, "Failed to connect to the test TCP relay server.");
uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE];
@ -234,12 +234,12 @@ static struct sec_TCP_con *new_tcp_con(const Logger *logger, const Memory *mem,
"Failed to encrypt the outgoing handshake."); "Failed to encrypt the outgoing handshake.");
ck_assert_msg(net_send(ns, logger, sock, handshake, TCP_CLIENT_HANDSHAKE_SIZE - 1, ck_assert_msg(net_send(ns, logger, sock, handshake, TCP_CLIENT_HANDSHAKE_SIZE - 1,
&localhost) == TCP_CLIENT_HANDSHAKE_SIZE - 1, &localhost, nullptr) == TCP_CLIENT_HANDSHAKE_SIZE - 1,
"Failed to send the first portion of the handshake to the TCP relay server."); "Failed to send the first portion of the handshake to the TCP relay server.");
do_tcp_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost) == 1, ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost, nullptr) == 1,
"Failed to send last byte of handshake."); "Failed to send last byte of handshake.");
do_tcp_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
@ -283,7 +283,7 @@ static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP
localhost.ip = get_loopback(); localhost.ip = get_loopback();
localhost.port = 0; localhost.port = 0;
ck_assert_msg(net_send(con->ns, logger, con->sock, packet, packet_size, &localhost) == packet_size, ck_assert_msg(net_send(con->ns, logger, con->sock, packet, packet_size, &localhost, nullptr) == packet_size,
"Failed to send a packet."); "Failed to send a packet.");
return 0; return 0;
} }
@ -312,7 +312,7 @@ static void test_some(void)
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new(); Logger *logger = logger_new(mem);
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
@ -506,7 +506,7 @@ static void test_client(void)
const Memory *mem = os_memory(); const Memory *mem = os_memory();
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
Logger *logger = logger_new(); Logger *logger = logger_new(mem);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
@ -524,7 +524,7 @@ static void test_client(void)
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
ip_port_tcp_s.ip = get_loopback(); ip_port_tcp_s.ip = get_loopback();
TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr); TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr, nullptr);
// TCP sockets might need a moment before they can be written to. // TCP sockets might need a moment before they can be written to.
c_sleep(50); c_sleep(50);
do_tcp_connection(logger, mono_time, conn, nullptr); do_tcp_connection(logger, mono_time, conn, nullptr);
@ -560,7 +560,7 @@ static void test_client(void)
crypto_new_keypair(rng, f2_public_key, f2_secret_key); crypto_new_keypair(rng, f2_public_key, f2_secret_key);
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
TCP_Client_Connection *conn2 = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key, TCP_Client_Connection *conn2 = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key,
f2_secret_key, nullptr); f2_secret_key, nullptr, nullptr);
c_sleep(50); c_sleep(50);
// The client should call this function (defined earlier) during the routing process. // The client should call this function (defined earlier) during the routing process.
@ -643,7 +643,7 @@ static void test_client_invalid(void)
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new(); Logger *logger = logger_new(mem);
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
@ -657,7 +657,7 @@ static void test_client_invalid(void)
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
ip_port_tcp_s.ip = get_loopback(); ip_port_tcp_s.ip = get_loopback();
TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s,
self_public_key, f_public_key, f_secret_key, nullptr); self_public_key, f_public_key, f_secret_key, nullptr, nullptr);
// Run the client's main loop but not the server. // Run the client's main loop but not the server.
mono_time_update(mono_time); mono_time_update(mono_time);
@ -721,7 +721,7 @@ static void test_tcp_connection(void)
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new(); Logger *logger = logger_new(mem);
tcp_data_callback_called = 0; tcp_data_callback_called = 0;
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
@ -834,7 +834,7 @@ static void test_tcp_connection2(void)
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new(); Logger *logger = logger_new(mem);
tcp_oobdata_callback_called = 0; tcp_oobdata_callback_called = 0;
tcp_data_callback_called = 0; tcp_data_callback_called = 0;

View File

@ -57,7 +57,7 @@ static void test_store_data(void)
const Memory *mem = os_memory(); const Memory *mem = os_memory();
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
Logger *log = logger_new(); Logger *log = logger_new(mem);
ck_assert(log != nullptr); ck_assert(log != nullptr);
logger_callback_log(log, print_debug_logger, nullptr, nullptr); logger_callback_log(log, print_debug_logger, nullptr, nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);

View File

@ -420,7 +420,7 @@ static void test_groupav(AutoTox *autotoxes)
tox_events_callback_conference_connected(autotoxes[i].dispatch, handle_conference_connected); 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"); "failed to create group");
printf("tox #%u: inviting its first friend\n", autotoxes[0].index); 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"); ck_assert_msg(tox_conference_invite(autotoxes[0].tox, 0, 0, nullptr) != 0, "failed to invite friend");

View File

@ -28,7 +28,7 @@ static void handle_conference_invite(
ck_assert_msg(!state->joined, "invitation callback generated for already joined conference"); 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; Tox_Err_Conference_Join err;
state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err); state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err);
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,

View File

@ -21,7 +21,7 @@ static void handle_conference_invite(
const uint8_t *cookie = tox_event_conference_invite_get_cookie(event); const uint8_t *cookie = tox_event_conference_invite_get_cookie(event);
const size_t length = tox_event_conference_invite_get_cookie_length(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; Tox_Err_Conference_Join err;
state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err); state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err);
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,

View File

@ -3,8 +3,6 @@
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <sodium.h>
#include "../testing/misc_tools.h" #include "../testing/misc_tools.h"
#include "../toxcore/ccompat.h" #include "../toxcore/ccompat.h"
#include "../toxcore/crypto_core.h" #include "../toxcore/crypto_core.h"
@ -14,13 +12,10 @@
#include "check_compat.h" #include "check_compat.h"
static unsigned char test_salt[TOX_PASS_SALT_LENGTH] = {0xB1, 0xC2, 0x09, 0xEE, 0x50, 0x6C, 0xF0, 0x20, 0xC4, 0xD6, 0xEB, 0xC0, 0x44, 0x51, 0x3B, 0x60, 0x4B, 0x39, 0x4A, 0xCF, 0x09, 0x53, 0x4F, 0xEA, 0x08, 0x41, 0xFA, 0xCA, 0x66, 0xD2, 0x68, 0x7F}; static unsigned char test_salt[TOX_PASS_SALT_LENGTH] = {0xB1, 0xC2, 0x09, 0xEE, 0x50, 0x6C, 0xF0, 0x20, 0xC4, 0xD6, 0xEB, 0xC0, 0x44, 0x51, 0x3B, 0x60, 0x4B, 0x39, 0x4A, 0xCF, 0x09, 0x53, 0x4F, 0xEA, 0x08, 0x41, 0xFA, 0xCA, 0x66, 0xD2, 0x68, 0x7F};
static unsigned char known_key[TOX_PASS_KEY_LENGTH] = {0x29, 0x36, 0x1c, 0x9e, 0x65, 0xbb, 0x46, 0x8b, 0xde, 0xa1, 0xac, 0xf, 0xd5, 0x11, 0x81, 0xc8, 0x29, 0x28, 0x17, 0x23, 0xa6, 0xc3, 0x6b, 0x77, 0x2e, 0xd7, 0xd3, 0x10, 0xeb, 0xd2, 0xf7, 0xc8}; static unsigned char known_key[CRYPTO_SHARED_KEY_SIZE] = {0x7a, 0xfa, 0x95, 0x45, 0x36, 0x8a, 0xa2, 0x5c, 0x40, 0xfd, 0xc0, 0xe2, 0x35, 0x8, 0x7, 0x88, 0xfa, 0xf9, 0x37, 0x86, 0xeb, 0xff, 0x50, 0x4f, 0x3, 0xe2, 0xf6, 0xd9, 0xef, 0x9, 0x17, 0x1};
static const char *pw = "hunter2"; static const char *pw = "hunter2";
static unsigned int pwlen = 7; static unsigned int pwlen = 7;
static unsigned char known_key2[CRYPTO_SHARED_KEY_SIZE] = {0x7a, 0xfa, 0x95, 0x45, 0x36, 0x8a, 0xa2, 0x5c, 0x40, 0xfd, 0xc0, 0xe2, 0x35, 0x8, 0x7, 0x88, 0xfa, 0xf9, 0x37, 0x86, 0xeb, 0xff, 0x50, 0x4f, 0x3, 0xe2, 0xf6, 0xd9, 0xef, 0x9, 0x17, 0x1};
// same as above, except standard opslimit instead of extra ops limit for test_known_kdf, and hash pw before kdf for compat
/* cause I'm shameless */ /* cause I'm shameless */
static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
{ {
@ -33,20 +28,6 @@ static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8
} }
} }
static void test_known_kdf(void)
{
unsigned char out[CRYPTO_SHARED_KEY_SIZE];
int16_t res = crypto_pwhash_scryptsalsa208sha256(out,
CRYPTO_SHARED_KEY_SIZE,
pw,
pwlen,
test_salt,
crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 8,
crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE);
ck_assert_msg(res != -1, "crypto function failed");
ck_assert_msg(memcmp(out, known_key, CRYPTO_SHARED_KEY_SIZE) == 0, "derived key is wrong");
}
static void test_save_friend(void) static void test_save_friend(void)
{ {
Tox *tox1 = tox_new_log(nullptr, nullptr, nullptr); Tox *tox1 = tox_new_log(nullptr, nullptr, nullptr);
@ -101,7 +82,7 @@ static void test_save_friend(void)
Tox_Pass_Key *key = tox_pass_key_derive((const uint8_t *)"123qweasdzxc", 12, &keyerr); Tox_Pass_Key *key = tox_pass_key_derive((const uint8_t *)"123qweasdzxc", 12, &keyerr);
ck_assert_msg(key != nullptr, "pass key allocation failure"); ck_assert_msg(key != nullptr, "pass key allocation failure");
memcpy((uint8_t *)key, test_salt, TOX_PASS_SALT_LENGTH); memcpy((uint8_t *)key, test_salt, TOX_PASS_SALT_LENGTH);
memcpy((uint8_t *)key + TOX_PASS_SALT_LENGTH, known_key2, TOX_PASS_KEY_LENGTH); memcpy((uint8_t *)key + TOX_PASS_SALT_LENGTH, known_key, TOX_PASS_KEY_LENGTH);
size2 = size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH; size2 = size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
uint8_t *encdata2 = (uint8_t *)malloc(size2); uint8_t *encdata2 = (uint8_t *)malloc(size2);
ck_assert(encdata2 != nullptr); ck_assert(encdata2 != nullptr);
@ -224,7 +205,6 @@ static void test_keys(void)
int main(void) int main(void)
{ {
setvbuf(stdout, nullptr, _IONBF, 0); setvbuf(stdout, nullptr, _IONBF, 0);
test_known_kdf();
test_save_friend(); test_save_friend();
test_keys(); test_keys();

View File

@ -112,7 +112,7 @@ static Forwarding_Subtox *new_forwarding_subtox(const Memory *mem, bool no_udp,
Forwarding_Subtox *subtox = (Forwarding_Subtox *)calloc(1, sizeof(Forwarding_Subtox)); Forwarding_Subtox *subtox = (Forwarding_Subtox *)calloc(1, sizeof(Forwarding_Subtox));
ck_assert(subtox != nullptr); ck_assert(subtox != nullptr);
subtox->log = logger_new(); subtox->log = logger_new(mem);
ck_assert(subtox->log != nullptr); ck_assert(subtox->log != nullptr);
logger_callback_log(subtox->log, print_debug_logger, nullptr, index); logger_callback_log(subtox->log, print_debug_logger, nullptr, index);
subtox->mono_time = mono_time_new(mem, nullptr, nullptr); subtox->mono_time = mono_time_new(mem, nullptr, nullptr);

View File

@ -10,44 +10,57 @@
#include "../toxcore/tox.h" #include "../toxcore/tox.h"
#include "../toxcore/util.h" #include "../toxcore/util.h"
#include "../testing/misc_tools.h" #include "../testing/misc_tools.h"
#include "auto_test_support.h" #include "auto_test_support.h"
#include "check_compat.h" #include "check_compat.h"
#define FR_MESSAGE "Gentoo" #define REQUEST_MESSAGE "Hello, I would like to be your friend. Please respond."
static void accept_friend_request(const Tox_Event_Friend_Request *event, typedef struct Callback_Data {
void *userdata) Tox *tox1; // request sender
Tox *tox2; // request receiver
uint8_t message[TOX_MAX_FRIEND_REQUEST_LENGTH];
uint16_t length;
} Callback_Data;
static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata)
{ {
Tox *state_tox = (Tox *)userdata; Callback_Data *cb_data = (Callback_Data *)userdata;
const uint8_t *public_key = tox_event_friend_request_get_public_key(event); const uint8_t *public_key = tox_event_friend_request_get_public_key(event);
const uint8_t *data = tox_event_friend_request_get_message(event); const uint8_t *data = tox_event_friend_request_get_message(event);
const size_t length = tox_event_friend_request_get_message_length(event); const size_t length = tox_event_friend_request_get_message_length(event);
ck_assert_msg(length == sizeof(FR_MESSAGE) && memcmp(FR_MESSAGE, data, sizeof(FR_MESSAGE)) == 0, ck_assert_msg(length == cb_data->length && memcmp(cb_data->message, data, cb_data->length) == 0,
"unexpected friend request message"); "unexpected friend request message");
tox_friend_add_norequest(state_tox, public_key, nullptr);
fprintf(stderr, "Tox2 accepts friend request.\n");
Tox_Err_Friend_Add err;
tox_friend_add_norequest(cb_data->tox2, public_key, &err);
ck_assert_msg(err == TOX_ERR_FRIEND_ADD_OK, "tox_friend_add_norequest failed: %d", err);
} }
static void iterate2_wait(const Tox_Dispatch *dispatch, Tox *tox1, Tox *tox2) static void iterate2_wait(const Tox_Dispatch *dispatch, Callback_Data *cb_data)
{ {
Tox_Err_Events_Iterate err; Tox_Err_Events_Iterate err;
Tox_Events *events; Tox_Events *events;
events = tox_events_iterate(tox1, true, &err); events = tox_events_iterate(cb_data->tox1, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(dispatch, events, tox1); tox_dispatch_invoke(dispatch, events, cb_data);
tox_events_free(events); tox_events_free(events);
events = tox_events_iterate(tox2, true, &err); events = tox_events_iterate(cb_data->tox2, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(dispatch, events, tox2); tox_dispatch_invoke(dispatch, events, cb_data);
tox_events_free(events); tox_events_free(events);
c_sleep(ITERATION_INTERVAL); c_sleep(ITERATION_INTERVAL);
} }
static void test_friend_request(void) static void test_friend_request(const uint8_t *message, uint16_t length)
{ {
printf("Initialising 2 toxes.\n"); printf("Initialising 2 toxes.\n");
uint32_t index[] = { 1, 2 }; uint32_t index[] = { 1, 2 };
@ -60,7 +73,7 @@ static void test_friend_request(void)
tox_events_init(tox1); tox_events_init(tox1);
tox_events_init(tox2); tox_events_init(tox2);
printf("Bootstrapping tox2 off tox1.\n"); printf("Bootstrapping Tox2 off Tox1.\n");
uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; uint8_t dht_key[TOX_PUBLIC_KEY_SIZE];
tox_self_get_dht_id(tox1, dht_key); tox_self_get_dht_id(tox1, dht_key);
const uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr); const uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr);
@ -70,25 +83,36 @@ static void test_friend_request(void)
Tox_Dispatch *dispatch = tox_dispatch_new(nullptr); Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
ck_assert(dispatch != nullptr); ck_assert(dispatch != nullptr);
Callback_Data cb_data = {nullptr};
cb_data.tox1 = tox1;
cb_data.tox2 = tox2;
ck_assert(length <= sizeof(cb_data.message));
memcpy(cb_data.message, message, length);
cb_data.length = length;
do { do {
iterate2_wait(dispatch, tox1, tox2); iterate2_wait(dispatch, &cb_data);
} while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE || } while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE ||
tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE); tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE);
printf("Toxes are online, took %lu seconds.\n", (unsigned long)(time(nullptr) - cur_time)); printf("Toxes are online, took %lu seconds.\n", (unsigned long)(time(nullptr) - cur_time));
const time_t con_time = time(nullptr); const time_t con_time = time(nullptr);
printf("Tox1 adds tox2 as friend, tox2 accepts.\n"); printf("Tox1 adds Tox2 as friend. Waiting for Tox2 to accept.\n");
tox_events_callback_friend_request(dispatch, accept_friend_request); tox_events_callback_friend_request(dispatch, accept_friend_request);
uint8_t address[TOX_ADDRESS_SIZE]; uint8_t address[TOX_ADDRESS_SIZE];
tox_self_get_address(tox2, address); tox_self_get_address(tox2, address);
const uint32_t test = tox_friend_add(tox1, address, (const uint8_t *)FR_MESSAGE, sizeof(FR_MESSAGE), nullptr); Tox_Err_Friend_Add err;
const uint32_t test = tox_friend_add(tox1, address, message, length, &err);
ck_assert_msg(err == TOX_ERR_FRIEND_ADD_OK, "tox_friend_add failed: %d", err);
ck_assert_msg(test == 0, "failed to add friend error code: %u", test); ck_assert_msg(test == 0, "failed to add friend error code: %u", test);
do { do {
iterate2_wait(dispatch, tox1, tox2); iterate2_wait(dispatch, &cb_data);
} while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP || } while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP ||
tox_friend_get_connection_status(tox2, 0, nullptr) != TOX_CONNECTION_UDP); tox_friend_get_connection_status(tox2, 0, nullptr) != TOX_CONNECTION_UDP);
@ -104,6 +128,20 @@ int main(void)
{ {
setvbuf(stdout, nullptr, _IONBF, 0); setvbuf(stdout, nullptr, _IONBF, 0);
test_friend_request(); fprintf(stderr, "Testing friend request with the smallest allowed message length.\n");
test_friend_request((const uint8_t *)"a", 1);
fprintf(stderr, "Testing friend request with an average sized message length.\n");
test_friend_request((const uint8_t *)REQUEST_MESSAGE, sizeof(REQUEST_MESSAGE) - 1);
uint8_t long_message[TOX_MAX_FRIEND_REQUEST_LENGTH];
for (uint16_t i = 0; i < sizeof(long_message); ++i) {
long_message[i] = 'a';
}
fprintf(stderr, "Testing friend request with the largest allowed message length.\n");
test_friend_request(long_message, sizeof(long_message));
return 0; return 0;
} }

View File

@ -0,0 +1,121 @@
/** Auto Tests: basic network profile functionality test (UDP only)
* TODO(JFreegman): test TCP packets as well
*/
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include "../toxcore/tox_private.h"
#include "../toxcore/util.h"
#include "auto_test_support.h"
#include "check_compat.h"
#define NUM_TOXES 2
static void test_netprof(AutoTox *autotoxes)
{
// Send some messages to create fake traffic
for (size_t i = 0; i < 256; ++i) {
for (uint32_t j = 0; j < NUM_TOXES; ++j) {
tox_friend_send_message(autotoxes[j].tox, 0, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)"test", 4, nullptr);
}
iterate_all_wait(autotoxes, NUM_TOXES, ITERATION_INTERVAL);
}
// idle traffic for a while
for (size_t i = 0; i < 100; ++i) {
iterate_all_wait(autotoxes, NUM_TOXES, ITERATION_INTERVAL);
}
const Tox *tox1 = autotoxes[0].tox;
const uint64_t UDP_count_sent1 = tox_netprof_get_packet_total_count(tox1, TOX_NETPROF_PACKET_TYPE_UDP,
TOX_NETPROF_DIRECTION_SENT);
const uint64_t UDP_count_recv1 = tox_netprof_get_packet_total_count(tox1, TOX_NETPROF_PACKET_TYPE_UDP,
TOX_NETPROF_DIRECTION_RECV);
const uint64_t TCP_count_sent1 = tox_netprof_get_packet_total_count(tox1, TOX_NETPROF_PACKET_TYPE_TCP,
TOX_NETPROF_DIRECTION_SENT);
const uint64_t TCP_count_recv1 = tox_netprof_get_packet_total_count(tox1, TOX_NETPROF_PACKET_TYPE_TCP,
TOX_NETPROF_DIRECTION_RECV);
const uint64_t UDP_bytes_sent1 = tox_netprof_get_packet_total_bytes(tox1, TOX_NETPROF_PACKET_TYPE_UDP,
TOX_NETPROF_DIRECTION_SENT);
const uint64_t UDP_bytes_recv1 = tox_netprof_get_packet_total_bytes(tox1, TOX_NETPROF_PACKET_TYPE_UDP,
TOX_NETPROF_DIRECTION_RECV);
const uint64_t TCP_bytes_sent1 = tox_netprof_get_packet_total_bytes(tox1, TOX_NETPROF_PACKET_TYPE_TCP,
TOX_NETPROF_DIRECTION_SENT);
const uint64_t TCP_bytes_recv1 = tox_netprof_get_packet_total_bytes(tox1, TOX_NETPROF_PACKET_TYPE_TCP,
TOX_NETPROF_DIRECTION_RECV);
ck_assert(UDP_count_recv1 > 0 && UDP_count_sent1 > 0);
ck_assert(UDP_bytes_recv1 > 0 && UDP_bytes_sent1 > 0);
(void)TCP_count_sent1;
(void)TCP_bytes_sent1;
(void)TCP_bytes_recv1;
(void)TCP_count_recv1;
uint64_t total_sent_count = 0;
uint64_t total_recv_count = 0;
uint64_t total_sent_bytes = 0;
uint64_t total_recv_bytes = 0;
// tox1 makes sure the sum value of all packet ID's is equal to the totals
for (size_t i = 0; i < 256; ++i) {
// this id isn't valid for UDP packets but we still want to call the
// functions and make sure they return some non-zero value
if (i == TOX_NETPROF_PACKET_ID_TCP_DATA) {
ck_assert(tox_netprof_get_packet_id_count(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_SENT) > 0);
ck_assert(tox_netprof_get_packet_id_bytes(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_SENT) > 0);
ck_assert(tox_netprof_get_packet_id_bytes(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_SENT) > 0);
ck_assert(tox_netprof_get_packet_id_bytes(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_RECV) > 0);
continue;
}
total_sent_count += tox_netprof_get_packet_id_count(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_SENT);
total_recv_count += tox_netprof_get_packet_id_count(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_RECV);
total_sent_bytes += tox_netprof_get_packet_id_bytes(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_SENT);
total_recv_bytes += tox_netprof_get_packet_id_bytes(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_RECV);
}
const uint64_t total_packets = total_sent_count + total_recv_count;
ck_assert_msg(total_packets == UDP_count_sent1 + UDP_count_recv1,
"%" PRIu64 "does not match %" PRIu64 "\n", total_packets, UDP_count_sent1 + UDP_count_recv1);
ck_assert_msg(total_sent_count == UDP_count_sent1, "%" PRIu64 " does not match %" PRIu64 "\n", total_sent_count, UDP_count_sent1);
ck_assert_msg(total_recv_count == UDP_count_recv1, "%" PRIu64 " does not match %" PRIu64"\n", total_recv_count, UDP_count_recv1);
const uint64_t total_bytes = total_sent_bytes + total_recv_bytes;
ck_assert_msg(total_bytes == UDP_bytes_sent1 + UDP_bytes_recv1,
"%" PRIu64 "does not match %" PRIu64 "\n", total_bytes, UDP_bytes_sent1 + UDP_bytes_recv1);
ck_assert_msg(total_sent_bytes == UDP_bytes_sent1, "%" PRIu64 " does not match %" PRIu64 "\n", total_sent_bytes, UDP_bytes_sent1);
ck_assert_msg(total_recv_bytes == UDP_bytes_recv1, "%" PRIu64 " does not match %" PRIu64 "\n", total_recv_bytes, UDP_bytes_recv1);
}
int main(void)
{
setvbuf(stdout, nullptr, _IONBF, 0);
Run_Auto_Options autotox_opts = default_run_auto_options();
autotox_opts.graph = GRAPH_COMPLETE;
run_auto_test(nullptr, NUM_TOXES, test_netprof, 0, &autotox_opts);
return 0;
}
#undef NUM_TOXES

View File

@ -23,12 +23,15 @@ static void test_addr_resolv_localhost(void)
const Network *ns = os_network(); const Network *ns = os_network();
ck_assert(ns != nullptr); ck_assert(ns != nullptr);
const Memory *mem = os_memory();
ck_assert(mem != nullptr);
const char localhost[] = "localhost"; const char localhost[] = "localhost";
IP ip; IP ip;
ip_init(&ip, 0); // ipv6enabled = 0 ip_init(&ip, 0); // ipv6enabled = 0
bool res = addr_resolve_or_parse_ip(ns, localhost, &ip, nullptr); bool res = addr_resolve_or_parse_ip(ns, mem, localhost, &ip, nullptr, true);
int error = net_error(); int error = net_error();
char *strerror = net_new_strerror(error); char *strerror = net_new_strerror(error);
@ -42,14 +45,14 @@ static void test_addr_resolv_localhost(void)
net_ip_ntoa(&ip, &ip_str)); net_ip_ntoa(&ip, &ip_str));
ip_init(&ip, 1); // ipv6enabled = 1 ip_init(&ip, 1); // ipv6enabled = 1
res = addr_resolve_or_parse_ip(ns, localhost, &ip, nullptr); res = addr_resolve_or_parse_ip(ns, mem, localhost, &ip, nullptr, true);
#if USE_IPV6 #if USE_IPV6
int localhost_split = 0; int localhost_split = 0;
if (!net_family_is_ipv6(ip.family)) { if (!net_family_is_ipv6(ip.family)) {
res = addr_resolve_or_parse_ip(ns, "ip6-localhost", &ip, nullptr); res = addr_resolve_or_parse_ip(ns, mem, "ip6-localhost", &ip, nullptr, true);
localhost_split = 1; localhost_split = 1;
} }
@ -75,7 +78,7 @@ static void test_addr_resolv_localhost(void)
ip.family = net_family_unspec(); ip.family = net_family_unspec();
IP extra; IP extra;
ip_reset(&extra); ip_reset(&extra);
res = addr_resolve_or_parse_ip(ns, localhost, &ip, &extra); res = addr_resolve_or_parse_ip(ns, mem, localhost, &ip, &extra, true);
error = net_error(); error = net_error();
strerror = net_new_strerror(error); strerror = net_new_strerror(error);
ck_assert_msg(res, "Resolver failed: %d, %s", error, strerror); ck_assert_msg(res, "Resolver failed: %d, %s", error, strerror);

View File

@ -228,9 +228,9 @@ static void test_basic(void)
const Random *rng = os_random(); const Random *rng = os_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
Logger *log1 = logger_new(); Logger *log1 = logger_new(mem);
logger_callback_log(log1, print_debug_logger, nullptr, &index[0]); logger_callback_log(log1, print_debug_logger, nullptr, &index[0]);
Logger *log2 = logger_new(); Logger *log2 = logger_new(mem);
logger_callback_log(log2, print_debug_logger, nullptr, &index[1]); logger_callback_log(log2, print_debug_logger, nullptr, &index[1]);
Mono_Time *mono_time1 = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time1 = mono_time_new(mem, nullptr, nullptr);
@ -329,7 +329,7 @@ static void test_basic(void)
CRYPTO_PUBLIC_KEY_SIZE) != 0); CRYPTO_PUBLIC_KEY_SIZE) != 0);
c_sleep(1000); c_sleep(1000);
Logger *log3 = logger_new(); Logger *log3 = logger_new(mem);
logger_callback_log(log3, print_debug_logger, nullptr, &index[2]); logger_callback_log(log3, print_debug_logger, nullptr, &index[2]);
Mono_Time *mono_time3 = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time3 = mono_time_new(mem, nullptr, nullptr);
@ -412,7 +412,7 @@ static Onions *new_onions(const Memory *mem, const Random *rng, uint16_t port, u
return nullptr; return nullptr;
} }
on->log = logger_new(); on->log = logger_new(mem);
if (!on->log) { if (!on->log) {
free(on); free(on);

View File

@ -168,29 +168,33 @@ static void test_av_three_calls(void)
Time_Data time_data; Time_Data time_data;
pthread_mutex_init(&time_data.lock, nullptr); 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; 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); ck_assert(error == TOX_ERR_NEW_OK);
time_data.clock = current_time_monotonic(bootstrap->mono_time); time_data.clock = current_time_monotonic(bootstrap->mono_time);
set_current_time_callback(bootstrap, &time_data); 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); ck_assert(error == TOX_ERR_NEW_OK);
set_current_time_callback(alice, &time_data); 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); ck_assert(error == TOX_ERR_NEW_OK);
set_current_time_callback(bobs[0], &time_data); 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); ck_assert(error == TOX_ERR_NEW_OK);
set_current_time_callback(bobs[1], &time_data); 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); ck_assert(error == TOX_ERR_NEW_OK);
set_current_time_callback(bobs[2], &time_data); set_current_time_callback(bobs[2], &time_data);
tox_options_free(opts);
} }
printf("Created 5 instances of Tox\n"); printf("Created 5 instances of Tox\n");

View File

@ -1,15 +1,25 @@
pool: pool:
vmImage: "windows-2019" vmImage: "windows-2019"
jobs: jobs:
- job: "windows_msvc_conan" - job: "vcpkg"
strategy: strategy:
matrix: matrix:
static: static:
conan.shared: "False" ENABLE_STATIC: "ON"
ENABLE_SHARED: "OFF"
shared: shared:
conan.shared: "True" ENABLE_STATIC: "OFF"
ENABLE_SHARED: "ON"
steps: steps:
- bash: python -m pip install conan==1.59.0 - task: Cache@2
inputs:
key: "vcpkg"
path: "_build/vcpkg_installed"
- bash: git submodule update --init --recursive - bash: git submodule update --init --recursive
- bash: conan install -if _build -o with_tests=True -o shared=$(conan.shared) . - bash: cmake --preset windows-default -DENABLE_STATIC=$(ENABLE_STATIC) -DENABLE_SHARED=$(ENABLE_SHARED)
- bash: CONAN_CPU_COUNT=50 CTEST_OUTPUT_ON_FAILURE=1 conan build -bf _build -if _build . || true env:
VCPKG_ROOT: "C:/vcpkg"
VCPKG_DEFAULT_TRIPLET: "x64-windows"
- bash: cmake --build _build --config Release
- bash: ctest --preset windows-default -C Release --parallel 50 ||
ctest --preset windows-default -C Release --rerun-failed --output-on-failure

View File

@ -12,14 +12,20 @@ find_library(SOCKET_LIBRARIES socket)
find_package(pthreads QUIET) find_package(pthreads QUIET)
if(NOT TARGET PThreads4W::PThreads4W) if(NOT TARGET PThreads4W::PThreads4W)
find_package(pthreads4w QUIET)
endif()
if(NOT TARGET pthreads4w::pthreads4w)
set(THREADS_PREFER_PTHREAD_FLAG ON) set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
endif() endif()
# For toxcore. # For toxcore.
pkg_search_module(LIBSODIUM libsodium IMPORTED_TARGET REQUIRED) pkg_search_module(LIBSODIUM libsodium IMPORTED_TARGET)
if(MSVC) if(MSVC)
find_package(unofficial-sodium REQUIRED) find_package(libsodium)
if(NOT TARGET libsodium::libsodium)
find_package(unofficial-sodium REQUIRED)
endif()
endif() endif()
# For toxav. # For toxav.
@ -27,10 +33,23 @@ pkg_search_module(OPUS opus IMPORTED_TARGET)
if(NOT OPUS_FOUND) if(NOT OPUS_FOUND)
pkg_search_module(OPUS Opus IMPORTED_TARGET) pkg_search_module(OPUS Opus IMPORTED_TARGET)
endif() endif()
if(NOT OPUS_FOUND)
find_package(Opus)
if(TARGET Opus::opus)
set(OPUS_FOUND TRUE)
endif()
endif()
pkg_search_module(VPX vpx IMPORTED_TARGET) pkg_search_module(VPX vpx IMPORTED_TARGET)
if(NOT VPX_FOUND) if(NOT VPX_FOUND)
pkg_search_module(VPX libvpx IMPORTED_TARGET) pkg_search_module(VPX libvpx IMPORTED_TARGET)
endif() endif()
if(NOT VPX_FOUND)
find_package(libvpx)
if(TARGET libvpx::libvpx)
set(VPX_FOUND TRUE)
endif()
endif()
# For tox-bootstrapd. # For tox-bootstrapd.
pkg_search_module(LIBCONFIG libconfig IMPORTED_TARGET) pkg_search_module(LIBCONFIG libconfig IMPORTED_TARGET)

View File

@ -1,87 +0,0 @@
# pylint: disable=not-callable
import os
import re
from conans import CMake
from conans import ConanFile
from conans.tools import collect_libs
from conans.tools import load
class ToxConan(ConanFile):
name = "c-toxcore"
url = "https://tox.chat"
description = "The future of online communications."
license = "GPL-3.0-only"
settings = "os", "compiler", "build_type", "arch"
requires = "libsodium/1.0.18", "opus/1.3.1", "libvpx/1.9.0"
generators = "cmake_find_package"
scm = {"type": "git", "url": "auto", "revision": "auto"}
options = {
"shared": [True, False],
"with_tests": [True, False],
}
default_options = {
"shared": False,
"with_tests": False,
}
_cmake = None
def _create_cmake(self):
if self._cmake is not None:
return self._cmake
self._cmake = CMake(self)
self._cmake.definitions["AUTOTEST"] = self.options.with_tests
self._cmake.definitions["BUILD_MISC_TESTS"] = self.options.with_tests
self._cmake.definitions["TEST_TIMEOUT_SECONDS"] = "300"
self._cmake.definitions[
"CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS"] = self.options.shared
self._cmake.definitions["ENABLE_SHARED"] = self.options.shared
self._cmake.definitions["ENABLE_STATIC"] = not self.options.shared
self._cmake.definitions["MUST_BUILD_TOXAV"] = True
if self.settings.compiler == "Visual Studio":
self._cmake.definitions["MSVC_STATIC_SODIUM"] = True
self._cmake.definitions[
"FLAT_OUTPUT_STRUCTURE"] = self.options.shared
self._cmake.configure()
return self._cmake
def set_version(self):
content = load(os.path.join(self.recipe_folder, "CMakeLists.txt"))
version_major = re.search(r"set\(PROJECT_VERSION_MAJOR \"(.*)\"\)",
content).group(1)
version_minor = re.search(r"set\(PROJECT_VERSION_MINOR \"(.*)\"\)",
content).group(1)
version_patch = re.search(r"set\(PROJECT_VERSION_PATCH \"(.*)\"\)",
content).group(1)
self.version = "%s.%s.%s" % (
version_major.strip(),
version_minor.strip(),
version_patch.strip(),
)
def requirements(self):
if self.settings.os == "Windows":
self.requires("pthreads4w/3.0.0")
def build(self):
cmake = self._create_cmake()
cmake.build()
if self.options.with_tests:
cmake.test(output_on_failure=True)
def package(self):
cmake = self._create_cmake()
cmake.install()
def package_info(self):
self.cpp_info.libs = collect_libs(self)
if self.settings.os == "Windows":
self.cpp_info.system_libs = ["Ws2_32", "Iphlpapi"]

View File

@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
AC_PREREQ([2.65]) AC_PREREQ([2.65])
AC_INIT([tox], [0.2.19]) AC_INIT([tox], [0.2.20])
AC_CONFIG_AUX_DIR(configure_aux) AC_CONFIG_AUX_DIR(configure_aux)
AC_CONFIG_SRCDIR([toxcore/net_crypto.c]) AC_CONFIG_SRCDIR([toxcore/net_crypto.c])
AM_INIT_AUTOMAKE([foreign 1.10 -Wall -Werror subdir-objects tar-ustar]) AM_INIT_AUTOMAKE([foreign 1.10 -Wall -Werror subdir-objects tar-ustar])

View File

@ -144,16 +144,16 @@ int main(int argc, char *argv[])
IP ip; IP ip;
ip_init(&ip, ipv6enabled); ip_init(&ip, ipv6enabled);
Logger *logger = logger_new(); const Random *rng = os_random();
const Network *ns = os_network();
const Memory *mem = os_memory();
Logger *logger = logger_new(mem);
if (MIN_LOGGER_LEVEL <= LOGGER_LEVEL_DEBUG) { if (MIN_LOGGER_LEVEL <= LOGGER_LEVEL_DEBUG) {
logger_callback_log(logger, print_log, nullptr, nullptr); logger_callback_log(logger, print_log, nullptr, nullptr);
} }
const Random *rng = os_random();
const Network *ns = os_network();
const Memory *mem = os_memory();
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
const uint16_t start_port = PORT; const uint16_t start_port = PORT;
const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM); const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM);
@ -228,9 +228,12 @@ int main(int argc, char *argv[])
const uint16_t port = net_htons((uint16_t)port_conv); const uint16_t port = net_htons((uint16_t)port_conv);
// TODO(iphydf): Maybe disable and only use IP addresses?
const bool dns_enabled = true;
uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]); uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]);
const bool res = dht_bootstrap_from_address(dht, argv[argvoffset + 1], const bool res = dht_bootstrap_from_address(dht, argv[argvoffset + 1],
ipv6enabled, port, bootstrap_key); ipv6enabled, dns_enabled, port, bootstrap_key);
free(bootstrap_key); free(bootstrap_key);
if (!res) { if (!res) {

View File

@ -27,7 +27,6 @@ run() {
-Wno-missing-noreturn \ -Wno-missing-noreturn \
-Wno-old-style-cast \ -Wno-old-style-cast \
-Wno-padded \ -Wno-padded \
-Wno-sign-compare \
-Wno-switch-default \ -Wno-switch-default \
-Wno-tautological-pointer-compare \ -Wno-tautological-pointer-compare \
-Wno-unreachable-code-return \ -Wno-unreachable-code-return \

View File

@ -20,8 +20,6 @@ CPPCHECK+=("--suppress=knownConditionTrueFalse")
CPPCHECK+=("--suppress=missingIncludeSystem") CPPCHECK+=("--suppress=missingIncludeSystem")
# TODO(iphydf): Maybe fix? # TODO(iphydf): Maybe fix?
CPPCHECK+=("--suppress=signConversion") CPPCHECK+=("--suppress=signConversion")
# TODO(iphydf): Fixed in the toxav refactor PR.
CPPCHECK+=("--suppress=redundantAssignment")
# We use this for VLAs. # We use this for VLAs.
CPPCHECK_CXX+=("--suppress=allocaCalled") CPPCHECK_CXX+=("--suppress=allocaCalled")

View File

@ -5,11 +5,11 @@ FROM alpine:3.19.0 AS build
RUN ["apk", "--no-cache", "add",\ RUN ["apk", "--no-cache", "add",\
"clang",\ "clang",\
"cmake",\ "cmake",\
"linux-headers",\
"libconfig-dev",\ "libconfig-dev",\
"libconfig-static",\ "libconfig-static",\
"libsodium-dev",\ "libsodium-dev",\
"libsodium-static",\ "libsodium-static",\
"linux-headers",\
"musl-dev",\ "musl-dev",\
"ninja",\ "ninja",\
"python3"] "python3"]

View File

@ -1 +1 @@
e96f03a89051c5df12c28d0d6941184da2b92742d248bd4c57d31189a0052844 /usr/local/bin/tox-bootstrapd 9ec2993a28988bd147bf8f4f21a824c2fc5dbf7255e391b3ce517d337ebce5c1 /usr/local/bin/tox-bootstrapd

View File

@ -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, 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, 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, int *enable_motd, char **motd) uint16_t **tcp_relay_ports, int *tcp_relay_port_count, bool *enable_motd, char **motd)
{ {
config_t cfg; 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); memcpy(*keys_file_path, tmp_keys_file, keys_file_path_len);
// Get IPv6 option // 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, "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"); log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_IPV6, DEFAULT_ENABLE_IPV6 ? "true" : "false");
*enable_ipv6 = DEFAULT_ENABLE_IPV6; *enable_ipv6 = DEFAULT_ENABLE_IPV6;
} }
// Get IPv4 fallback option // 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, "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, log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_IPV4_FALLBACK,
DEFAULT_ENABLE_IPV4_FALLBACK ? "true" : "false"); 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 // 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, "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, log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_LAN_DISCOVERY,
DEFAULT_ENABLE_LAN_DISCOVERY ? "true" : "false"); 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 // 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, "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, log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_TCP_RELAY,
DEFAULT_ENABLE_TCP_RELAY ? "true" : "false"); DEFAULT_ENABLE_TCP_RELAY ? "true" : "false");
*enable_tcp_relay = DEFAULT_ENABLE_TCP_RELAY; *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); parse_tcp_relay_ports_config(&cfg, tcp_relay_ports, tcp_relay_port_count);
} else { } else {
*tcp_relay_port_count = 0; *tcp_relay_port_count = 0;
} }
// Get MOTD option // 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, "No '%s' setting in configuration file.\n", NAME_ENABLE_MOTD);
log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_MOTD, log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_MOTD,
DEFAULT_ENABLE_MOTD ? "true" : "false"); DEFAULT_ENABLE_MOTD ? "true" : "false");
*enable_motd = DEFAULT_ENABLE_MOTD; *enable_motd = DEFAULT_ENABLE_MOTD;
} }
if (*enable_motd != 0) { if (*enable_motd) {
// Get MOTD // Get MOTD
const char *tmp_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_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': %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': %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_IPV6, *enable_ipv6 ? "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_IPV4_FALLBACK, *enable_ipv4_fallback ? "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_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 // 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) { if (*tcp_relay_port_count == 0) {
log_write(LOG_LEVEL_ERROR, "No TCP ports could be read.\n"); log_write(LOG_LEVEL_ERROR, "No TCP ports could be read.\n");
} else { } 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); log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_MOTD, *motd);
} }
@ -379,6 +390,9 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6
bool address_resolved; bool address_resolved;
uint8_t *bs_public_key_bin; uint8_t *bs_public_key_bin;
// TODO(iphydf): Maybe disable it and only use IP addresses?
const bool dns_enabled = true;
node = config_setting_get_elem(node_list, 0); node = config_setting_get_elem(node_list, 0);
if (node == nullptr) { if (node == nullptr) {
@ -418,7 +432,7 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6
} }
bs_public_key_bin = bootstrap_hex_string_to_bin(bs_public_key); bs_public_key_bin = bootstrap_hex_string_to_bin(bs_public_key);
address_resolved = dht_bootstrap_from_address(dht, bs_address, enable_ipv6, net_htons(bs_port), address_resolved = dht_bootstrap_from_address(dht, bs_address, enable_ipv6, dns_enabled, net_htons(bs_port),
bs_public_key_bin); bs_public_key_bin);
free(bs_public_key_bin); free(bs_public_key_bin);

View File

@ -17,14 +17,14 @@
* *
* Important: You are responsible for freeing `pid_file_path` and `keys_file_path` * 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` * 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, * @return true on success,
* false on failure, doesn't modify any data pointed by arguments. * 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, 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, 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, int *enable_motd, char **motd); uint16_t **tcp_relay_ports, int *tcp_relay_port_count, bool *enable_motd, char **motd);
/** /**
* Bootstraps off nodes listed in the config file. * Bootstraps off nodes listed in the config file.

View File

@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later /* 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. * Copyright © 2014-2016 Tox project.
*/ */
@ -10,17 +10,19 @@
#ifndef C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_DEFAULTS_H #ifndef C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_DEFAULTS_H
#define C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_DEFAULTS_H #define C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_DEFAULTS_H
#include <stdbool.h>
#include "global.h" #include "global.h"
#define DEFAULT_PID_FILE_PATH "tox-bootstrapd.pid" #define DEFAULT_PID_FILE_PATH "tox-bootstrapd.pid"
#define DEFAULT_KEYS_FILE_PATH "tox-bootstrapd.keys" #define DEFAULT_KEYS_FILE_PATH "tox-bootstrapd.keys"
#define DEFAULT_PORT 33445 #define DEFAULT_PORT 33445
#define DEFAULT_ENABLE_IPV6 1 // 1 - true, 0 - false #define DEFAULT_ENABLE_IPV6 true
#define DEFAULT_ENABLE_IPV4_FALLBACK 1 // 1 - true, 0 - false #define DEFAULT_ENABLE_IPV4_FALLBACK true
#define DEFAULT_ENABLE_LAN_DISCOVERY 1 // 1 - true, 0 - false #define DEFAULT_ENABLE_LAN_DISCOVERY true
#define DEFAULT_ENABLE_TCP_RELAY 1 // 1 - true, 0 - false #define DEFAULT_ENABLE_TCP_RELAY true
#define DEFAULT_TCP_RELAY_PORTS 443, 3389, 33445 // comma-separated list of ports #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 #define DEFAULT_MOTD DAEMON_NAME
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_DEFAULTS_H #endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_DEFAULTS_H

View File

@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later /* 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. * Copyright © 2014-2016 Tox project.
*/ */
@ -240,13 +240,13 @@ int main(int argc, char *argv[])
char *pid_file_path = nullptr; char *pid_file_path = nullptr;
char *keys_file_path = nullptr; char *keys_file_path = nullptr;
int start_port = 0; int start_port = 0;
int enable_ipv6 = 0; bool enable_ipv6 = false;
int enable_ipv4_fallback = 0; bool enable_ipv4_fallback = false;
int enable_lan_discovery = 0; bool enable_lan_discovery = false;
int enable_tcp_relay = 0; bool enable_tcp_relay = false;
uint16_t *tcp_relay_ports = nullptr; uint16_t *tcp_relay_ports = nullptr;
int tcp_relay_port_count = 0; int tcp_relay_port_count = 0;
int enable_motd = 0; bool enable_motd = false;
char *motd = nullptr; char *motd = nullptr;
if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &start_port, &enable_ipv6, &enable_ipv4_fallback, if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &start_port, &enable_ipv6, &enable_ipv4_fallback,
@ -281,25 +281,26 @@ int main(int argc, char *argv[])
free(pid_file_path); free(pid_file_path);
IP ip; IP ip;
ip_init(&ip, enable_ipv6 != 0); ip_init(&ip, enable_ipv6);
Logger *logger = logger_new(); const Memory *mem = os_memory();
const Random *rng = os_random();
const Network *ns = os_network();
Logger *logger = logger_new(mem);
if (MIN_LOGGER_LEVEL <= LOGGER_LEVEL_DEBUG) { if (MIN_LOGGER_LEVEL <= LOGGER_LEVEL_DEBUG) {
logger_callback_log(logger, toxcore_logger_callback, nullptr, nullptr); logger_callback_log(logger, toxcore_logger_callback, nullptr, nullptr);
} }
const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM); const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM);
const Memory *mem = os_memory();
const Random *rng = os_random();
const Network *ns = os_network();
Networking_Core *net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr); Networking_Core *net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr);
if (net == 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"); log_write(LOG_LEVEL_WARNING, "Couldn't initialize IPv6 networking. Falling back to using IPv4.\n");
enable_ipv6 = 0; enable_ipv6 = false;
ip_init(&ip, enable_ipv6 != 0); ip_init(&ip, enable_ipv6);
net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr); net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr);
if (net == nullptr) { if (net == nullptr) {
@ -334,7 +335,7 @@ int main(int argc, char *argv[])
mono_time_update(mono_time); 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) { if (dht == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n");
@ -429,7 +430,7 @@ int main(int argc, char *argv[])
gca_onion_init(group_announce, onion_a); 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) { 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"); log_write(LOG_LEVEL_INFO, "Set MOTD successfully.\n");
free(motd); free(motd);
@ -472,7 +473,7 @@ int main(int argc, char *argv[])
TCP_Server *tcp_server = nullptr; TCP_Server *tcp_server = nullptr;
if (enable_tcp_relay != 0) { if (enable_tcp_relay) {
if (tcp_relay_port_count == 0) { if (tcp_relay_port_count == 0) {
log_write(LOG_LEVEL_ERROR, "No TCP relay ports read. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "No TCP relay ports read. Exiting.\n");
kill_onion_announce(onion_a); kill_onion_announce(onion_a);
@ -488,7 +489,7 @@ int main(int argc, char *argv[])
return 1; 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, tcp_relay_port_count, tcp_relay_ports,
dht_get_self_secret_key(dht), onion, forwarding); dht_get_self_secret_key(dht), onion, forwarding);
@ -535,7 +536,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"); log_write(LOG_LEVEL_INFO, "List of bootstrap nodes read successfully.\n");
} else { } else {
log_write(LOG_LEVEL_ERROR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path); log_write(LOG_LEVEL_ERROR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path);
@ -561,7 +562,7 @@ int main(int argc, char *argv[])
Broadcast_Info *broadcast = nullptr; Broadcast_Info *broadcast = nullptr;
if (enable_lan_discovery != 0) { if (enable_lan_discovery) {
broadcast = lan_discovery_init(ns); broadcast = lan_discovery_init(ns);
log_write(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n"); log_write(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n");
} }
@ -589,12 +590,12 @@ int main(int argc, char *argv[])
do_dht(dht); 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); 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); last_lan_discovery = mono_time_get(mono_time);
} }
if (enable_tcp_relay != 0) { if (enable_tcp_relay) {
do_tcp_server(tcp_server, mono_time); do_tcp_server(tcp_server, mono_time);
} }
@ -618,7 +619,7 @@ int main(int argc, char *argv[])
break; break;
default: 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); lan_discovery_kill(broadcast);

View File

@ -4,4 +4,4 @@ go 1.17
require github.com/gorilla/websocket v1.5.1 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

View File

@ -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-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.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.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.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/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-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.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.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.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.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-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.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.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.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-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.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.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.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= 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.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.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.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.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.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.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-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.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=

View File

@ -3,10 +3,10 @@ FROM alpine:3.14.0
RUN ["apk", "add", "--no-cache", \ RUN ["apk", "add", "--no-cache", \
"bash", \ "bash", \
"gcc", \ "gcc", \
"linux-headers", \
"musl-dev", \
"libsodium-dev", \ "libsodium-dev", \
"libvpx-dev", \ "libvpx-dev", \
"linux-headers", \
"musl-dev", \
"opus-dev", \ "opus-dev", \
"perf"] "perf"]

View File

@ -5,7 +5,7 @@ COPY . /work/c-toxcore-0.2.18
RUN ["tar", "zcf", "c-toxcore.tar.gz", "c-toxcore-0.2.18"] RUN ["tar", "zcf", "c-toxcore.tar.gz", "c-toxcore-0.2.18"]
WORKDIR /work/pkgsrc/chat/toxcore 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", "clean"]
RUN ["bmake", "DISTFILES=c-toxcore.tar.gz", "DISTDIR=/work", "NO_CHECKSUM=yes"] RUN ["bmake", "DISTFILES=c-toxcore.tar.gz", "DISTDIR=/work", "NO_CHECKSUM=yes"]
RUN ["bmake", "install"] RUN ["bmake", "install"]

View File

@ -444,7 +444,10 @@ void generate_event_impl(const std::string& event_name, const std::vector<EventT
f << " Tox_Event event;\n"; f << " Tox_Event event;\n";
f << " event.type = TOX_EVENT_" << str_toupper(event_name) << ";\n"; f << " event.type = TOX_EVENT_" << str_toupper(event_name) << ";\n";
f << " event.data." << event_name_l << " = " << event_name_l << ";\n\n"; f << " event.data." << event_name_l << " = " << event_name_l << ";\n\n";
f << " tox_events_add(events, &event);\n"; f << " if (!tox_events_add(events, &event)) {\n";
f << " tox_event_" << event_name_l << "_free(" << event_name_l << ", mem);\n";
f << " return nullptr;\n";
f << " }\n";
f << " return " << event_name_l << ";\n}\n\n"; f << " return " << event_name_l << ";\n}\n\n";
// unpack // unpack

View File

@ -137,7 +137,7 @@ int main(int argc, char *argv[])
printf("Failed to set status. Error number: %d\n", err); printf("Failed to set status. Error number: %d\n", err);
} }
for (unsigned int i = 2; i < argc; i++) { //start at 2 because that is where the tox ids are for (int i = 2; i < argc; i++) { //start at 2 because that is where the tox ids are
uint8_t *address = hex_string_to_bin(argv[i]); uint8_t *address = hex_string_to_bin(argv[i]);
Tox_Err_Friend_Add friend_err; Tox_Err_Friend_Add friend_err;
tox_friend_add(tox, address, (const uint8_t *)GENERATED_REQUEST_MESSAGE, strlen(GENERATED_REQUEST_MESSAGE), tox_friend_add(tox, address, (const uint8_t *)GENERATED_REQUEST_MESSAGE, strlen(GENERATED_REQUEST_MESSAGE),
@ -145,7 +145,7 @@ int main(int argc, char *argv[])
free(address); free(address);
if (friend_err != TOX_ERR_FRIEND_ADD_OK) { if (friend_err != TOX_ERR_FRIEND_ADD_OK) {
printf("Failed to add friend number %u. Error number: %d\n", i - 1, friend_err); printf("Failed to add friend number %d. Error number: %d\n", i - 1, friend_err);
} }
} }

View File

@ -35,7 +35,7 @@ static int load_file(const char *filename, unsigned char **result)
fseek(f, 0, SEEK_SET); fseek(f, 0, SEEK_SET);
*result = (unsigned char *)malloc(size + 1); *result = (unsigned char *)malloc(size + 1);
if (size != fread(*result, sizeof(char), size, f)) { if ((size_t)size != fread(*result, sizeof(char), size, f)) {
free(*result); free(*result);
fclose(f); fclose(f);
return -2; // -2 means file reading fail return -2; // -2 means file reading fail
@ -55,13 +55,13 @@ int main(int argc, char *argv[])
crypto_sign_ed25519_keypair(pk, sk); crypto_sign_ed25519_keypair(pk, sk);
printf("Public key:\n"); printf("Public key:\n");
for (int i = 0; i < crypto_sign_ed25519_PUBLICKEYBYTES; ++i) { for (uint32_t i = 0; i < crypto_sign_ed25519_PUBLICKEYBYTES; ++i) {
printf("%02X", pk[i]); printf("%02X", pk[i]);
} }
printf("\nSecret key:\n"); printf("\nSecret key:\n");
for (int i = 0; i < crypto_sign_ed25519_SECRETKEYBYTES; ++i) { for (uint32_t i = 0; i < crypto_sign_ed25519_SECRETKEYBYTES; ++i) {
printf("%02X", sk[i]); printf("%02X", sk[i]);
} }

View File

@ -117,7 +117,7 @@ int main(int argc, char *argv[])
#endif #endif
crypto_box_keypair(public_key, secret_key); crypto_box_keypair(public_key, secret_key);
for (int i = 0; i <= crypto_box_PUBLICKEYBYTES - len; ++i) { for (uint32_t i = 0; i <= crypto_box_PUBLICKEYBYTES - len; ++i) {
if (memcmp(public_key + i, desired_bin, len) == 0) { if (memcmp(public_key + i, desired_bin, len) == 0) {
found = 1; found = 1;
break; break;

View File

@ -11,6 +11,6 @@
# For a full reference see: # For a full reference see:
# https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info # https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info
CURRENT=21 CURRENT=22
REVISION=0 REVISION=0
AGE=19 AGE=20

View File

@ -75,7 +75,6 @@ cc_library(
deps = [ deps = [
"//c-toxcore/toxcore:ccompat", "//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:tox", "//c-toxcore/toxcore:tox",
"@libsodium",
], ],
) )

View File

@ -8,15 +8,9 @@ if(TARGET toxcore_static)
else() else()
target_link_libraries(misc_tools PRIVATE toxcore_shared) target_link_libraries(misc_tools PRIVATE toxcore_shared)
endif() endif()
if(TARGET unofficial-sodium::sodium) if(TARGET pthreads4w::pthreads4w)
target_link_libraries(misc_tools PRIVATE unofficial-sodium::sodium) target_link_libraries(misc_tools PRIVATE pthreads4w::pthreads4w)
else() elseif(TARGET PThreads4W::PThreads4W)
target_link_libraries(misc_tools PRIVATE ${LIBSODIUM_LIBRARIES})
target_link_directories(misc_tools PUBLIC ${LIBSODIUM_LIBRARY_DIRS})
target_include_directories(misc_tools SYSTEM PRIVATE ${LIBSODIUM_INCLUDE_DIRS})
target_compile_options(misc_tools PRIVATE ${LIBSODIUM_CFLAGS_OTHER})
endif()
if(TARGET PThreads4W::PThreads4W)
target_link_libraries(misc_tools PRIVATE PThreads4W::PThreads4W) target_link_libraries(misc_tools PRIVATE PThreads4W::PThreads4W)
elseif(TARGET Threads::Threads) elseif(TARGET Threads::Threads)
target_link_libraries(misc_tools PRIVATE Threads::Threads) target_link_libraries(misc_tools PRIVATE Threads::Threads)
@ -36,7 +30,9 @@ if(BUILD_MISC_TESTS)
else() else()
target_link_libraries(Messenger_test PRIVATE toxcore_shared) target_link_libraries(Messenger_test PRIVATE toxcore_shared)
endif() endif()
if(TARGET PThreads4W::PThreads4W) if(TARGET pthreads4w::pthreads4w)
target_link_libraries(Messenger_test PRIVATE pthreads4w::pthreads4w)
elseif(TARGET PThreads4W::PThreads4W)
target_link_libraries(Messenger_test PRIVATE PThreads4W::PThreads4W) target_link_libraries(Messenger_test PRIVATE PThreads4W::PThreads4W)
elseif(TARGET Threads::Threads) elseif(TARGET Threads::Threads)
target_link_libraries(Messenger_test PRIVATE Threads::Threads) target_link_libraries(Messenger_test PRIVATE Threads::Threads)

View File

@ -10,22 +10,34 @@ ENV NO_ARCH_OPT 1
RUN apt-get update && \ RUN apt-get update && \
apt-get -y install --no-install-suggests --no-install-recommends \ apt-get -y install --no-install-suggests --no-install-recommends \
apt-transport-https \
apt-utils \
automake \ automake \
ninja-build \ bash-completion \
bison flex \ bison flex \
build-essential \ build-essential \
git \ ca-certificates \
python3 python3-dev python3-setuptools python-is-python3 \
libtool libtool-bin \
libglib2.0-dev \
wget vim jupp nano bash-completion less \
apt-utils apt-transport-https ca-certificates gnupg dialog \
libpixman-1-dev \
gnuplot-nox \
screen \
cmake \ cmake \
parallel \ dialog \
git \
gnupg \
gnuplot-nox \
jupp \
less \
libglib2.0-dev \
libpixman-1-dev \
libsodium-dev \ libsodium-dev \
libtool libtool-bin \
nano \
ninja-build \
parallel \
python-is-python3 \
python3 \
python3-dev \
python3-setuptools \
screen \
vim \
wget \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
RUN echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-12 main" >> /etc/apt/sources.list && \ RUN echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-12 main" >> /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 && \ RUN apt-get update && apt-get full-upgrade -y && \
apt-get -y install --no-install-suggests --no-install-recommends \ 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-12 clang-tools-12 libc++1-12 libc++-12-dev \ clang-tools-12 \
libc++abi1-12 libc++abi-12-dev libclang1-12 libclang-12-dev \ g++-10 \
libclang-common-12-dev libclang-cpp12 libclang-cpp12-dev liblld-12 \ gcc-10 \
liblld-12-dev liblldb-12 liblldb-12-dev libllvm12 libomp-12-dev \ gcc-10-multilib \
libomp5-12 lld-12 lldb-12 llvm-12 llvm-12-dev llvm-12-runtime llvm-12-tools \ 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/* && rm -rf /var/lib/apt/lists/*
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 0 RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 0

View File

@ -8,10 +8,6 @@ endif
noinst_LTLIBRARIES += libmisc_tools.la noinst_LTLIBRARIES += libmisc_tools.la
libmisc_tools_la_SOURCES = ../testing/misc_tools.c ../testing/misc_tools.h libmisc_tools_la_SOURCES = ../testing/misc_tools.c ../testing/misc_tools.h
libmisc_tools_la_CFLAGS = $(LIBSODIUM_CFLAGS)
libmisc_tools_la_LIBADD = $(LIBSODIUM_LDFLAGS)
if BUILD_TESTING if BUILD_TESTING
noinst_PROGRAMS += Messenger_test noinst_PROGRAMS += Messenger_test

View File

@ -118,10 +118,13 @@ int main(int argc, char *argv[])
exit(1); exit(1);
} }
// TODO(iphydf): Maybe disable.
const bool dns_enabled = true;
const uint16_t port = net_htons((uint16_t)port_conv); const uint16_t port = net_htons((uint16_t)port_conv);
uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]); uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]);
bool res = dht_bootstrap_from_address(m->dht, argv[argvoffset + 1], bool res = dht_bootstrap_from_address(m->dht, argv[argvoffset + 1],
ipv6enabled, port, bootstrap_key); ipv6enabled, dns_enabled, port, bootstrap_key);
free(bootstrap_key); free(bootstrap_key);
if (!res) { if (!res) {

View File

@ -111,6 +111,7 @@ static constexpr Network_Funcs fuzz_network_funcs = {
/* .accept = */ ![](Fuzz_System *self, Socket sock) { return Socket{1337}; }, /* .accept = */ ![](Fuzz_System *self, Socket sock) { return Socket{1337}; },
/* .bind = */ ![](Fuzz_System *self, Socket sock, const Network_Addr *addr) { return 0; }, /* .bind = */ ![](Fuzz_System *self, Socket sock, const Network_Addr *addr) { return 0; },
/* .listen = */ ![](Fuzz_System *self, Socket sock, int backlog) { return 0; }, /* .listen = */ ![](Fuzz_System *self, Socket sock, int backlog) { return 0; },
/* .connect = */ ![](Fuzz_System *self, Socket sock, const Network_Addr *addr) { return 0; },
/* .recvbuf = */ /* .recvbuf = */
![](Fuzz_System *self, Socket sock) { ![](Fuzz_System *self, Socket sock) {
assert(sock.value == 42 || sock.value == 1337); assert(sock.value == 42 || sock.value == 1337);
@ -225,6 +226,7 @@ static constexpr Network_Funcs null_network_funcs = {
/* .accept = */ ![](Null_System *self, Socket sock) { return Socket{1337}; }, /* .accept = */ ![](Null_System *self, Socket sock) { return Socket{1337}; },
/* .bind = */ ![](Null_System *self, Socket sock, const Network_Addr *addr) { return 0; }, /* .bind = */ ![](Null_System *self, Socket sock, const Network_Addr *addr) { return 0; },
/* .listen = */ ![](Null_System *self, Socket sock, int backlog) { return 0; }, /* .listen = */ ![](Null_System *self, Socket sock, int backlog) { return 0; },
/* .connect = */ ![](Null_System *self, Socket sock, const Network_Addr *addr) { return 0; },
/* .recvbuf = */ ![](Null_System *self, Socket sock) { return 0; }, /* .recvbuf = */ ![](Null_System *self, Socket sock) { return 0; },
/* .recv = */ /* .recv = */
![](Null_System *self, Socket sock, uint8_t *buf, size_t len) { ![](Null_System *self, Socket sock, uint8_t *buf, size_t len) {
@ -341,6 +343,7 @@ static constexpr Network_Funcs record_network_funcs = {
return 0; return 0;
}, },
/* .listen = */ ![](Record_System *self, Socket sock, int backlog) { return 0; }, /* .listen = */ ![](Record_System *self, Socket sock, int backlog) { return 0; },
/* .connect = */ ![](Record_System *self, Socket sock, const Network_Addr *addr) { return 0; },
/* .recvbuf = */ ![](Record_System *self, Socket sock) { return 0; }, /* .recvbuf = */ ![](Record_System *self, Socket sock) { return 0; },
/* .recv = */ /* .recv = */
![](Record_System *self, Socket sock, uint8_t *buf, size_t len) { ![](Record_System *self, Socket sock, uint8_t *buf, size_t len) {

View File

@ -20,8 +20,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sodium.h>
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
#include <windows.h> #include <windows.h>
#else #else
@ -137,60 +135,3 @@ int cmdline_parsefor_ipv46(int argc, char **argv, bool *ipv6enabled)
return argvoffset; return argvoffset;
} }
static const char *test_rng_name(void)
{
return "test_rng";
}
static uint32_t rng_state;
static uint32_t test_rng_random(void)
{
rng_state = 2624534371 * rng_state + 1;
return rng_state;
}
static void test_rng_buf(void *const buf, const size_t size)
{
uint8_t *p = (uint8_t *)buf;
uint32_t r = 0;
for (size_t i = 0; i < size; i++) {
if ((i % 4) == 0) {
r = test_rng_random();
}
*p = (r >> ((i % 4) * 8)) & 0xff;
++p;
}
}
static uint32_t test_rng_uniform(const uint32_t upper_bound)
{
// XXX: Not uniform! But that's ok for testing purposes.
return test_rng_random() % upper_bound;
}
static void test_rng_stir(void) { }
static int test_rng_close(void)
{
return 0;
}
static randombytes_implementation test_rng = {
test_rng_name,
test_rng_random,
test_rng_stir,
test_rng_uniform,
test_rng_buf,
test_rng_close
};
/* Simple insecure PRNG for testing purposes */
int use_test_rng(uint32_t seed)
{
rng_state = seed;
return randombytes_set_implementation(&test_rng);
}

View File

@ -42,127 +42,32 @@ cc_library(
) )
cc_library( cc_library(
name = "bwcontroller", name = "toxav",
srcs = ["bwcontroller.c"], srcs = glob(
hdrs = ["bwcontroller.h"], [
"*.c",
"*.h",
],
exclude = ["toxav.h"],
),
hdrs = ["toxav.h"],
visibility = ["//c-toxcore:__subpackages__"],
deps = [ deps = [
":ring_buffer",
"//c-toxcore/toxcore",
"//c-toxcore/toxcore:Messenger", "//c-toxcore/toxcore:Messenger",
"//c-toxcore/toxcore:ccompat", "//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:group",
"//c-toxcore/toxcore:logger", "//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time", "//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:net_crypto",
"//c-toxcore/toxcore:network",
"//c-toxcore/toxcore:tox", "//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:util", "//c-toxcore/toxcore:util",
"@libsodium",
"@libvpx",
"@opus", "@opus",
], ],
) )
cc_library(
name = "toxav",
srcs = [
"toxav.c",
"toxav_old.c",
],
hdrs = [
"toxav.h",
],
visibility = ["//c-toxcore:__subpackages__"],
deps = [
":groupav",
":rtp",
":video",
"//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",
],
)
sh_library( sh_library(
name = "cimple_files", name = "cimple_files",
srcs = glob([ srcs = glob([

View File

@ -19,6 +19,7 @@ libtoxav_la_SOURCES = ../toxav/rtp.h \
../toxav/ring_buffer.h \ ../toxav/ring_buffer.h \
../toxav/ring_buffer.c \ ../toxav/ring_buffer.c \
../toxav/toxav.h \ ../toxav/toxav.h \
../toxav/toxav_hacks.h \
../toxav/toxav.c \ ../toxav/toxav.c \
../toxav/toxav_old.c ../toxav/toxav_old.c

View File

@ -13,6 +13,7 @@
#include "../toxcore/ccompat.h" #include "../toxcore/ccompat.h"
#include "../toxcore/logger.h" #include "../toxcore/logger.h"
#include "../toxcore/mono_time.h" #include "../toxcore/mono_time.h"
#include "../toxcore/network.h"
static struct JitterBuffer *jbuf_new(uint32_t capacity); static struct JitterBuffer *jbuf_new(uint32_t capacity);
static void jbuf_clear(struct JitterBuffer *q); 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); 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); 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, 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) 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); 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, /** NOTE: even though OPUS supports decoding mono frames with stereo decoder and vice versa,
* it didn't work quite well. * it didn't work quite well.
*/ */
if (!reconfigure_audio_decoder(ac, ac->lp_sampling_rate, ac->lp_channel_count)) { if (!reconfigure_audio_decoder(ac, ac->lp_sampling_rate, ac->lp_channel_count)) {
LOGGER_WARNING(ac->log, "Failed to reconfigure decoder!"); LOGGER_WARNING(ac->log, "Failed to reconfigure decoder!");
free(msg); free(msg);
@ -273,6 +276,7 @@ static struct JitterBuffer *jbuf_new(uint32_t capacity)
q->capacity = capacity; q->capacity = capacity;
return q; return q;
} }
static void jbuf_clear(struct JitterBuffer *q) static void jbuf_clear(struct JitterBuffer *q)
{ {
while (q->bottom != q->top) { while (q->bottom != q->top) {
@ -281,6 +285,7 @@ static void jbuf_clear(struct JitterBuffer *q)
++q->bottom; ++q->bottom;
} }
} }
static void jbuf_free(struct JitterBuffer *q) static void jbuf_free(struct JitterBuffer *q)
{ {
if (q == nullptr) { if (q == nullptr) {
@ -291,6 +296,11 @@ static void jbuf_free(struct JitterBuffer *q)
free(q->queue); free(q->queue);
free(q); 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) static int jbuf_write(const Logger *log, struct JitterBuffer *q, struct RTPMessage *m)
{ {
const uint16_t sequnum = m->header.sequnum; 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; return 0;
} }
static struct RTPMessage *jbuf_read(struct JitterBuffer *q, int32_t *success) static struct RTPMessage *jbuf_read(struct JitterBuffer *q, int32_t *success)
{ {
if (q->top == q->bottom) { if (q->top == q->bottom) {

View File

@ -10,12 +10,16 @@
#include <string.h> #include <string.h>
#include "ring_buffer.h" #include "ring_buffer.h"
#include "toxav_hacks.h"
#include "../toxcore/ccompat.h" #include "../toxcore/ccompat.h"
#include "../toxcore/logger.h" #include "../toxcore/logger.h"
#include "../toxcore/mono_time.h" #include "../toxcore/mono_time.h"
#include "../toxcore/network.h"
#include "../toxcore/tox_private.h"
#include "../toxcore/util.h" #include "../toxcore/util.h"
#define BWC_PACKET_ID 196 #define BWC_PACKET_ID 196
#define BWC_SEND_INTERVAL_MS 950 // 0.95s #define BWC_SEND_INTERVAL_MS 950 // 0.95s
#define BWC_AVG_PKT_COUNT 20 #define BWC_AVG_PKT_COUNT 20
@ -38,9 +42,8 @@ typedef struct BWCRcvPkt {
struct BWController { struct BWController {
m_cb *mcb; m_cb *mcb;
void *mcb_user_data; void *mcb_user_data;
Messenger *m;
Tox *tox; Tox *tox;
const Logger *log;
uint32_t friend_number; uint32_t friend_number;
BWCCycle cycle; BWCCycle cycle;
@ -49,6 +52,7 @@ struct BWController {
uint32_t packet_loss_counted_cycles; uint32_t packet_loss_counted_cycles;
Mono_Time *bwc_mono_time; 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 { struct BWCMessage {
@ -56,11 +60,11 @@ struct BWCMessage {
uint32_t recv; uint32_t recv;
}; };
static int bwc_handle_data(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object); static void bwc_handle_data(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data);
static int bwc_send_custom_lossy_packet(Tox *tox, int32_t friendnumber, const uint8_t *data, uint32_t length);
static void send_update(BWController *bwc); 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) Mono_Time *bwc_mono_time)
{ {
BWController *retu = (BWController *)calloc(1, sizeof(BWController)); 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; return nullptr;
} }
LOGGER_DEBUG(m->log, "Creating bandwidth controller"); LOGGER_DEBUG(log, "Creating bandwidth controller");
retu->mcb = mcb; retu->mcb = mcb;
retu->mcb_user_data = mcb_user_data; retu->mcb_user_data = mcb_user_data;
retu->m = m;
retu->friend_number = friendnumber; retu->friend_number = friendnumber;
retu->bwc_mono_time = bwc_mono_time; retu->bwc_mono_time = bwc_mono_time;
const uint64_t now = current_time_monotonic(bwc_mono_time); const uint64_t now = current_time_monotonic(bwc_mono_time);
retu->cycle.last_sent_timestamp = now; retu->cycle.last_sent_timestamp = now;
retu->cycle.last_refresh_timestamp = now; retu->cycle.last_refresh_timestamp = now;
retu->tox = tox; retu->tox = tox;
retu->log = log;
retu->bwc_receive_active = true;
retu->rcvpkt.rb = rb_new(BWC_AVG_PKT_COUNT); retu->rcvpkt.rb = rb_new(BWC_AVG_PKT_COUNT);
retu->cycle.lost = 0; retu->cycle.lost = 0;
retu->cycle.recv = 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]); 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; return retu;
} }
@ -99,7 +104,6 @@ void bwc_kill(BWController *bwc)
return; return;
} }
m_callback_rtp_packet(bwc->m, bwc->friend_number, BWC_PACKET_ID, nullptr, nullptr);
rb_kill(bwc->rcvpkt.rb); rb_kill(bwc->rcvpkt.rb);
free(bwc); free(bwc);
} }
@ -111,7 +115,7 @@ void bwc_add_lost(BWController *bwc, uint32_t bytes_lost)
} }
if (bytes_lost > 0) { 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; bwc->cycle.lost += bytes_lost;
send_update(bwc); send_update(bwc);
} }
@ -135,7 +139,7 @@ static void send_update(BWController *bwc)
bwc->packet_loss_counted_cycles = 0; bwc->packet_loss_counted_cycles = 0;
if (bwc->cycle.lost != 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, (void *)bwc, bwc->cycle.recv, bwc->cycle.lost,
((double)bwc->cycle.lost / (bwc->cycle.recv + bwc->cycle.lost)) * 100.0); ((double)bwc->cycle.lost / (bwc->cycle.recv + bwc->cycle.lost)) * 100.0);
uint8_t bwc_packet[sizeof(struct BWCMessage) + 1]; 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); offset += net_pack_u32(bwc_packet + offset, bwc->cycle.recv);
assert(offset == sizeof(bwc_packet)); assert(offset == sizeof(bwc_packet));
if (bwc_send_custom_lossy_packet(bwc->tox, bwc->friend_number, bwc_packet, sizeof(bwc_packet)) == -1) { Tox_Err_Friend_Custom_Packet error;
char *netstrerror = net_new_strerror(net_error()); tox_friend_send_lossy_packet(bwc->tox, bwc->friend_number, bwc_packet, sizeof(bwc_packet), &error);
char *stdstrerror = net_new_strerror(errno);
LOGGER_WARNING(bwc->m->log, "BWC send failed (len: %u)! std error: %s, net error %s", if (error != TOX_ERR_FRIEND_CUSTOM_PACKET_OK) {
(unsigned)sizeof(bwc_packet), stdstrerror, netstrerror); LOGGER_WARNING(bwc->log, "BWC send failed: %d", error);
net_kill_strerror(stdstrerror);
net_kill_strerror(netstrerror);
} }
} }
@ -166,11 +168,11 @@ static void send_update(BWController *bwc)
static int on_update(BWController *bwc, const struct BWCMessage *msg) 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 */ /* Peers sent update too soon */
if (bwc->cycle.last_recv_timestamp + BWC_SEND_INTERVAL_MS > current_time_monotonic(bwc->bwc_mono_time)) { 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; return -1;
} }
@ -180,8 +182,8 @@ static int on_update(BWController *bwc, const struct BWCMessage *msg)
if (lost != 0 && bwc->mcb != nullptr) { if (lost != 0 && bwc->mcb != nullptr) {
const uint32_t recv = msg->recv; const uint32_t recv = msg->recv;
LOGGER_DEBUG(bwc->m->log, "recved: %u lost: %u percentage: %f %%", recv, lost, LOGGER_DEBUG(bwc->log, "recved: %u lost: %u percentage: %f %%", recv, lost,
((double)lost / (recv + lost)) * 100.0); ((double) lost / (recv + lost)) * 100.0);
bwc->mcb(bwc, bwc->friend_number, bwc->mcb(bwc, bwc->friend_number,
(float)lost / (recv + lost), (float)lost / (recv + lost),
bwc->mcb_user_data); bwc->mcb_user_data);
@ -190,28 +192,41 @@ static int on_update(BWController *bwc, const struct BWCMessage *msg)
return 0; return 0;
} }
/* static void bwc_handle_data(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data)
* 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)
{ {
Tox_Err_Friend_Custom_Packet error; /* get BWController object from Tox and friend number */
tox_friend_send_lossy_packet(tox, friendnumber, data, (size_t)length, &error); ToxAV *toxav = (ToxAV *)tox_get_av_object(tox);
if (error == TOX_ERR_FRIEND_CUSTOM_PACKET_OK) { if (toxav == nullptr) {
return 0; // LOGGER_ERROR(log, "Could not get ToxAV object from Tox");
return;
} }
return -1; const Logger *log = toxav_get_logger(toxav);
}
static int bwc_handle_data(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object)
{
BWController *bwc = (BWController *)object;
if (length - 1 != sizeof(struct BWCMessage)) { 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. 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); offset += net_unpack_u32(data + offset, &msg.recv);
assert(offset == length); 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);
} }

View File

@ -5,19 +5,24 @@
#ifndef C_TOXCORE_TOXAV_BWCONTROLLER_H #ifndef C_TOXCORE_TOXAV_BWCONTROLLER_H
#define C_TOXCORE_TOXAV_BWCONTROLLER_H #define C_TOXCORE_TOXAV_BWCONTROLLER_H
#include "../toxcore/Messenger.h" #include <stdint.h>
#include "../toxcore/logger.h"
#include "../toxcore/mono_time.h"
#include "../toxcore/tox.h" #include "../toxcore/tox.h"
typedef struct BWController BWController; typedef struct BWController BWController;
typedef void m_cb(BWController *bwc, uint32_t friend_number, float loss, void *user_data); typedef void m_cb(BWController *bwc, uint32_t friend_number, float loss, void *user_data);
BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb, void *mcb_user_data, BWController *bwc_new(const Logger *log, Tox *tox, uint32_t friendnumber,
Mono_Time *bwc_mono_time); m_cb *mcb, void *mcb_user_data, Mono_Time *bwc_mono_time);
void bwc_kill(BWController *bwc); void bwc_kill(BWController *bwc);
void bwc_add_lost(BWController *bwc, uint32_t bytes_lost); void bwc_add_lost(BWController *bwc, uint32_t bytes_lost);
void bwc_add_recv(BWController *bwc, uint32_t recv_bytes); 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 */ #endif /* C_TOXCORE_TOXAV_BWCONTROLLER_H */

View File

@ -476,7 +476,7 @@ int groupchat_enable_av(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t
return -1; 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); 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; 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_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); group_peer_set_object(g_c, conference_number, i, nullptr);
} }

View File

@ -9,8 +9,13 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "toxav_hacks.h"
#include "../toxcore/ccompat.h" #include "../toxcore/ccompat.h"
#include "../toxcore/logger.h" #include "../toxcore/logger.h"
#include "../toxcore/net_crypto.h"
#include "../toxcore/tox.h"
#include "../toxcore/tox_private.h"
#include "../toxcore/util.h" #include "../toxcore/util.h"
#define MSI_MAXMSG_SIZE 256 #define MSI_MAXMSG_SIZE 256
@ -55,20 +60,20 @@ typedef struct MSIMessage {
} MSIMessage; } MSIMessage;
static void msg_init(MSIMessage *dest, MSIRequest request); 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 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, static uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const uint8_t *value, uint8_t value_len,
uint16_t *length); uint16_t *length);
static int send_message(const Messenger *m, uint32_t friend_number, const MSIMessage *msg); static int send_message(const Logger *log, Tox *tox, uint32_t friend_number, const MSIMessage *msg);
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);
static bool invoke_callback(MSICall *call, MSICallbackID cb);
static MSICall *get_call(MSISession *session, uint32_t friend_number); static MSICall *get_call(MSISession *session, uint32_t friend_number);
static MSICall *new_call(MSISession *session, uint32_t friend_number); static MSICall *new_call(MSISession *session, uint32_t friend_number);
static void kill_call(MSICall *call); static bool invoke_callback(const Logger *log, MSICall *call, MSICallbackID cb);
static void on_peer_status(Messenger *m, uint32_t friend_number, bool is_online, void *user_data); static void handle_init(const Logger *log, MSICall *call, const MSIMessage *msg);
static void handle_init(MSICall *call, const MSIMessage *msg); static void handle_push(const Logger *log, MSICall *call, const MSIMessage *msg);
static void handle_push(MSICall *call, const MSIMessage *msg); static void handle_pop(const Logger *log, MSICall *call, const MSIMessage *msg);
static void handle_pop(MSICall *call, const MSIMessage *msg); static void handle_msi_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
static void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *user_data); void *user_data);
/* /*
* Public functions * Public functions
@ -99,43 +104,43 @@ void msi_callback_capabilities(MSISession *session, msi_action_cb *callback)
session->capabilities_callback = 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; return nullptr;
} }
MSISession *retu = (MSISession *)calloc(1, sizeof(MSISession)); MSISession *retu = (MSISession *)calloc(1, sizeof(MSISession));
if (retu == nullptr) { if (retu == nullptr) {
LOGGER_ERROR(m->log, "Allocation failed! Program might misbehave!"); LOGGER_ERROR(log, "Allocation failed! Program might misbehave!");
return nullptr; return nullptr;
} }
if (create_recursive_mutex(retu->mutex) != 0) { 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); free(retu);
return nullptr; return nullptr;
} }
retu->messenger = m; retu->tox = tox;
m_callback_msi_packet(m, handle_msi_packet, retu); // register callback
tox_callback_friend_lossless_packet_per_pktid(tox, handle_msi_packet, PACKET_ID_MSI);
/* This is called when remote terminates session */ LOGGER_DEBUG(log, "New msi session: %p ", (void *)retu);
m_callback_connectionstatus_internal_av(m, on_peer_status, retu);
LOGGER_DEBUG(m->log, "New msi session: %p ", (void *)retu);
return retu; return retu;
} }
int msi_kill(MSISession *session, const Logger *log)
int msi_kill(const Logger *log, Tox *tox, MSISession *session)
{ {
if (session == nullptr) { if (session == nullptr) {
LOGGER_ERROR(log, "Tried to terminate non-existing session"); LOGGER_ERROR(log, "Tried to terminate non-existing session");
return -1; 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) { if (pthread_mutex_trylock(session->mutex) != 0) {
LOGGER_ERROR(log, "Failed to acquire lock on msi mutex"); 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); MSICall *it = get_call(session, session->calls_head);
while (it != nullptr) { while (it != nullptr) {
send_message(session->messenger, it->friend_number, &msg); send_message(log, session->tox, it->friend_number, &msg);
MSICall *temp_it = it; MSICall *temp_it = it;
it = it->next; 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); free(session);
return 0; 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) { if (session == nullptr) {
return -1; 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) { 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; return -1;
} }
if (get_call(session, friend_number) != nullptr) { 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); pthread_mutex_unlock(session->mutex);
return -1; return -1;
} }
@ -197,17 +238,18 @@ int msi_invite(MSISession *session, MSICall **call, uint32_t friend_number, uint
msg.capabilities.exists = true; msg.capabilities.exists = true;
msg.capabilities.value = capabilities; 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; temp->state = MSI_CALL_REQUESTING;
*call = temp; *call = temp;
LOGGER_DEBUG(session->messenger->log, "Invite sent"); LOGGER_DEBUG(log, "Invite sent");
pthread_mutex_unlock(session->mutex); pthread_mutex_unlock(session->mutex);
return 0; return 0;
} }
int msi_hangup(MSICall *call)
int msi_hangup(const Logger *log, MSICall *call)
{ {
if (call == nullptr || call->session == nullptr) { if (call == nullptr || call->session == nullptr) {
return -1; return -1;
@ -215,16 +257,16 @@ int msi_hangup(MSICall *call)
MSISession *session = call->session; 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); call->friend_number);
if (pthread_mutex_trylock(session->mutex) != 0) { 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; return -1;
} }
if (call->state == MSI_CALL_INACTIVE) { 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); pthread_mutex_unlock(session->mutex);
return -1; return -1;
} }
@ -232,13 +274,14 @@ int msi_hangup(MSICall *call)
MSIMessage msg; MSIMessage msg;
msg_init(&msg, REQU_POP); 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); pthread_mutex_unlock(session->mutex);
return 0; 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) { if (call == nullptr || call->session == nullptr) {
return -1; return -1;
@ -246,18 +289,18 @@ int msi_answer(MSICall *call, uint8_t capabilities)
MSISession *session = call->session; 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); call->friend_number);
if (pthread_mutex_trylock(session->mutex) != 0) { 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; return -1;
} }
if (call->state != MSI_CALL_REQUESTED) { if (call->state != MSI_CALL_REQUESTED) {
/* Though sending in invalid state will not cause anything weird /* Though sending in invalid state will not cause anything weird
* Its better to not do it like a maniac */ * 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); pthread_mutex_unlock(session->mutex);
return -1; return -1;
} }
@ -270,14 +313,15 @@ int msi_answer(MSICall *call, uint8_t capabilities)
msg.capabilities.exists = true; msg.capabilities.exists = true;
msg.capabilities.value = capabilities; 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; call->state = MSI_CALL_ACTIVE;
pthread_mutex_unlock(session->mutex); pthread_mutex_unlock(session->mutex);
return 0; 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) { if (call == nullptr || call->session == nullptr) {
return -1; return -1;
@ -285,16 +329,16 @@ int msi_change_capabilities(MSICall *call, uint8_t capabilities)
MSISession *session = call->session; 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); call->friend_number);
if (pthread_mutex_trylock(session->mutex) != 0) { 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; return -1;
} }
if (call->state != MSI_CALL_ACTIVE) { 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); pthread_mutex_unlock(session->mutex);
return -1; return -1;
} }
@ -307,7 +351,7 @@ int msi_change_capabilities(MSICall *call, uint8_t capabilities)
msg.capabilities.exists = true; msg.capabilities.exists = true;
msg.capabilities.value = capabilities; 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); pthread_mutex_unlock(session->mutex);
return 0; return 0;
@ -351,10 +395,51 @@ static bool check_enum_high(const Logger *log, const uint8_t *bytes, uint8_t enu
return true; 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) 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 */ /* Parse raw data received from socket into MSIMessage struct */
assert(dest != nullptr); assert(dest != nullptr);
if (length == 0 || data[length - 1] != 0) { /* End byte must have value 0 */ 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; int size_constraint = length;
while (*it != 0) {/* until end byte is hit */ while (*it != 0) {/* until end byte is hit */
switch (*it) { it = msg_parse_one(log, dest, it, &size_constraint);
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]; if (it == nullptr) {
dest->request.exists = true; return -1;
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;
}
dest->capabilities.value = it[2];
dest->capabilities.exists = true;
it += 3;
break;
}
default: {
LOGGER_ERROR(log, "Invalid id byte");
return -1;
}
} }
} }
@ -418,6 +467,7 @@ static int msg_parse_in(const Logger *log, MSIMessage *dest, const uint8_t *data
return 0; return 0;
} }
static uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const uint8_t *value, uint8_t value_len, static uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const uint8_t *value, uint8_t value_len,
uint16_t *length) 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 */ 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)
{
/* Parse and send message */
assert(m != nullptr);
/* 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)
{
// 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 parsed[MSI_MAXMSG_SIZE];
uint8_t *it = parsed; 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, it = msg_parse_header_out(ID_REQUEST, it, &cast,
sizeof(cast), &size); sizeof(cast), &size);
} else { } else {
LOGGER_DEBUG(m->log, "Must have request field"); LOGGER_DEBUG(log, "Must have request field");
return -1; return -1;
} }
@ -468,26 +555,27 @@ static int send_message(const Messenger *m, uint32_t friend_number, const MSIMes
} }
if (it == parsed) { if (it == parsed) {
LOGGER_WARNING(m->log, "Parsing message failed; empty message"); LOGGER_WARNING(log, "Parsing message failed; empty message");
return -1; return -1;
} }
*it = 0; *it = 0;
++size; ++size;
if (m_msi_packet(m, friend_number, parsed, size)) { if (m_msi_packet(tox, friend_number, parsed, size) == 1) {
LOGGER_DEBUG(m->log, "Sent message"); LOGGER_DEBUG(log, "Sent message");
return 0; return 0;
} }
return -1; return -1;
} }
static int send_error(const Messenger *m, uint32_t friend_number, MSIError error)
{
/* Send error message */
assert(m != nullptr);
LOGGER_DEBUG(m->log, "Sending error: %d to friend: %d", error, friend_number); static int send_error(const Logger *log, Tox *tox, uint32_t friend_number, MSIError error)
{
assert(tox != nullptr);
/* Send error message */
LOGGER_DEBUG(log, "Sending error: %d to friend: %d", error, friend_number);
MSIMessage msg; MSIMessage msg;
msg_init(&msg, REQU_POP); 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.exists = true;
msg.error.value = error; msg.error.value = error;
send_message(m, friend_number, &msg); send_message(log, tox, friend_number, &msg);
return 0; 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; MSISession *session = call->session;
LOGGER_DEBUG(session->messenger->log, "invoking callback function: %d", id); LOGGER_DEBUG(log, "invoking callback function: %d", id);
switch (id) { switch (id) {
case MSI_ON_INVITE: case MSI_ON_INVITE:
@ -523,15 +612,16 @@ static int invoke_callback_inner(MSICall *call, MSICallbackID id)
return session->capabilities_callback(session->av, call); 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; return -1;
} }
static bool invoke_callback(MSICall *call, MSICallbackID cb)
static bool invoke_callback(const Logger *log, MSICall *call, MSICallbackID cb)
{ {
assert(call != nullptr); assert(call != nullptr);
if (invoke_callback_inner(call, cb) != 0) { if (invoke_callback_inner(log, call, cb) != 0) {
LOGGER_WARNING(call->session->messenger->log, LOGGER_WARNING(log,
"Callback state handling failed, sending error"); "Callback state handling failed, sending error");
/* If no callback present or error happened while handling, /* If no callback present or error happened while handling,
@ -546,6 +636,7 @@ static bool invoke_callback(MSICall *call, MSICallbackID cb)
return true; return true;
} }
static MSICall *get_call(MSISession *session, uint32_t friend_number) static MSICall *get_call(MSISession *session, uint32_t friend_number)
{ {
assert(session != nullptr); assert(session != nullptr);
@ -556,6 +647,7 @@ static MSICall *get_call(MSISession *session, uint32_t friend_number)
return session->calls[friend_number]; return session->calls[friend_number];
} }
static MSICall *new_call(MSISession *session, uint32_t friend_number) static MSICall *new_call(MSISession *session, uint32_t friend_number)
{ {
assert(session != nullptr); assert(session != nullptr);
@ -607,7 +699,8 @@ static MSICall *new_call(MSISession *session, uint32_t friend_number)
session->calls[friend_number] = rc; session->calls[friend_number] = rc;
return rc; return rc;
} }
static void kill_call(MSICall *call)
static void kill_call(const Logger *log, MSICall *call)
{ {
/* Assume that session mutex is locked */ /* Assume that session mutex is locked */
if (call == nullptr) { if (call == nullptr) {
@ -616,7 +709,7 @@ static void kill_call(MSICall *call)
MSISession *session = call->session; 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 *prev = call->prev;
MSICall *next = call->next; MSICall *next = call->next;
@ -648,37 +741,12 @@ CLEAR_CONTAINER:
free(call); free(call);
session->calls = nullptr; session->calls = nullptr;
} }
static void on_peer_status(Messenger *m, uint32_t friend_number, bool is_online, void *user_data)
static bool try_handle_init(const Logger *log, MSICall *call, const MSIMessage *msg)
{ {
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)
{
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) { 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; call->error = MSI_E_INVALID_MESSAGE;
return false; return false;
} }
@ -689,7 +757,7 @@ static bool try_handle_init(MSICall *call, const MSIMessage *msg)
call->peer_capabilities = msg->capabilities.value; call->peer_capabilities = msg->capabilities.value;
call->state = MSI_CALL_REQUESTED; call->state = MSI_CALL_REQUESTED;
if (!invoke_callback(call, MSI_ON_INVITE)) { if (!invoke_callback(log, call, MSI_ON_INVITE)) {
return false; return false;
} }
@ -704,7 +772,7 @@ static bool try_handle_init(MSICall *call, const MSIMessage *msg)
* we can automatically answer the re-call. * 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; MSIMessage out_msg;
msg_init(&out_msg, REQU_PUSH); 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.exists = true;
out_msg.capabilities.value = call->self_capabilities; 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 /* If peer changed capabilities during re-call they will
* be handled accordingly during the next step * 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_REQUESTED: // fall-through
case MSI_CALL_REQUESTING: { 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; call->error = MSI_E_INVALID_STATE;
return false; return false;
} }
@ -730,26 +798,28 @@ static bool try_handle_init(MSICall *call, const MSIMessage *msg)
return true; 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); assert(call != nullptr);
LOGGER_DEBUG(call->session->messenger->log, LOGGER_DEBUG(log,
"Session: %p Handling 'init' friend: %d", (void *)call->session, call->friend_number); "Session: %p Handling 'init' friend: %d", (void *)call->session, call->friend_number);
if (!try_handle_init(call, msg)) { if (!try_handle_init(log, call, msg)) {
send_error(call->session->messenger, call->friend_number, call->error); send_error(log, call->session->tox, call->friend_number, call->error);
kill_call(call); 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); 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); call->friend_number);
if (!msg->capabilities.exists) { 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; call->error = MSI_E_INVALID_MESSAGE;
goto FAILURE; goto FAILURE;
} }
@ -757,12 +827,11 @@ static void handle_push(MSICall *call, const MSIMessage *msg)
switch (call->state) { switch (call->state) {
case MSI_CALL_ACTIVE: { case MSI_CALL_ACTIVE: {
if (call->peer_capabilities != msg->capabilities.value) { if (call->peer_capabilities != msg->capabilities.value) {
/* Only act if capabilities changed */ LOGGER_INFO(log, "Friend is changing capabilities to: %u", msg->capabilities.value);
LOGGER_INFO(call->session->messenger->log, "Friend is changing capabilities to: %u", msg->capabilities.value);
call->peer_capabilities = 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; goto FAILURE;
} }
} }
@ -771,13 +840,13 @@ static void handle_push(MSICall *call, const MSIMessage *msg)
} }
case MSI_CALL_REQUESTING: { case MSI_CALL_REQUESTING: {
LOGGER_INFO(call->session->messenger->log, "Friend answered our call"); LOGGER_INFO(log, "Friend answered our call");
/* Call started */ /* Call started */
call->peer_capabilities = msg->capabilities.value; call->peer_capabilities = msg->capabilities.value;
call->state = MSI_CALL_ACTIVE; call->state = MSI_CALL_ACTIVE;
if (!invoke_callback(call, MSI_ON_START)) { if (!invoke_callback(log, call, MSI_ON_START)) {
goto FAILURE; goto FAILURE;
} }
@ -786,8 +855,7 @@ static void handle_push(MSICall *call, const MSIMessage *msg)
case MSI_CALL_INACTIVE: // fall-through case MSI_CALL_INACTIVE: // fall-through
case MSI_CALL_REQUESTED: { case MSI_CALL_REQUESTED: {
/* Pushes during initialization state are ignored */ LOGGER_WARNING(log, "Ignoring invalid push");
LOGGER_WARNING(call->session->messenger->log, "Ignoring invalid push");
break; break;
} }
} }
@ -795,76 +863,102 @@ static void handle_push(MSICall *call, const MSIMessage *msg)
return; return;
FAILURE: FAILURE:
send_error(call->session->messenger, call->friend_number, call->error); send_error(log, call->session->tox, call->friend_number, call->error);
kill_call(call); 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); 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); call->friend_number);
/* callback errors are ignored */ /* callback errors are ignored */
if (msg->error.exists) { 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; call->error = msg->error.value;
invoke_callback(call, MSI_ON_ERROR); invoke_callback(log, call, MSI_ON_ERROR);
} else { } else {
switch (call->state) { switch (call->state) {
case MSI_CALL_INACTIVE: { 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; break;
} }
case MSI_CALL_ACTIVE: { case MSI_CALL_ACTIVE: {
/* Hangup */ /* Hangup */
LOGGER_INFO(call->session->messenger->log, "Friend hung up on us"); LOGGER_INFO(log, "Friend hung up on us");
invoke_callback(call, MSI_ON_END); invoke_callback(log, call, MSI_ON_END);
break; break;
} }
case MSI_CALL_REQUESTING: { case MSI_CALL_REQUESTING: {
/* Reject */ /* Reject */
LOGGER_INFO(call->session->messenger->log, "Friend rejected our call"); LOGGER_INFO(log, "Friend rejected our call");
invoke_callback(call, MSI_ON_END); invoke_callback(log, call, MSI_ON_END);
break; break;
} }
case MSI_CALL_REQUESTED: { case MSI_CALL_REQUESTED: {
/* Cancel */ /* Cancel */
LOGGER_INFO(call->session->messenger->log, "Friend canceled call invite"); LOGGER_INFO(log, "Friend canceled call invite");
invoke_callback(call, MSI_ON_END); invoke_callback(log, call, MSI_ON_END);
break; 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);
LOGGER_DEBUG(m->log, "Got msi message"); if (toxav == nullptr) {
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);
return; return;
} }
LOGGER_DEBUG(m->log, "Successfully parsed message"); 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;
}
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(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(log, "Successfully parsed message");
pthread_mutex_lock(session->mutex); pthread_mutex_lock(session->mutex);
MSICall *call = get_call(session, friend_number); MSICall *call = get_call(session, friend_number);
if (call == nullptr) { if (call == nullptr) {
if (msg.request.value != REQU_INIT) { 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); pthread_mutex_unlock(session->mutex);
return; return;
} }
@ -872,7 +966,7 @@ static void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_
call = new_call(session, friend_number); call = new_call(session, friend_number);
if (call == nullptr) { 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); pthread_mutex_unlock(session->mutex);
return; return;
} }
@ -880,17 +974,17 @@ static void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_
switch (msg.request.value) { switch (msg.request.value) {
case REQU_INIT: { case REQU_INIT: {
handle_init(call, &msg); handle_init(log, call, &msg);
break; break;
} }
case REQU_PUSH: { case REQU_PUSH: {
handle_push(call, &msg); handle_push(log, call, &msg);
break; break;
} }
case REQU_POP: { case REQU_POP: {
handle_pop(call, &msg); /* always kills the call */ handle_pop(log, call, &msg); /* always kills the call */
break; break;
} }
} }

View File

@ -11,7 +11,6 @@
#include "audio.h" #include "audio.h"
#include "video.h" #include "video.h"
#include "../toxcore/Messenger.h"
#include "../toxcore/logger.h" #include "../toxcore/logger.h"
/** /**
@ -42,22 +41,22 @@ typedef enum MSICapabilities {
* Call state identifiers. * Call state identifiers.
*/ */
typedef enum MSICallState { typedef enum MSICallState {
MSI_CALL_INACTIVE, /* Default */ MSI_CALL_INACTIVE = 0, /* Default */
MSI_CALL_ACTIVE, MSI_CALL_ACTIVE = 1,
MSI_CALL_REQUESTING, /* when sending call invite */ MSI_CALL_REQUESTING = 2, /* when sending call invite */
MSI_CALL_REQUESTED, /* when getting call invite */ MSI_CALL_REQUESTED = 3, /* when getting call invite */
} MSICallState; } MSICallState;
/** /**
* Callbacks ids that handle the states * Callbacks ids that handle the states
*/ */
typedef enum MSICallbackID { typedef enum MSICallbackID {
MSI_ON_INVITE, /* Incoming call */ MSI_ON_INVITE = 0, /* Incoming call */
MSI_ON_START, /* Call (RTP transmission) started */ MSI_ON_START = 1, /* Call (RTP transmission) started */
MSI_ON_END, /* Call that was active ended */ MSI_ON_END = 2, /* Call that was active ended */
MSI_ON_ERROR, /* On protocol error */ MSI_ON_ERROR = 3, /* On protocol error */
MSI_ON_PEERTIMEOUT, /* Peer timed out; stop the call */ MSI_ON_PEERTIMEOUT = 4, /* Peer timed out; stop the call */
MSI_ON_CAPABILITIES, /* Peer requested capabilities change */ MSI_ON_CAPABILITIES = 5, /* Peer requested capabilities change */
} MSICallbackID; } MSICallbackID;
/** /**
@ -96,7 +95,7 @@ typedef struct MSISession {
uint32_t calls_head; uint32_t calls_head;
void *av; void *av;
Messenger *messenger; Tox *tox;
pthread_mutex_t mutex[1]; pthread_mutex_t mutex[1];
@ -111,11 +110,11 @@ typedef struct MSISession {
/** /**
* Start the control session. * 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 * 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. * Callback setters.
*/ */
@ -128,18 +127,20 @@ void msi_callback_capabilities(MSISession *session, msi_action_cb *callback);
/** /**
* Send invite request to friend_number. * 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 * Hangup call. NOTE: `call` will be freed
*/ */
int msi_hangup(MSICall *call); int msi_hangup(const Logger *log, MSICall *call);
/** /**
* Answer call request. * 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. * 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 */ #endif /* C_TOXCORE_TOXAV_MSI_H */

View File

@ -9,12 +9,16 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "bwcontroller.h" #include <sodium.h>
#include "bwcontroller.h"
#include "toxav_hacks.h"
#include "../toxcore/Messenger.h"
#include "../toxcore/ccompat.h" #include "../toxcore/ccompat.h"
#include "../toxcore/logger.h" #include "../toxcore/logger.h"
#include "../toxcore/mono_time.h" #include "../toxcore/mono_time.h"
#include "../toxcore/net_crypto.h"
#include "../toxcore/tox_private.h"
#include "../toxcore/util.h" #include "../toxcore/util.h"
/** /**
@ -23,30 +27,15 @@
*/ */
#define VIDEO_KEEP_KEYFRAME_IN_BUFFER_FOR_MS 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! // allocate_len is NOT including header!
static struct RTPMessage *new_message(const struct RTPHeader *header, size_t allocate_len, const uint8_t *data, static struct RTPMessage *new_message(const Logger *log, const struct RTPHeader *header, size_t allocate_len,
uint16_t data_length) const uint8_t *data, uint16_t data_length)
{ {
assert(allocate_len >= data_length); assert(allocate_len >= data_length);
struct RTPMessage *msg = (struct RTPMessage *)calloc(1, sizeof(struct RTPMessage) + allocate_len); struct RTPMessage *msg = (struct RTPMessage *)calloc(1, sizeof(struct RTPMessage) + allocate_len);
if (msg == nullptr) { if (msg == nullptr) {
LOGGER_DEBUG(log, "Could not allocate RTPMessage buffer");
return nullptr; 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 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 slot_id The slot we want to fill the data into.
* @param is_keyframe Whether the data is part of a key frame. * @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; 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) { if (session->first_packets_counter < DISMISS_FIRST_LOST_VIDEO_PACKET_COUNT) {
++session->first_packets_counter; ++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); bwc_add_recv(session->bwc, data_length_full);
if (received_length_full < 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); 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 -1 on error.
* @retval 0 on success. * @retval 0 on success.
*/ */
static int handle_video_packet(RTPSession *session, const struct RTPHeader *header, static int handle_video_packet(const Logger *log, RTPSession *session, const struct RTPHeader *header,
const uint8_t *incoming_data, uint16_t incoming_data_length, const Logger *log) const uint8_t *incoming_data, uint16_t incoming_data_length)
{ {
// Full frame length in bytes. The frame may be split into multiple packets, // Full frame length in bytes. The frame may be split into multiple packets,
// but this value is the complete assembled frame size. // but this value is the complete assembled frame size.
const uint32_t full_frame_length = header->data_length_full; 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. // The sender tells us whether this is a key frame.
const bool is_keyframe = (header->flags & RTP_KEY_FRAME) != 0; 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); 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; 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. // get_slot just told us it's full, so process_frame must return non-null.
assert(m_new != nullptr); 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]); LOGGER_DEBUG(log, "-- handle_video_packet -- CALLBACK-001a b0=%d b1=%d", (int)m_new->data[0],
update_bwc_values(log, session, m_new); (int)m_new->data[1]);
update_bwc_values(session, m_new);
// Pass ownership of m_new to the callback. // 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. // Now we no longer own m_new.
m_new = nullptr; 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); struct RTPMessage *m_new = process_frame(log, session->work_buffer_list, slot_id);
if (m_new != nullptr) { 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]); LOGGER_DEBUG(log, "-- handle_video_packet -- CALLBACK-003a b0=%d b1=%d", (int)m_new->data[0],
update_bwc_values(log, session, m_new); (int)m_new->data[1]);
session->mcb(session->m->mono_time, session->cs, m_new); 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; m_new = nullptr;
} }
@ -436,80 +425,113 @@ static int handle_video_packet(RTPSession *session, const struct RTPHeader *head
} }
/** /**
* @retval -1 on error. * receive custom lossypackets and process them. they can be incoming audio or video packets
* @retval 0 on success.
*/ */
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) { if (toxav == nullptr) {
LOGGER_WARNING(m->log, "No session or invalid length of received buffer!"); // LOGGER_WARNING(log, "ToxAV is NULL!");
return -1; 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. // Get the packet type.
const uint8_t packet_type = data[0]; const uint8_t packet_type = data[0];
++data; const uint8_t *payload = &data[1];
--length; // TODO(Zoff): is this ok?
const uint16_t payload_size = (uint16_t)length - 1;
// Unpack the header. // Unpack the header.
struct RTPHeader header; struct RTPHeader header;
rtp_header_unpack(data, &header); rtp_header_unpack(payload, &header);
if (header.pt != packet_type % 128) { 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); header.pt, packet_type % 128);
return -1; return;
} }
if (header.pt != session->payload_type % 128) { 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); header.pt, session->payload_type % 128);
return -1; return;
} }
if ((header.flags & RTP_LARGE_FRAME) != 0 && header.offset_full >= header.data_length_full) { 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); (unsigned)header.offset_full, (unsigned)header.data_length_full);
return -1; return;
} }
if (header.offset_lower >= header.data_length_lower) { 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); (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 // The sender uses the new large-frame capable protocol and is sending a
// video packet. // video packet.
if ((header.flags & RTP_LARGE_FRAME) != 0 && header.pt == (RTP_TYPE_VIDEO % 128)) { 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 ------------------ // 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 */ /* The message is sent in single part */
/* Message is not late; pick up the latest parameters */ /* Message is not late; pick up the latest parameters */
session->rsequnum = header.sequnum; session->rsequnum = header.sequnum;
session->rtimestamp = header.timestamp; session->rtimestamp = header.timestamp;
bwc_add_recv(session->bwc, length); bwc_add_recv(session->bwc, payload_size);
/* Invoke processing of active multiparted message */ /* Invoke processing of active multiparted message */
if (session->mp != nullptr) { 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; session->mp = nullptr;
} }
/* The message came in the allowed time; /* The message came in the allowed time;
*/ */
return session->mcb(session->m->mono_time, session->cs, new_message(&header, length - RTP_HEADER_SIZE, session->mp = new_message(log, &header, payload_size - RTP_HEADER_SIZE, &payload[RTP_HEADER_SIZE], payload_size - RTP_HEADER_SIZE);
data + RTP_HEADER_SIZE, length - 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 */ /* 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 */ /* First case */
/* Make sure we have enough allocated memory */ /* 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) { session->mp->header.data_length_lower <= header.offset_lower) {
/* There happened to be some corruption on the stream; /* There happened to be some corruption on the stream;
* continue wihtout this part * continue wihtout this part
*/ */
return 0; return;
} }
memcpy(session->mp->data + header.offset_lower, data + RTP_HEADER_SIZE, memcpy(session->mp->data + header.offset_lower, &payload[RTP_HEADER_SIZE],
length - RTP_HEADER_SIZE); payload_size - RTP_HEADER_SIZE);
session->mp->len += length - RTP_HEADER_SIZE; session->mp->len += payload_size - RTP_HEADER_SIZE;
bwc_add_recv(session->bwc, length); bwc_add_recv(session->bwc, payload_size);
if (session->mp->len == session->mp->header.data_length_lower) { if (session->mp->len == session->mp->header.data_length_lower) {
/* Received a full message; now push it for the further /* Received a full message; now push it for the further
* processing. * 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; session->mp = nullptr;
} }
} else { } 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; /* The received message part is from the old message;
* discard it. * discard it.
*/ */
return 0; return;
} }
/* Push the previous message for processing */ /* 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; session->mp = nullptr;
goto NEW_MULTIPARTED; goto NEW_MULTIPARTED;
} }
} else { } 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 */ /* This is also a point for new multiparted messages */
NEW_MULTIPARTED: NEW_MULTIPARTED:
@ -571,21 +597,21 @@ NEW_MULTIPARTED:
/* Message is not late; pick up the latest parameters */ /* Message is not late; pick up the latest parameters */
session->rsequnum = header.sequnum; session->rsequnum = header.sequnum;
session->rtimestamp = header.timestamp; session->rtimestamp = header.timestamp;
bwc_add_recv(session->bwc, length); bwc_add_recv(session->bwc, payload_size);
/* Store message. /* 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) { if (session->mp != nullptr) {
memmove(session->mp->data + header.offset_lower, session->mp->data, session->mp->len); memmove(session->mp->data + header.offset_lower, session->mp->data, session->mp->len);
} else { } else {
LOGGER_WARNING(m->log, "new_message() returned a null pointer"); LOGGER_WARNING(log, "new_message() returned a null pointer");
return -1; return;
} }
} }
return 0; return;
} }
size_t rtp_header_pack(uint8_t *const rdata, const struct RTPHeader *header) 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; 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) BWController *bwc, void *cs, rtp_m_cb *mcb)
{ {
assert(mcb != nullptr); assert(mcb != nullptr);
assert(cs != nullptr); assert(cs != nullptr);
assert(m != nullptr);
RTPSession *session = (RTPSession *)calloc(1, sizeof(RTPSession)); RTPSession *session = (RTPSession *)calloc(1, sizeof(RTPSession));
if (session == nullptr) { if (session == nullptr) {
LOGGER_WARNING(m->log, "Alloc failed! Program might misbehave!"); LOGGER_WARNING(log, "Alloc failed! Program might misbehave!");
return nullptr; return nullptr;
} }
session->work_buffer_list = (struct RTPWorkBufferList *)calloc(1, sizeof(struct RTPWorkBufferList)); session->work_buffer_list = (struct RTPWorkBufferList *)calloc(1, sizeof(struct RTPWorkBufferList));
if (session->work_buffer_list == nullptr) { 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); free(session);
return nullptr; return nullptr;
} }
@ -672,11 +703,12 @@ RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnum
// First entry is free. // First entry is free.
session->work_buffer_list->next_free_entry = 0; 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->payload_type = payload_type;
session->m = m;
session->tox = tox; session->tox = tox;
session->toxav = toxav;
session->friend_number = friendnumber; session->friend_number = friendnumber;
session->rtp_receive_active = true;
// set NULL just in case // set NULL just in case
session->mp = nullptr; session->mp = nullptr;
@ -687,26 +719,18 @@ RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnum
session->cs = cs; session->cs = cs;
session->mcb = mcb; 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; return session;
} }
void rtp_kill(RTPSession *session) void rtp_kill(const Logger *log, RTPSession *session)
{ {
if (session == nullptr) { if (session == nullptr) {
LOGGER_WARNING(log, "No session");
return; return;
} }
LOGGER_DEBUG(session->m->log, "Terminated RTP session: %p", (void *)session); LOGGER_DEBUG(log, "Terminated RTP session: %p", (void *)session);
rtp_stop_receiving(session); LOGGER_DEBUG(log, "Terminated RTP session V3 work_buffer_list->next_free_entry: %d",
LOGGER_DEBUG(session->m->log, "Terminated RTP session V3 work_buffer_list->next_free_entry: %d",
(int)session->work_buffer_list->next_free_entry); (int)session->work_buffer_list->next_free_entry);
for (int8_t i = 0; i < session->work_buffer_list->next_free_entry; ++i) { for (int8_t i = 0; i < session->work_buffer_list->next_free_entry; ++i) {
@ -716,36 +740,95 @@ void rtp_kill(RTPSession *session)
free(session); free(session);
} }
int rtp_allow_receiving(RTPSession *session) void rtp_allow_receiving_mark(RTPSession *session)
{ {
if (session == nullptr) { if (session != nullptr) {
return -1; 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;
}
LOGGER_DEBUG(session->m->log, "Started receiving on session: %p", (void *)session);
return 0;
} }
int rtp_stop_receiving(RTPSession *session) void rtp_stop_receiving_mark(RTPSession *session)
{ {
if (session == nullptr) { if (session != nullptr) {
return -1; session->rtp_receive_active = false;
}
}
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);
}
void rtp_stop_receiving(Tox *tox)
{
// 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);
Tox_Err_Friend_Custom_Packet error;
tox_friend_send_lossy_packet(tox, friend_number,
rdata, length + RTP_HEADER_SIZE + 1, &error);
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);
}
}
static struct RTPHeader rtp_default_header(const RTPSession *session, uint32_t length, bool is_keyframe)
{
uint16_t length_safe = (uint16_t)length;
if (length > UINT16_MAX) {
length_safe = UINT16_MAX;
} }
m_callback_rtp_packet(session->m, session->friend_number, session->payload_type, nullptr, nullptr); struct RTPHeader header = {0};
LOGGER_DEBUG(session->m->log, "Stopped receiving on session: %p", (void *)session); if (is_keyframe) {
return 0; header.flags |= RTP_KEY_FRAME;
}
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;
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;
header.data_length_lower = length_safe;
header.data_length_full = length; // without header
header.offset_lower = 0;
header.offset_full = 0;
return header;
} }
/** /**
* 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 session The A/V session to send the data for.
* @param data A byte array of length @p length. * @param data A byte array of length @p length.
@ -753,77 +836,27 @@ int rtp_stop_receiving(RTPSession *session)
* @param is_keyframe Whether this video frame is a key frame. If it is an * @param is_keyframe Whether this video frame is a key frame. If it is an
* audio frame, this parameter is ignored. * audio frame, this parameter is ignored.
*/ */
int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length, int rtp_send_data(const Logger *log, RTPSession *session, const uint8_t *data, uint32_t length,
bool is_keyframe, const Logger *log) bool is_keyframe)
{ {
if (session == nullptr) { if (session == nullptr) {
LOGGER_ERROR(log, "No session!");
return -1; return -1;
} }
struct RTPHeader header = {0};
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);
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;
}
const uint16_t rdata_size = min_u32(length + RTP_HEADER_SIZE + 1, MAX_CRYPTO_DATA_SIZE); const uint16_t rdata_size = min_u32(length + RTP_HEADER_SIZE + 1, MAX_CRYPTO_DATA_SIZE);
VLA(uint8_t, rdata, rdata_size); VLA(uint8_t, rdata, rdata_size);
memset(rdata, 0, rdata_size); memset(rdata, 0, rdata_size);
rdata[0] = session->payload_type; // packet id == payload_type 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)) { if (MAX_CRYPTO_DATA_SIZE > (length + RTP_HEADER_SIZE + 1)) {
/* /*
* The length is lesser than the maximum allowed length (including header) * The length is lesser than the maximum allowed length (including header)
* Send the packet in single piece. * Send the packet in single piece.
*/ */
rtp_header_pack(rdata + 1, &header); assert(length < UINT16_MAX);
memcpy(rdata + 1 + RTP_HEADER_SIZE, data, length); rtp_send_piece(log, session->tox, session->friend_number, &header, data, rdata, 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);
}
} else { } else {
/* /*
* The length is greater than the maximum allowed length (including header) * 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); uint16_t piece = MAX_CRYPTO_DATA_SIZE - (RTP_HEADER_SIZE + 1);
while ((length - sent) + RTP_HEADER_SIZE + 1 > MAX_CRYPTO_DATA_SIZE) { while ((length - sent) + RTP_HEADER_SIZE + 1 > MAX_CRYPTO_DATA_SIZE) {
rtp_header_pack(rdata + 1, &header); rtp_send_piece(log, session->tox, session->friend_number, &header, data + sent, rdata, piece);
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);
}
sent += piece; sent += piece;
header.offset_lower = sent; header.offset_lower = sent;
@ -853,16 +877,7 @@ int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length,
piece = length - sent; piece = length - sent;
if (piece != 0) { if (piece != 0) {
rtp_header_pack(rdata + 1, &header); rtp_send_piece(log, session->tox, session->friend_number, &header, data + sent, rdata, piece);
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);
}
} }
} }

View File

@ -9,7 +9,6 @@
#include "bwcontroller.h" #include "bwcontroller.h"
#include "../toxcore/Messenger.h"
#include "../toxcore/logger.h" #include "../toxcore/logger.h"
#include "../toxcore/tox.h" #include "../toxcore/tox.h"
@ -36,6 +35,11 @@ typedef enum RTP_Type {
RTP_TYPE_VIDEO = 193, RTP_TYPE_VIDEO = 193,
} RTP_Type; } 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 * A bit mask (up to 64 bits) specifying features of the current frame affecting
* the behaviour of the decoder. * the behaviour of the decoder.
@ -157,14 +161,19 @@ typedef struct RTPSession {
struct RTPMessage *mp; /* Expected parted message */ struct RTPMessage *mp; /* Expected parted message */
struct RTPWorkBufferList *work_buffer_list; struct RTPWorkBufferList *work_buffer_list;
uint8_t first_packets_counter; /* dismiss first few lost video packets */ uint8_t first_packets_counter; /* dismiss first few lost video packets */
Messenger *m; const Logger *log;
Tox *tox; Tox *tox;
ToxAV *toxav;
uint32_t friend_number; 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; BWController *bwc;
void *cs; void *cs;
rtp_m_cb *mcb; rtp_m_cb *mcb;
} RTPSession; } 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. * 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); 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); BWController *bwc, void *cs, rtp_m_cb *mcb);
void rtp_kill(RTPSession *session); void rtp_kill(const Logger *log, RTPSession *session);
int rtp_allow_receiving(RTPSession *session); void rtp_allow_receiving_mark(RTPSession *session);
int rtp_stop_receiving(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 session The A/V session to send the data for.
* @param data A byte array of length @p length. * @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 * @param is_keyframe Whether this video frame is a key frame. If it is an
* audio frame, this parameter is ignored. * audio frame, this parameter is ignored.
*/ */
int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length, int rtp_send_data(const Logger *log, RTPSession *session, const uint8_t *data, uint32_t length,
bool is_keyframe, const Logger *log); bool is_keyframe);
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@ -12,11 +12,15 @@
#include "msi.h" #include "msi.h"
#include "rtp.h" #include "rtp.h"
#include "toxav_hacks.h"
#include "../toxcore/Messenger.h"
#include "../toxcore/ccompat.h" #include "../toxcore/ccompat.h"
#include "../toxcore/logger.h" #include "../toxcore/logger.h"
#include "../toxcore/mono_time.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/tox_struct.h"
#include "../toxcore/util.h" #include "../toxcore/util.h"
@ -36,7 +40,12 @@
// iteration interval that is used when no call is active // iteration interval that is used when no call is active
#define IDLE_ITERATION_INTERVAL_MS 200 #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; ToxAV *av;
pthread_mutex_t mutex_audio[1]; pthread_mutex_t mutex_audio[1];
@ -63,7 +72,7 @@ typedef struct ToxAVCall {
struct ToxAVCall *prev; struct ToxAVCall *prev;
struct ToxAVCall *next; struct ToxAVCall *next;
} ToxAVCall; };
/** Decode time statistics */ /** Decode time statistics */
typedef struct DecodeTimeStats { typedef struct DecodeTimeStats {
@ -79,8 +88,8 @@ typedef struct DecodeTimeStats {
} DecodeTimeStats; } DecodeTimeStats;
struct ToxAV { struct ToxAV {
Logger *log;
Tox *tox; Tox *tox;
Messenger *m;
MSISession *msi; MSISession *msi;
/* Two-way storage: first is array of calls and second is list of calls with head and tail */ /* 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 */ /* keep track of decode times for audio and video */
DecodeTimeStats audio_stats; DecodeTimeStats audio_stats;
DecodeTimeStats video_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); 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 video_bit_rate_invalid(uint32_t bit_rate);
static bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state); 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_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 ToxAVCall *call_remove(ToxAVCall *call);
static bool call_prepare_transmission(ToxAVCall *call); static bool call_prepare_transmission(ToxAVCall *call);
static void call_kill_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 * @brief initialize d with default values
* @param d struct to be initialized, must not be nullptr * @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; 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)); av = (ToxAV *)calloc(1, sizeof(ToxAV));
if (av == nullptr) { if (av == nullptr) {
LOGGER_WARNING(m->log, "Allocation failed!");
rc = TOXAV_ERR_NEW_MALLOC; rc = TOXAV_ERR_NEW_MALLOC;
goto RETURN; goto RETURN;
} }
if (create_recursive_mutex(av->mutex) != 0) { if (create_recursive_mutex(av->mutex) != 0) {
LOGGER_WARNING(m->log, "Mutex creation failed!");
rc = TOXAV_ERR_NEW_MALLOC; rc = TOXAV_ERR_NEW_MALLOC;
goto RETURN; goto RETURN;
} }
av->log = tox->m->log;
av->tox = tox; 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->toxav_mono_time = mono_time_new(tox->sys.mem, nullptr, nullptr);
av->msi = msi_new(av->m);
if (av->msi == nullptr) { if (av->msi == nullptr) {
pthread_mutex_destroy(av->mutex); 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); init_decode_time_stats(&av->video_stats);
av->msi->av = av; 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_invite(av->msi, callback_invite);
msi_callback_start(av->msi, callback_start); msi_callback_start(av->msi, callback_start);
msi_callback_end(av->msi, callback_end); msi_callback_end(av->msi, callback_end);
@ -207,12 +256,15 @@ RETURN:
} }
if (rc != TOXAV_ERR_NEW_OK) { if (rc != TOXAV_ERR_NEW_OK) {
free(av); if (av != nullptr) {
av = nullptr; free(av);
av = nullptr;
}
} }
return av; return av;
} }
void toxav_kill(ToxAV *av) void toxav_kill(ToxAV *av)
{ {
if (av == nullptr) { if (av == nullptr) {
@ -221,8 +273,16 @@ void toxav_kill(ToxAV *av)
pthread_mutex_lock(av->mutex); 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 */ /* 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_unlock(av->mutex);
pthread_mutex_lock(av->mutex); pthread_mutex_lock(av->mutex);
} }
@ -243,13 +303,22 @@ void toxav_kill(ToxAV *av)
pthread_mutex_unlock(av->mutex); pthread_mutex_unlock(av->mutex);
pthread_mutex_destroy(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); free(av);
} }
Tox *toxav_get_tox(const ToxAV *av) Tox *toxav_get_tox(const ToxAV *av)
{ {
return av->tox; return av->tox;
} }
const Logger *toxav_get_logger(const ToxAV *av)
{
return av->log;
}
uint32_t toxav_audio_iteration_interval(const ToxAV *av) uint32_t toxav_audio_iteration_interval(const ToxAV *av)
{ {
return av->calls != nullptr ? av->audio_stats.interval : IDLE_ITERATION_INTERVAL_MS; 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) 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->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) { 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->count = 0;
stats->total = 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); 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; int32_t frame_time = IDLE_ITERATION_INTERVAL_MS;
for (ToxAVCall *i = av->calls[av->calls_head]; i != nullptr; i = i->next) { 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_lock(i->toxav_call_mutex);
pthread_mutex_unlock(av->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) { if (audio) {
ac_iterate(i->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_unlock(i->toxav_call_mutex);
pthread_mutex_lock(av->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; DecodeTimeStats *stats = audio ? &av->audio_stats : &av->video_stats;
calc_interval(av, stats, frame_time, start); calc_interval(av, stats, frame_time, start);
pthread_mutex_unlock(av->mutex); pthread_mutex_unlock(av->mutex);
} }
void toxav_audio_iterate(ToxAV *av) void toxav_audio_iterate(ToxAV *av)
{ {
iterate_common(av, true); 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 |= audio_bit_rate > 0 ? MSI_CAP_S_AUDIO : 0;
call->previous_self_capabilities |= video_bit_rate > 0 ? MSI_CAP_S_VIDEO : 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); call_remove(call);
rc = TOXAV_ERR_CALL_SYNC; rc = TOXAV_ERR_CALL_SYNC;
goto RETURN; goto RETURN;
@ -405,6 +483,7 @@ RETURN:
return rc == TOXAV_ERR_CALL_OK; return rc == TOXAV_ERR_CALL_OK;
} }
void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data) void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data)
{ {
pthread_mutex_lock(av->mutex); 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; av->ccb_user_data = user_data;
pthread_mutex_unlock(av->mutex); pthread_mutex_unlock(av->mutex);
} }
bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate,
Toxav_Err_Answer *error) 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; Toxav_Err_Answer rc = TOXAV_ERR_ANSWER_OK;
ToxAVCall *call; 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; rc = TOXAV_ERR_ANSWER_FRIEND_NOT_FOUND;
goto RETURN; 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 |= audio_bit_rate > 0 ? MSI_CAP_S_AUDIO : 0;
call->previous_self_capabilities |= video_bit_rate > 0 ? MSI_CAP_S_VIDEO : 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; rc = TOXAV_ERR_ANSWER_SYNC;
} }
@ -465,6 +545,7 @@ RETURN:
return rc == TOXAV_ERR_ANSWER_OK; return rc == TOXAV_ERR_ANSWER_OK;
} }
void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *user_data) void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *user_data)
{ {
pthread_mutex_lock(av->mutex); 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; av->scb_user_data = user_data;
pthread_mutex_unlock(av->mutex); pthread_mutex_unlock(av->mutex);
} }
static Toxav_Err_Call_Control call_control_handle_resume(const ToxAVCall *call) static Toxav_Err_Call_Control call_control_handle_resume(const ToxAVCall *call)
{ {
/* Only act if paused and had media transfer active before */ /* 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; 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; return TOXAV_ERR_CALL_CONTROL_SYNC;
} }
rtp_allow_receiving(call->audio_rtp); rtp_allow_receiving_mark(call->audio_rtp);
rtp_allow_receiving(call->video_rtp); rtp_allow_receiving_mark(call->video_rtp);
return TOXAV_ERR_CALL_CONTROL_OK; 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; 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; return TOXAV_ERR_CALL_CONTROL_SYNC;
} }
rtp_stop_receiving(call->audio_rtp); rtp_stop_receiving_mark(call->audio_rtp);
rtp_stop_receiving(call->video_rtp); rtp_stop_receiving_mark(call->video_rtp);
return TOXAV_ERR_CALL_CONTROL_OK; return TOXAV_ERR_CALL_CONTROL_OK;
} }
@ -511,7 +594,7 @@ static Toxav_Err_Call_Control call_control_handle_cancel(ToxAVCall *call)
/* Hang up */ /* Hang up */
pthread_mutex_lock(call->toxav_call_mutex); 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); pthread_mutex_unlock(call->toxav_call_mutex);
return TOXAV_ERR_CALL_CONTROL_SYNC; 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; 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) { msi_call->self_capabilities ^ MSI_CAP_R_AUDIO) == -1) {
return TOXAV_ERR_CALL_CONTROL_SYNC; 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; return TOXAV_ERR_CALL_CONTROL_OK;
} }
static Toxav_Err_Call_Control call_control_handle_unmute_audio(const ToxAVCall *call) 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; 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) { msi_call->self_capabilities | MSI_CAP_R_AUDIO) == -1) {
return TOXAV_ERR_CALL_CONTROL_SYNC; 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; return TOXAV_ERR_CALL_CONTROL_OK;
} }
static Toxav_Err_Call_Control call_control_handle_hide_video(const ToxAVCall *call) 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; 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) { msi_call->self_capabilities ^ MSI_CAP_R_VIDEO) == -1) {
return TOXAV_ERR_CALL_CONTROL_SYNC; 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; return TOXAV_ERR_CALL_CONTROL_OK;
} }
static Toxav_Err_Call_Control call_control_handle_show_video(const ToxAVCall *call) 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; 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) { msi_call->self_capabilities | MSI_CAP_R_VIDEO) == -1) {
return TOXAV_ERR_CALL_CONTROL_SYNC; 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; return TOXAV_ERR_CALL_CONTROL_OK;
} }
static Toxav_Err_Call_Control call_control_handle(ToxAVCall *call, Toxav_Call_Control control) 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) 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; 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; return rc == TOXAV_ERR_CALL_CONTROL_OK;
} }
bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_rate, 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 *error)
{ {
Toxav_Err_Bit_Rate_Set rc = TOXAV_ERR_BIT_RATE_SET_OK; Toxav_Err_Bit_Rate_Set rc = TOXAV_ERR_BIT_RATE_SET_OK;
ToxAVCall *call; 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; rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND;
goto RETURN; goto RETURN;
} }
@ -662,14 +746,14 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
goto RETURN; 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) { 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) { } 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) { self_capabilities ^ MSI_CAP_S_AUDIO) != 0) {
pthread_mutex_unlock(av->mutex); pthread_mutex_unlock(av->mutex);
rc = TOXAV_ERR_BIT_RATE_SET_SYNC; 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); pthread_mutex_lock(call->toxav_call_mutex);
if (call->audio_bit_rate == 0) { 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 */ /* 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) { msi_call->self_capabilities | MSI_CAP_S_AUDIO) != 0) {
pthread_mutex_unlock(call->toxav_call_mutex); pthread_mutex_unlock(call->toxav_call_mutex);
pthread_mutex_unlock(av->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; goto RETURN;
} }
} else { } 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; call->audio_bit_rate = bit_rate;
@ -709,13 +793,14 @@ RETURN:
return rc == TOXAV_ERR_BIT_RATE_SET_OK; return rc == TOXAV_ERR_BIT_RATE_SET_OK;
} }
bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_rate, 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 *error)
{ {
Toxav_Err_Bit_Rate_Set rc = TOXAV_ERR_BIT_RATE_SET_OK; Toxav_Err_Bit_Rate_Set rc = TOXAV_ERR_BIT_RATE_SET_OK;
ToxAVCall *call; 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; rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND;
goto RETURN; goto RETURN;
} }
@ -734,15 +819,15 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
goto RETURN; 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) { 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) { } 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 */ /* 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) { self_capabilities ^ MSI_CAP_S_VIDEO) != 0) {
pthread_mutex_unlock(av->mutex); pthread_mutex_unlock(av->mutex);
rc = TOXAV_ERR_BIT_RATE_SET_SYNC; 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); pthread_mutex_lock(call->toxav_call_mutex);
if (call->video_bit_rate == 0) { 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 */ /* 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) { msi_call->self_capabilities | MSI_CAP_S_VIDEO) != 0) {
pthread_mutex_unlock(call->toxav_call_mutex); pthread_mutex_unlock(call->toxav_call_mutex);
pthread_mutex_unlock(av->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; goto RETURN;
} }
} else { } 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; call->video_bit_rate = bit_rate;
@ -781,6 +866,7 @@ RETURN:
return rc == TOXAV_ERR_BIT_RATE_SET_OK; 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) void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback, void *user_data)
{ {
pthread_mutex_lock(av->mutex); 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; av->abcb_user_data = user_data;
pthread_mutex_unlock(av->mutex); pthread_mutex_unlock(av->mutex);
} }
void toxav_callback_video_bit_rate(ToxAV *av, toxav_video_bit_rate_cb *callback, void *user_data) void toxav_callback_video_bit_rate(ToxAV *av, toxav_video_bit_rate_cb *callback, void *user_data)
{ {
pthread_mutex_lock(av->mutex); 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; av->vbcb_user_data = user_data;
pthread_mutex_unlock(av->mutex); pthread_mutex_unlock(av->mutex);
} }
bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pcm, size_t sample_count, 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) uint8_t channels, uint32_t sampling_rate, Toxav_Err_Send_Frame *error)
{ {
Toxav_Err_Send_Frame rc = TOXAV_ERR_SEND_FRAME_OK; Toxav_Err_Send_Frame rc = TOXAV_ERR_SEND_FRAME_OK;
ToxAVCall *call; 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; rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND;
goto RETURN; 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)); dest + sizeof(sampling_rate), dest_size - sizeof(sampling_rate));
if (vrc < 0) { 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); pthread_mutex_unlock(call->mutex_audio);
rc = TOXAV_ERR_SEND_FRAME_INVALID; rc = TOXAV_ERR_SEND_FRAME_INVALID;
goto RETURN; goto RETURN;
} }
if (rtp_send_data(call->audio_rtp, dest, vrc + sizeof(sampling_rate), false, av->m->log) != 0) { if (rtp_send_data(av->log, call->audio_rtp, dest, vrc + sizeof(sampling_rate), false) != 0) {
LOGGER_WARNING(av->m->log, "Failed to send audio packet"); LOGGER_WARNING(av->log, "Failed to send audio packet");
rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED; rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED;
} }
} }
@ -882,7 +970,7 @@ RETURN:
return rc == TOXAV_ERR_SEND_FRAME_OK; 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; 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 uint32_t frame_length_in_bytes = pkt->data.frame.sz;
const int res = rtp_send_data( const int res = rtp_send_data(
av->log,
call->video_rtp, call->video_rtp,
(const uint8_t *)pkt->data.frame.buf, (const uint8_t *)pkt->data.frame.buf,
frame_length_in_bytes, frame_length_in_bytes,
is_keyframe, 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]);
if (res < 0) { if (res < 0) {
char *netstrerror = net_new_strerror(net_error()); 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); net_kill_strerror(netstrerror);
return TOXAV_ERR_SEND_FRAME_RTP_FAILED; 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; 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; rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND;
goto RETURN; goto RETURN;
} }
@ -965,7 +1048,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u
goto RETURN; 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); pthread_mutex_unlock(call->mutex_video);
rc = TOXAV_ERR_SEND_FRAME_INVALID; rc = TOXAV_ERR_SEND_FRAME_INVALID;
goto RETURN; 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) { if (call->video_rtp->ssrc < VIDEO_SEND_X_KEYFRAMES_FIRST) {
// Key frame flag for first frames // Key frame flag for first frames
vpx_encode_flags = VPX_EFLAG_FORCE_KF; 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; ++call->video_rtp->ssrc;
} else if (call->video_rtp->ssrc == VIDEO_SEND_X_KEYFRAMES_FIRST) { } else if (call->video_rtp->ssrc == VIDEO_SEND_X_KEYFRAMES_FIRST) {
// normal keyframe placement // normal keyframe placement
vpx_encode_flags = 0; 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; ++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) { if (vrc != VPX_CODEC_OK) {
pthread_mutex_unlock(call->mutex_video); 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; rc = TOXAV_ERR_SEND_FRAME_INVALID;
goto RETURN; 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; ++call->video->frame_counter;
rc = send_frames(av->m->log, call); rc = send_frames(av, call);
pthread_mutex_unlock(call->mutex_video); 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; ToxAVCall *call = (ToxAVCall *)user_data;
assert(call != nullptr); 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 less than 10% data loss we do nothing! */
if (loss < 0.1F) { 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->video_bit_rate != 0) {
if (call->av->vbcb == nullptr) { if (call->av->vbcb == nullptr) {
pthread_mutex_unlock(call->av->mutex); 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; return;
} }
@ -1085,7 +1168,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss,
} else if (call->audio_bit_rate != 0) { } else if (call->audio_bit_rate != 0) {
if (call->av->abcb == nullptr) { if (call->av->abcb == nullptr) {
pthread_mutex_unlock(call->av->mutex); 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; return;
} }
@ -1096,6 +1179,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss,
pthread_mutex_unlock(call->av->mutex); pthread_mutex_unlock(call->av->mutex);
} }
static int callback_invite(void *object, MSICall *call) static int callback_invite(void *object, MSICall *call)
{ {
ToxAV *toxav = (ToxAV *)object; 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); ToxAVCall *av_call = call_new(toxav, call->friend_number, nullptr);
if (av_call == 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); pthread_mutex_unlock(toxav->mutex);
return -1; return -1;
} }
@ -1124,6 +1208,7 @@ static int callback_invite(void *object, MSICall *call)
pthread_mutex_unlock(toxav->mutex); pthread_mutex_unlock(toxav->mutex);
return 0; return 0;
} }
static int callback_start(void *object, MSICall *call) static int callback_start(void *object, MSICall *call)
{ {
ToxAV *toxav = (ToxAV *)object; ToxAV *toxav = (ToxAV *)object;
@ -1152,6 +1237,7 @@ static int callback_start(void *object, MSICall *call)
pthread_mutex_unlock(toxav->mutex); pthread_mutex_unlock(toxav->mutex);
return 0; return 0;
} }
static int callback_end(void *object, MSICall *call) static int callback_end(void *object, MSICall *call)
{ {
ToxAV *toxav = (ToxAV *)object; ToxAV *toxav = (ToxAV *)object;
@ -1167,6 +1253,7 @@ static int callback_end(void *object, MSICall *call)
pthread_mutex_unlock(toxav->mutex); pthread_mutex_unlock(toxav->mutex);
return 0; return 0;
} }
static int callback_error(void *object, MSICall *call) static int callback_error(void *object, MSICall *call)
{ {
ToxAV *toxav = (ToxAV *)object; ToxAV *toxav = (ToxAV *)object;
@ -1182,21 +1269,22 @@ static int callback_error(void *object, MSICall *call)
pthread_mutex_unlock(toxav->mutex); pthread_mutex_unlock(toxav->mutex);
return 0; return 0;
} }
static int callback_capabilites(void *object, MSICall *call) static int callback_capabilites(void *object, MSICall *call)
{ {
ToxAV *toxav = (ToxAV *)object; ToxAV *toxav = (ToxAV *)object;
pthread_mutex_lock(toxav->mutex); pthread_mutex_lock(toxav->mutex);
if ((call->peer_capabilities & MSI_CAP_S_AUDIO) != 0) { 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 { } 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) { 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 { } 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); 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); pthread_mutex_unlock(toxav->mutex);
return 0; return 0;
} }
static bool audio_bit_rate_invalid(uint32_t bit_rate) static bool audio_bit_rate_invalid(uint32_t bit_rate)
{ {
/* Opus RFC 6716 section-2.1.1 dictates the following: /* 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; return bit_rate < 6 || bit_rate > 510;
} }
static bool video_bit_rate_invalid(uint32_t bit_rate) 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: /* 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; return bit_rate > UINT32_MAX;
} }
static bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state) static bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state)
{ {
if (av->scb != nullptr) { 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; Toxav_Err_Call rc = TOXAV_ERR_CALL_OK;
ToxAVCall *call = nullptr; 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; rc = TOXAV_ERR_CALL_FRIEND_NOT_FOUND;
goto RETURN; 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; rc = TOXAV_ERR_CALL_FRIEND_NOT_CONNECTED;
goto RETURN; goto RETURN;
} }
@ -1323,16 +1419,6 @@ RETURN:
return call; 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) static ToxAVCall *call_remove(ToxAVCall *call)
{ {
if (call == nullptr) { if (call == nullptr) {
@ -1399,7 +1485,7 @@ static bool call_prepare_transmission(ToxAVCall *call)
} }
if (call->active) { if (call->active) {
LOGGER_WARNING(av->m->log, "Call already active!"); LOGGER_WARNING(av->log, "Call already active!");
return true; return true;
} }
@ -1412,43 +1498,37 @@ static bool call_prepare_transmission(ToxAVCall *call)
} }
/* Prepare bwc */ /* Prepare bwc */
call->bwc = bwc_new(av->m, av->tox, call->friend_number, callback_bwc, call, av->toxav_mono_time); call->bwc = bwc_new(av->log, av->tox, call->friend_number, callback_bwc, call, av->toxav_mono_time);
if (call->bwc == nullptr) { { /* Prepare audio */
LOGGER_ERROR(av->m->log, "Failed to create new bwc"); call->audio = ac_new(av->toxav_mono_time, av->log, av, call->friend_number, av->acb, av->acb_user_data);
goto FAILURE;
}
{ /* Prepare audio */
call->audio = ac_new(av->toxav_mono_time, av->m->log, av, call->friend_number, av->acb, av->acb_user_data);
if (call->audio == nullptr) { 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; 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); call->audio, ac_queue_message);
if (call->audio_rtp == nullptr) { 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; goto FAILURE;
} }
} }
{ /* Prepare video */
{ /* Prepare video */ call->video = vc_new(av->log, av->toxav_mono_time, av, call->friend_number, av->vcb, av->vcb_user_data);
call->video = vc_new(av->toxav_mono_time, av->m->log, av, call->friend_number, av->vcb, av->vcb_user_data);
if (call->video == nullptr) { 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; 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); call->video, vc_queue_message);
if (call->video_rtp == nullptr) { 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; goto FAILURE;
} }
} }
@ -1458,11 +1538,11 @@ static bool call_prepare_transmission(ToxAVCall *call)
FAILURE: FAILURE:
bwc_kill(call->bwc); bwc_kill(call->bwc);
rtp_kill(call->audio_rtp); rtp_kill(av->log, call->audio_rtp);
ac_kill(call->audio); ac_kill(call->audio);
call->audio_rtp = nullptr; call->audio_rtp = nullptr;
call->audio = nullptr; call->audio = nullptr;
rtp_kill(call->video_rtp); rtp_kill(av->log, call->video_rtp);
vc_kill(call->video); vc_kill(call->video);
call->video_rtp = nullptr; call->video_rtp = nullptr;
call->video = nullptr; call->video = nullptr;
@ -1489,12 +1569,14 @@ static void call_kill_transmission(ToxAVCall *call)
bwc_kill(call->bwc); 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); ac_kill(call->audio);
call->audio_rtp = nullptr; call->audio_rtp = nullptr;
call->audio = nullptr; call->audio = nullptr;
rtp_kill(call->video_rtp); rtp_kill(av->log, call->video_rtp);
vc_kill(call->video); vc_kill(call->video);
call->video_rtp = nullptr; call->video_rtp = nullptr;
call->video = 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_audio);
pthread_mutex_destroy(call->mutex_video); 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;
}

View File

@ -73,6 +73,8 @@ typedef struct Tox Tox;
#endif /* !TOX_DEFINED */ #endif /* !TOX_DEFINED */
#endif /* !APIGEN_IGNORE */ #endif /* !APIGEN_IGNORE */
#ifndef TOXAV_DEFINED
#define TOXAV_DEFINED
/** /**
* @brief The ToxAV instance type. * @brief The ToxAV instance type.
* *
@ -83,6 +85,7 @@ typedef struct Tox Tox;
* notifying peers. * notifying peers.
*/ */
typedef struct ToxAV ToxAV; typedef struct ToxAV ToxAV;
#endif /* TOXAV_DEFINED */
/** @{ /** @{
* @brief Creation and destruction * @brief Creation and destruction
@ -246,9 +249,9 @@ typedef enum Toxav_Err_Call {
* receiving are both enabled by default. * receiving are both enabled by default.
* *
* @param friend_number The friend number of the friend that should be called. * @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. * 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. * video sending.
*/ */
bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, 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. * enabled by default.
* *
* @param friend_number The friend number of the friend that is calling. * @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. * 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. * video sending.
*/ */
bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, 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); 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 * @param friend_number The friend number of the friend for which to set the
* bit rate. * 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. * @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 * @param friend_number The friend number of the friend for which to set the
* bit rate. * 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); 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. * Send a video frame to a friend.
* *
* Y - plane should be of size: `height * width` * The video frame needs to be planar YUV420.
* U - plane should be of size: `(height/2) * (width/2)` * Y - plane should be of size: `width * height`
* V - plane should be of size: `(height/2) * (width/2)` * 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 * @param friend_number The friend number of the friend to which to send a video
* frame. * frame.
@ -641,9 +645,9 @@ void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback,
*/ */
bool toxav_video_send_frame( bool toxav_video_send_frame(
ToxAV *av, uint32_t friend_number, uint16_t width, uint16_t height, ToxAV *av, uint32_t friend_number, uint16_t width, uint16_t height,
const uint8_t y[/*! height * width */], const uint8_t y[/*! width * height */],
const uint8_t u[/*! height/2 * width/2 */], const uint8_t u[/*! width/2 * height/2 */],
const uint8_t v[/*! height/2 * width/2 */], const uint8_t v[/*! width/2 * height/2 */],
Toxav_Err_Send_Frame *error); 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 * @param friend_number The friend number of the friend for which to set the
* bit rate. * 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. * @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 * @param friend_number The friend number of the friend for which to set the
* bit rate. * 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); typedef void toxav_video_bit_rate_cb(ToxAV *av, uint32_t friend_number, uint32_t video_bit_rate, void *user_data);

View File

@ -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 */

View File

@ -143,7 +143,7 @@ static void vc_init_encoder_cfg(const Logger *log, vpx_codec_enc_cfg_t *cfg, int
#endif /* 0 */ #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) toxav_video_receive_frame_cb *cb, void *cb_data)
{ {
VCSession *vc = (VCSession *)calloc(1, sizeof(VCSession)); 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 /* 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); vc_init_encoder_cfg(log, &cfg, 1);
LOGGER_DEBUG(log, "Using VP8 codec for encoder (0.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 */ #endif /* 0 */
vc->linfts = current_time_monotonic(mono_time); vc->linfts = current_time_monotonic(mono_time);
vc->lcfd = 60; vc->lcfd = 60;
vc->vcb = cb; 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->av = av;
vc->log = log; vc->log = log;
return vc; return vc;
BASE_CLEANUP_1: BASE_CLEANUP_1:
vpx_codec_destroy(vc->decoder); vpx_codec_destroy(vc->decoder);
BASE_CLEANUP: BASE_CLEANUP:
pthread_mutex_destroy(vc->queue_mutex); pthread_mutex_destroy(vc->queue_mutex);
rb_kill(vc->vbuf_raw); rb_kill(vc->vbuf_raw);
free(vc); free(vc);
return nullptr; return nullptr;
} }

View File

@ -33,7 +33,6 @@ typedef struct VCSession {
uint64_t linfts; /* Last received frame time stamp */ uint64_t linfts; /* Last received frame time stamp */
uint32_t lcfd; /* Last calculated frame duration for incoming video payload */ uint32_t lcfd; /* Last calculated frame duration for incoming video payload */
const Logger *log;
ToxAV *av; ToxAV *av;
uint32_t friend_number; uint32_t friend_number;
@ -42,9 +41,10 @@ typedef struct VCSession {
void *vcb_user_data; void *vcb_user_data;
pthread_mutex_t queue_mutex[1]; pthread_mutex_t queue_mutex[1];
const Logger *log;
} VCSession; } 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); toxav_video_receive_frame_cb *cb, void *cb_data);
void vc_kill(VCSession *vc); void vc_kill(VCSession *vc);
void vc_iterate(VCSession *vc); void vc_iterate(VCSession *vc);

View File

@ -6,7 +6,7 @@ exports_files(
"tox.h", "tox.h",
"tox_private.h", "tox_private.h",
], ],
visibility = ["//c-toxcore:__pkg__"], visibility = ["//c-toxcore:__subpackages__"],
) )
cc_library( cc_library(
@ -121,6 +121,7 @@ cc_library(
deps = [ deps = [
":attributes", ":attributes",
":ccompat", ":ccompat",
":mem",
], ],
) )
@ -299,6 +300,18 @@ cc_library(
], ],
) )
cc_library(
name = "net_profile",
srcs = ["net_profile.c"],
hdrs = ["net_profile.h"],
deps = [
":attributes",
":ccompat",
":logger",
":mem",
],
)
cc_library( cc_library(
name = "network", name = "network",
srcs = ["network.c"], srcs = ["network.c"],
@ -318,6 +331,7 @@ cc_library(
":logger", ":logger",
":mem", ":mem",
":mono_time", ":mono_time",
":net_profile",
":util", ":util",
"@libsodium", "@libsodium",
"@psocket", "@psocket",
@ -332,6 +346,7 @@ cc_library(
hdrs = ["network_test_util.hh"], hdrs = ["network_test_util.hh"],
deps = [ deps = [
":crypto_core", ":crypto_core",
":mem",
":network", ":network",
":test_util", ":test_util",
], ],
@ -570,6 +585,7 @@ cc_library(
":crypto_core", ":crypto_core",
":logger", ":logger",
":mem", ":mem",
":net_profile",
":network", ":network",
], ],
) )
@ -597,6 +613,7 @@ cc_library(
":logger", ":logger",
":mem", ":mem",
":mono_time", ":mono_time",
":net_profile",
":network", ":network",
":onion", ":onion",
":util", ":util",
@ -618,6 +635,7 @@ cc_library(
":logger", ":logger",
":mem", ":mem",
":mono_time", ":mono_time",
":net_profile",
":network", ":network",
":util", ":util",
], ],
@ -640,6 +658,7 @@ cc_library(
":logger", ":logger",
":mem", ":mem",
":mono_time", ":mono_time",
":net_profile",
":network", ":network",
":onion", ":onion",
":util", ":util",
@ -661,7 +680,10 @@ cc_library(
name = "net_crypto", name = "net_crypto",
srcs = ["net_crypto.c"], srcs = ["net_crypto.c"],
hdrs = ["net_crypto.h"], hdrs = ["net_crypto.h"],
visibility = ["//c-toxcore/auto_tests:__pkg__"], visibility = [
"//c-toxcore/auto_tests:__pkg__",
"//c-toxcore/toxav:__pkg__",
],
deps = [ deps = [
":DHT", ":DHT",
":LAN_discovery", ":LAN_discovery",
@ -674,6 +696,7 @@ cc_library(
":logger", ":logger",
":mem", ":mem",
":mono_time", ":mono_time",
":net_profile",
":network", ":network",
":util", ":util",
"@pthread", "@pthread",
@ -993,6 +1016,7 @@ cc_library(
":DHT", ":DHT",
":Messenger", ":Messenger",
":TCP_client", ":TCP_client",
":TCP_server",
":attributes", ":attributes",
":ccompat", ":ccompat",
":crypto_core", ":crypto_core",
@ -1003,6 +1027,7 @@ cc_library(
":mem", ":mem",
":mono_time", ":mono_time",
":net_crypto", ":net_crypto",
":net_profile",
":network", ":network",
":onion_client", ":onion_client",
":state", ":state",

View File

@ -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); 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); mem_delete(mem, encrypted);
return -1; 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); mem_delete(mem, encrypted);
return -1; 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; plain[0] = num_nodes;
memcpy(plain + 1 + nodes_length, sendback_data, length); 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 uint16_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 data_size = 1 + nodes_length + length + crypto_size;
VLA(uint8_t, data, data_size); VLA(uint8_t, data, data_size);
const int len = dht_create_packet(dht->mem, dht->rng, const int len = dht_create_packet(dht->mem, dht->rng,
dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6, dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6,
plain, 1 + nodes_length + length, data, data_size); plain, 1 + nodes_length + length, data, data_size);
if (len != data_size) { if (len < 0 || (uint32_t)len != data_size) {
return -1; return -1;
} }
@ -1840,7 +1840,7 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key)
return dht_getnodes(dht, ip_port, public_key, dht->self_public_key); return dht_getnodes(dht, ip_port, public_key, dht->self_public_key);
} }
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dns_enabled,
uint16_t port, const uint8_t *public_key) uint16_t port, const uint8_t *public_key)
{ {
IP_Port ip_port_v64; IP_Port ip_port_v64;
@ -1855,7 +1855,7 @@ bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled,
ip_extra = &ip_port_v4.ip; ip_extra = &ip_port_v4.ip;
} }
if (addr_resolve_or_parse_ip(dht->ns, address, &ip_port_v64.ip, ip_extra)) { if (addr_resolve_or_parse_ip(dht->ns, dht->mem, address, &ip_port_v64.ip, ip_extra, dns_enabled)) {
ip_port_v64.port = port; ip_port_v64.port = port;
dht_bootstrap(dht, &ip_port_v64, public_key); dht_bootstrap(dht, &ip_port_v64, public_key);

View File

@ -404,12 +404,13 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key);
* @param address can be a hostname or an IP address (IPv4 or IPv6). * @param address can be a hostname or an IP address (IPv4 or IPv6).
* @param ipv6enabled if false, the resolving sticks STRICTLY to IPv4 addresses. * @param ipv6enabled if false, the resolving sticks STRICTLY to IPv4 addresses.
* Otherwise, the resolving looks for IPv6 addresses first, then IPv4 addresses. * Otherwise, the resolving looks for IPv6 addresses first, then IPv4 addresses.
* @param dns_enabled if false, the resolving does not use DNS, only IP addresses are supported.
* *
* @retval true if the address could be converted into an IP address * @retval true if the address could be converted into an IP address
* @retval false otherwise * @retval false otherwise
*/ */
non_null() non_null()
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dns_enabled,
uint16_t port, const uint8_t *public_key); uint16_t port, const uint8_t *public_key);
/** @brief Start sending packets after DHT loaded_friends_list and loaded_clients_list are set. /** @brief Start sending packets after DHT loaded_friends_list and loaded_clients_list are set.

View File

@ -31,7 +31,8 @@ void TestUnpackNodes(Fuzz_Data &input)
const int packed_count = unpack_nodes( const int packed_count = unpack_nodes(
nodes, node_count, &processed_data_len, input.data(), input.size(), tcp_enabled); nodes, node_count, &processed_data_len, input.data(), input.size(), tcp_enabled);
if (packed_count > 0) { if (packed_count > 0) {
Logger *logger = logger_new(); const Memory *mem = os_memory();
Logger *logger = logger_new(mem);
std::vector<uint8_t> packed(packed_count * PACKED_NODE_SIZE_IP6); std::vector<uint8_t> packed(packed_count * PACKED_NODE_SIZE_IP6);
const int packed_size const int packed_size
= pack_nodes(logger, packed.data(), packed.size(), nodes, packed_count); = pack_nodes(logger, packed.data(), packed.size(), nodes, packed_count);

View File

@ -334,7 +334,7 @@ TEST(AnnounceNodes, SetAndTest)
Test_Memory mem; Test_Memory mem;
Test_Network ns; Test_Network ns;
Logger *log = logger_new(); Logger *log = logger_new(mem);
ASSERT_NE(log, nullptr); ASSERT_NE(log, nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
ASSERT_NE(mono_time, nullptr); ASSERT_NE(mono_time, nullptr);

View File

@ -74,6 +74,8 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
../toxcore/ping_array.c \ ../toxcore/ping_array.c \
../toxcore/net_crypto.h \ ../toxcore/net_crypto.h \
../toxcore/net_crypto.c \ ../toxcore/net_crypto.c \
../toxcore/net_profile.c \
../toxcore/net_profile.h \
../toxcore/friend_requests.h \ ../toxcore/friend_requests.h \
../toxcore/friend_requests.c \ ../toxcore/friend_requests.c \
../toxcore/LAN_discovery.h \ ../toxcore/LAN_discovery.h \

View File

@ -472,10 +472,6 @@ int m_delfriend(Messenger *m, int32_t friendnumber)
return -1; return -1;
} }
if (m->friend_connectionstatuschange_internal != nullptr) {
m->friend_connectionstatuschange_internal(m, friendnumber, false, m->friend_connectionstatuschange_internal_userdata);
}
clear_receipts(m, friendnumber); clear_receipts(m, friendnumber);
remove_request_received(m->fr, m->friendlist[friendnumber].real_pk); 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, 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; 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) non_null(1) nullable(3)
static void check_friend_tcp_udp(Messenger *m, int32_t friendnumber, void *userdata) 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; m->friendlist[friendnumber].status = status;
check_friend_tcp_udp(m, friendnumber, userdata); 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, static int m_handle_lossy_packet(void *object, int friendcon_id, const uint8_t *data, uint16_t length,
void *userdata) void *userdata)
{ {
@ -1881,17 +1848,6 @@ static int m_handle_lossy_packet(void *object, int friendcon_id, const uint8_t *
return 1; 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) { if (m->lossy_packethandler != nullptr) {
m->lossy_packethandler(m, friendcon_id, data[0], data, length, userdata); 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; 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) 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)) { 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; 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) { if (data[0] < PACKET_ID_RANGE_LOSSY_START || data[0] > PACKET_ID_RANGE_LOSSY_END) {
return -3; 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) { 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) { 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; 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) 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) 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: case PACKET_ID_FILE_DATA:
return m_handle_packet_file_data(m, friendcon_id, payload, payload_length, userdata); return m_handle_packet_file_data(m, friendcon_id, payload, payload_length, userdata);
case PACKET_ID_MSI: 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: case PACKET_ID_INVITE_GROUPCHAT:
return m_handle_packet_invite_groupchat(m, friendcon_id, payload, payload_length, userdata); return m_handle_packet_invite_groupchat(m, friendcon_id, payload, payload_length, userdata);
} }
@ -3570,7 +3482,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
return nullptr; return nullptr;
} }
m->log = logger_new(); m->log = logger_new(mem);
if (m->log == nullptr) { if (m->log == nullptr) {
friendreq_kill(m->fr); friendreq_kill(m->fr);

View File

@ -86,6 +86,8 @@ typedef struct Messenger_Options {
Messenger_State_Plugin *state_plugins; Messenger_State_Plugin *state_plugins;
uint8_t state_plugins_length; uint8_t state_plugins_length;
bool dns_enabled;
} Messenger_Options; } Messenger_Options;
struct Receipts { struct Receipts {
@ -200,20 +202,10 @@ typedef void m_friend_lossy_packet_cb(Messenger *m, uint32_t friend_number, uint
size_t length, void *user_data); 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, 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); 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, typedef void m_conference_invite_cb(Messenger *m, uint32_t friend_number, const uint8_t *cookie, uint16_t length,
void *user_data); void *user_data);
typedef void m_group_invite_cb(const Messenger *m, uint32_t friend_number, const uint8_t *invite_data, size_t length, 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); 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 { typedef struct Friend {
uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE];
@ -243,8 +235,6 @@ typedef struct Friend {
uint32_t num_sending_files; uint32_t num_sending_files;
struct File_Transfers file_receiving[MAX_CONCURRENT_FILE_PIPES]; 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_start;
struct Receipts *receipts_end; struct Receipts *receipts_end;
} Friend; } Friend;
@ -301,8 +291,6 @@ struct Messenger {
m_friend_typing_cb *friend_typingchange; m_friend_typing_cb *friend_typingchange;
m_friend_read_receipt_cb *read_receipt; m_friend_read_receipt_cb *read_receipt;
m_friend_connection_status_cb *friend_connectionstatuschange; 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; struct Group_Chats *conferences_object;
m_conference_invite_cb *conference_invite; m_conference_invite_cb *conference_invite;
@ -314,9 +302,6 @@ struct Messenger {
m_file_recv_chunk_cb *file_filedata; m_file_recv_chunk_cb *file_filedata;
m_file_chunk_request_cb *file_reqchunk; 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_lossy_packet_cb *lossy_packethandler;
m_friend_lossless_packet_cb *lossless_packethandler; m_friend_lossless_packet_cb *lossless_packethandler;
@ -614,10 +599,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); 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. */ /** @brief Set the callback for typing changes. */
non_null() void m_callback_core_connection(Messenger *m, m_self_connection_status_cb *function); non_null() void m_callback_core_connection(Messenger *m, m_self_connection_status_cb *function);
@ -731,42 +712,12 @@ non_null(1) nullable(5)
int send_file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uint64_t position, int send_file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uint64_t position,
const uint8_t *data, uint16_t length); 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 */ /*** CUSTOM PACKETS */
/** @brief Set handlers for custom lossy packets. */ /** @brief Set handlers for custom lossy packets. */
non_null() void custom_lossy_packet_registerhandler(Messenger *m, m_friend_lossy_packet_cb *lossy_packethandler); 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. /** @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 -1 if friend invalid.
* @retval -2 if length wrong. * @retval -2 if length wrong.

View File

@ -20,6 +20,7 @@
#include "logger.h" #include "logger.h"
#include "mem.h" #include "mem.h"
#include "mono_time.h" #include "mono_time.h"
#include "net_profile.h"
#include "network.h" #include "network.h"
#include "util.h" #include "util.h"
@ -107,12 +108,12 @@ void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value)
* @retval false on failure * @retval false on failure
*/ */
non_null() non_null()
static bool connect_sock_to(const Logger *logger, const Memory *mem, Socket sock, const IP_Port *ip_port, const TCP_Proxy_Info *proxy_info) static bool connect_sock_to(const Network *ns, const Logger *logger, const Memory *mem, Socket sock, const IP_Port *ip_port, const TCP_Proxy_Info *proxy_info)
{ {
if (proxy_info->proxy_type != TCP_PROXY_NONE) { if (proxy_info->proxy_type != TCP_PROXY_NONE) {
return net_connect(mem, logger, sock, &proxy_info->ip_port); return net_connect(ns, mem, logger, sock, &proxy_info->ip_port);
} else { } else {
return net_connect(mem, logger, sock, ip_port); return net_connect(ns, mem, logger, sock, ip_port);
} }
} }
@ -582,7 +583,7 @@ void forwarding_handler(TCP_Client_Connection *con, forwarded_response_cb *forwa
TCP_Client_Connection *new_tcp_connection( TCP_Client_Connection *new_tcp_connection(
const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns, const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns,
const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key,
const TCP_Proxy_Info *proxy_info) const TCP_Proxy_Info *proxy_info, Net_Profile *net_profile)
{ {
assert(logger != nullptr); assert(logger != nullptr);
assert(mem != nullptr); assert(mem != nullptr);
@ -617,7 +618,7 @@ TCP_Client_Connection *new_tcp_connection(
return nullptr; return nullptr;
} }
if (!(set_socket_nonblock(ns, sock) && connect_sock_to(logger, mem, sock, ip_port, proxy_info))) { if (!(set_socket_nonblock(ns, sock) && connect_sock_to(ns, logger, mem, sock, ip_port, proxy_info))) {
kill_sock(ns, sock); kill_sock(ns, sock);
return nullptr; return nullptr;
} }
@ -634,6 +635,7 @@ TCP_Client_Connection *new_tcp_connection(
temp->con.rng = rng; temp->con.rng = rng;
temp->con.sock = sock; temp->con.sock = sock;
temp->con.ip_port = *ip_port; temp->con.ip_port = *ip_port;
temp->con.net_profile = net_profile;
memcpy(temp->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(temp->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(temp->self_public_key, self_public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(temp->self_public_key, self_public_key, CRYPTO_PUBLIC_KEY_SIZE);
encrypt_precompute(temp->public_key, self_secret_key, temp->con.shared_key); encrypt_precompute(temp->public_key, self_secret_key, temp->con.shared_key);
@ -819,6 +821,8 @@ static int handle_tcp_client_packet(const Logger *logger, TCP_Client_Connection
return -1; return -1;
} }
netprof_record_packet(conn->con.net_profile, data[0], length, PACKET_DIRECTION_RECV);
switch (data[0]) { switch (data[0]) {
case TCP_PACKET_ROUTING_RESPONSE: case TCP_PACKET_ROUTING_RESPONSE:
return handle_tcp_client_routing_response(conn, data, length); return handle_tcp_client_routing_response(conn, data, length);

View File

@ -15,6 +15,7 @@
#include "logger.h" #include "logger.h"
#include "mem.h" #include "mem.h"
#include "mono_time.h" #include "mono_time.h"
#include "net_profile.h"
#include "network.h" #include "network.h"
#define TCP_CONNECTION_TIMEOUT 10 #define TCP_CONNECTION_TIMEOUT 10
@ -60,11 +61,11 @@ non_null()
void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value); void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value);
/** Create new TCP connection to ip_port/public_key */ /** Create new TCP connection to ip_port/public_key */
non_null(1, 2, 3, 4, 5, 6, 7, 8, 9) nullable(10) non_null(1, 2, 3, 4, 5, 6, 7, 8, 9) nullable(10, 11)
TCP_Client_Connection *new_tcp_connection( TCP_Client_Connection *new_tcp_connection(
const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns, const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns,
const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key,
const TCP_Proxy_Info *proxy_info); const TCP_Proxy_Info *proxy_info, Net_Profile *net_profile);
/** Run the TCP connection */ /** Run the TCP connection */
non_null(1, 2, 3) nullable(4) non_null(1, 2, 3) nullable(4)

View File

@ -35,7 +35,8 @@ int send_pending_data_nonpriority(const Logger *logger, TCP_Connection *con)
} }
const uint16_t left = con->last_packet_length - con->last_packet_sent; const uint16_t left = con->last_packet_length - con->last_packet_sent;
const int len = net_send(con->ns, logger, con->sock, con->last_packet + con->last_packet_sent, left, &con->ip_port); const int len = net_send(con->ns, logger, con->sock, con->last_packet + con->last_packet_sent, left, &con->ip_port,
con->net_profile);
if (len <= 0) { if (len <= 0) {
return -1; return -1;
@ -66,7 +67,7 @@ int send_pending_data(const Logger *logger, TCP_Connection *con)
while (p != nullptr) { while (p != nullptr) {
const uint16_t left = p->size - p->sent; const uint16_t left = p->size - p->sent;
const int len = net_send(con->ns, logger, con->sock, p->data + p->sent, left, &con->ip_port); const int len = net_send(con->ns, logger, con->sock, p->data + p->sent, left, &con->ip_port, con->net_profile);
if (len != left) { if (len != left) {
if (len > 0) { if (len > 0) {
@ -164,7 +165,8 @@ int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con
} }
if (priority) { if (priority) {
len = sendpriority ? net_send(con->ns, logger, con->sock, packet, packet_size, &con->ip_port) : 0; len = sendpriority ? net_send(con->ns, logger, con->sock, packet, packet_size, &con->ip_port,
con->net_profile) : 0;
if (len <= 0) { if (len <= 0) {
len = 0; len = 0;
@ -179,7 +181,7 @@ int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con
return add_priority(con, packet, packet_size, len) ? 1 : 0; return add_priority(con, packet, packet_size, len) ? 1 : 0;
} }
len = net_send(con->ns, logger, con->sock, packet, packet_size, &con->ip_port); len = net_send(con->ns, logger, con->sock, packet, packet_size, &con->ip_port, con->net_profile);
if (len <= 0) { if (len <= 0) {
return 0; return 0;

View File

@ -10,6 +10,7 @@
#include "crypto_core.h" #include "crypto_core.h"
#include "logger.h" #include "logger.h"
#include "mem.h" #include "mem.h"
#include "net_profile.h"
#include "network.h" #include "network.h"
typedef struct TCP_Priority_List TCP_Priority_List; typedef struct TCP_Priority_List TCP_Priority_List;
@ -66,6 +67,10 @@ typedef struct TCP_Connection {
TCP_Priority_List *priority_queue_start; TCP_Priority_List *priority_queue_start;
TCP_Priority_List *priority_queue_end; TCP_Priority_List *priority_queue_end;
// This is a shared pointer to the parent's respective Net_Profile object
// (either TCP_Server for TCP server packets or TCP_Connections for TCP client packets).
Net_Profile *net_profile;
} TCP_Connection; } TCP_Connection;
/** /**

View File

@ -20,6 +20,7 @@
#include "logger.h" #include "logger.h"
#include "mem.h" #include "mem.h"
#include "mono_time.h" #include "mono_time.h"
#include "net_profile.h"
#include "network.h" #include "network.h"
#include "util.h" #include "util.h"
@ -56,6 +57,9 @@ struct TCP_Connections {
bool onion_status; bool onion_status;
uint16_t onion_num_conns; uint16_t onion_num_conns;
/* Network profile for all TCP client packets. */
Net_Profile *net_profile;
}; };
static const TCP_Connection_to empty_tcp_connection_to = {0}; static const TCP_Connection_to empty_tcp_connection_to = {0};
@ -928,7 +932,8 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec
uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE];
memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE); memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE);
kill_tcp_connection(tcp_con->connection); kill_tcp_connection(tcp_con->connection);
tcp_con->connection = new_tcp_connection(tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); tcp_con->connection = new_tcp_connection(tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info,
tcp_c->net_profile);
if (tcp_con->connection == nullptr) { if (tcp_con->connection == nullptr) {
kill_tcp_relay_connection(tcp_c, tcp_connections_number); kill_tcp_relay_connection(tcp_c, tcp_connections_number);
@ -1017,7 +1022,7 @@ static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connecti
tcp_con->connection = new_tcp_connection( tcp_con->connection = new_tcp_connection(
tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &tcp_con->ip_port, tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &tcp_con->ip_port,
tcp_con->relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); tcp_con->relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info, tcp_c->net_profile);
if (tcp_con->connection == nullptr) { if (tcp_con->connection == nullptr) {
kill_tcp_relay_connection(tcp_c, tcp_connections_number); kill_tcp_relay_connection(tcp_c, tcp_connections_number);
@ -1315,7 +1320,7 @@ static int add_tcp_relay_instance(TCP_Connections *tcp_c, const IP_Port *ip_port
tcp_con->connection = new_tcp_connection( tcp_con->connection = new_tcp_connection(
tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ipp_copy, tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ipp_copy,
relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info, tcp_c->net_profile);
if (tcp_con->connection == nullptr) { if (tcp_con->connection == nullptr) {
return -1; return -1;
@ -1609,6 +1614,14 @@ TCP_Connections *new_tcp_connections(const Logger *logger, const Memory *mem, co
return nullptr; return nullptr;
} }
Net_Profile *np = netprof_new(logger, mem);
if (np == nullptr) {
mem_delete(mem, temp);
return nullptr;
}
temp->net_profile = np;
temp->logger = logger; temp->logger = logger;
temp->mem = mem; temp->mem = mem;
temp->rng = rng; temp->rng = rng;
@ -1723,7 +1736,17 @@ void kill_tcp_connections(TCP_Connections *tcp_c)
crypto_memzero(tcp_c->self_secret_key, sizeof(tcp_c->self_secret_key)); crypto_memzero(tcp_c->self_secret_key, sizeof(tcp_c->self_secret_key));
netprof_kill(tcp_c->mem, tcp_c->net_profile);
mem_delete(tcp_c->mem, tcp_c->tcp_connections); mem_delete(tcp_c->mem, tcp_c->tcp_connections);
mem_delete(tcp_c->mem, tcp_c->connections); mem_delete(tcp_c->mem, tcp_c->connections);
mem_delete(tcp_c->mem, tcp_c); mem_delete(tcp_c->mem, tcp_c);
} }
const Net_Profile *tcp_connection_get_client_net_profile(const TCP_Connections *tcp_c)
{
if (tcp_c == nullptr) {
return nullptr;
}
return tcp_c->net_profile;
}

View File

@ -21,6 +21,7 @@
#include "logger.h" #include "logger.h"
#include "mem.h" #include "mem.h"
#include "mono_time.h" #include "mono_time.h"
#include "net_profile.h"
#include "network.h" #include "network.h"
#define TCP_CONN_NONE 0 #define TCP_CONN_NONE 0
@ -317,4 +318,11 @@ void do_tcp_connections(const Logger *logger, TCP_Connections *tcp_c, void *user
nullable(1) nullable(1)
void kill_tcp_connections(TCP_Connections *tcp_c); void kill_tcp_connections(TCP_Connections *tcp_c);
/** @brief a pointer to the tcp client net profile associated with tcp_c.
*
* @retval null if tcp_c is null.
*/
non_null()
const Net_Profile *tcp_connection_get_client_net_profile(const TCP_Connections *tcp_c);
#endif /* C_TOXCORE_TOXCORE_TCP_CONNECTION_H */ #endif /* C_TOXCORE_TOXCORE_TCP_CONNECTION_H */

View File

@ -27,6 +27,7 @@
#include "logger.h" #include "logger.h"
#include "mem.h" #include "mem.h"
#include "mono_time.h" #include "mono_time.h"
#include "net_profile.h"
#include "network.h" #include "network.h"
#include "onion.h" #include "onion.h"
@ -91,6 +92,9 @@ struct TCP_Server {
uint64_t counter; uint64_t counter;
BS_List accepted_key_list; BS_List accepted_key_list;
/* Network profile for all TCP server packets. */
Net_Profile *net_profile;
}; };
static_assert(sizeof(TCP_Server) < 7 * 1024 * 1024, static_assert(sizeof(TCP_Server) < 7 * 1024 * 1024,
@ -236,6 +240,7 @@ static int add_accepted(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_
tcp_server->accepted_connection_array[index].identifier = ++tcp_server->counter; tcp_server->accepted_connection_array[index].identifier = ++tcp_server->counter;
tcp_server->accepted_connection_array[index].last_pinged = mono_time_get(mono_time); tcp_server->accepted_connection_array[index].last_pinged = mono_time_get(mono_time);
tcp_server->accepted_connection_array[index].ping_id = 0; tcp_server->accepted_connection_array[index].ping_id = 0;
tcp_server->accepted_connection_array[index].con.net_profile = tcp_server->net_profile;
return index; return index;
} }
@ -357,7 +362,7 @@ static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con
const IP_Port ipp = {{{0}}}; const IP_Port ipp = {{{0}}};
if (TCP_SERVER_HANDSHAKE_SIZE != net_send(con->con.ns, logger, con->con.sock, response, TCP_SERVER_HANDSHAKE_SIZE, &ipp)) { if (TCP_SERVER_HANDSHAKE_SIZE != net_send(con->con.ns, logger, con->con.sock, response, TCP_SERVER_HANDSHAKE_SIZE, &ipp, con->con.net_profile)) {
crypto_memzero(shared_key, sizeof(shared_key)); crypto_memzero(shared_key, sizeof(shared_key));
return -1; return -1;
} }
@ -680,6 +685,7 @@ static int handle_tcp_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
} }
TCP_Secure_Connection *const con = &tcp_server->accepted_connection_array[con_id]; TCP_Secure_Connection *const con = &tcp_server->accepted_connection_array[con_id];
netprof_record_packet(con->con.net_profile, data[0], length, PACKET_DIRECTION_RECV);
switch (data[0]) { switch (data[0]) {
case TCP_PACKET_ROUTING_REQUEST: { case TCP_PACKET_ROUTING_REQUEST: {
@ -969,6 +975,14 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
return nullptr; return nullptr;
} }
Net_Profile *np = netprof_new(logger, mem);
if (np == nullptr) {
mem_delete(mem, temp);
return nullptr;
}
temp->net_profile = np;
temp->logger = logger; temp->logger = logger;
temp->mem = mem; temp->mem = mem;
temp->ns = ns; temp->ns = ns;
@ -978,6 +992,7 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
if (socks_listening == nullptr) { if (socks_listening == nullptr) {
LOGGER_ERROR(logger, "socket allocation failed"); LOGGER_ERROR(logger, "socket allocation failed");
netprof_kill(mem, temp->net_profile);
mem_delete(mem, temp); mem_delete(mem, temp);
return nullptr; return nullptr;
} }
@ -989,6 +1004,7 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
if (temp->efd == -1) { if (temp->efd == -1) {
LOGGER_ERROR(logger, "epoll initialisation failed"); LOGGER_ERROR(logger, "epoll initialisation failed");
netprof_kill(mem, temp->net_profile);
mem_delete(mem, socks_listening); mem_delete(mem, socks_listening);
mem_delete(mem, temp); mem_delete(mem, temp);
return nullptr; return nullptr;
@ -1022,6 +1038,7 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
} }
if (temp->num_listening_socks == 0) { if (temp->num_listening_socks == 0) {
netprof_kill(mem, temp->net_profile);
mem_delete(mem, temp->socks_listening); mem_delete(mem, temp->socks_listening);
mem_delete(mem, temp); mem_delete(mem, temp);
return nullptr; return nullptr;
@ -1422,6 +1439,16 @@ void kill_tcp_server(TCP_Server *tcp_server)
crypto_memzero(tcp_server->secret_key, sizeof(tcp_server->secret_key)); crypto_memzero(tcp_server->secret_key, sizeof(tcp_server->secret_key));
netprof_kill(tcp_server->mem, tcp_server->net_profile);
mem_delete(tcp_server->mem, tcp_server->socks_listening); mem_delete(tcp_server->mem, tcp_server->socks_listening);
mem_delete(tcp_server->mem, tcp_server); mem_delete(tcp_server->mem, tcp_server);
} }
const Net_Profile *tcp_server_get_net_profile(const TCP_Server *tcp_server)
{
if (tcp_server == nullptr) {
return nullptr;
}
return tcp_server->net_profile;
}

View File

@ -15,6 +15,7 @@
#include "logger.h" #include "logger.h"
#include "mem.h" #include "mem.h"
#include "mono_time.h" #include "mono_time.h"
#include "net_profile.h"
#include "network.h" #include "network.h"
#include "onion.h" #include "onion.h"
@ -52,4 +53,11 @@ void do_tcp_server(TCP_Server *tcp_server, const Mono_Time *mono_time);
nullable(1) nullable(1)
void kill_tcp_server(TCP_Server *tcp_server); void kill_tcp_server(TCP_Server *tcp_server);
/** @brief Returns a pointer to the net profile associated with `tcp_server`.
*
* Returns null if `tcp_server` is null.
*/
nullable(1)
const Net_Profile *tcp_server_get_net_profile(const TCP_Server *tcp_server);
#endif /* C_TOXCORE_TOXCORE_TCP_SERVER_H */ #endif /* C_TOXCORE_TOXCORE_TCP_SERVER_H */

View File

@ -579,7 +579,7 @@ static int create_reply(Announcements *announce, const IP_Port *source,
const int plain_reply_max_len = (int)reply_max_length - const int plain_reply_max_len = (int)reply_max_length -
(1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE); (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; return -1;
} }

View File

@ -109,7 +109,10 @@ static Tox_Event_Conference_Connected *tox_events_add_conference_connected(Tox_E
event.type = TOX_EVENT_CONFERENCE_CONNECTED; event.type = TOX_EVENT_CONFERENCE_CONNECTED;
event.data.conference_connected = 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; return conference_connected;
} }

View File

@ -177,7 +177,10 @@ static Tox_Event_Conference_Invite *tox_events_add_conference_invite(Tox_Events
event.type = TOX_EVENT_CONFERENCE_INVITE; event.type = TOX_EVENT_CONFERENCE_INVITE;
event.data.conference_invite = 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; return conference_invite;
} }

View File

@ -193,7 +193,10 @@ static Tox_Event_Conference_Message *tox_events_add_conference_message(Tox_Event
event.type = TOX_EVENT_CONFERENCE_MESSAGE; event.type = TOX_EVENT_CONFERENCE_MESSAGE;
event.data.conference_message = 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; return conference_message;
} }

Some files were not shown because too many files have changed in this diff Show More