Compare commits

...

34 Commits

Author SHA1 Message Date
ac951b2afa update toxcore, includes ngc mem savings
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
Merge commit '261d2e53b7a513de7eb35e022fe3b2ae4efa835f'
2024-12-19 16:27:50 +01:00
261d2e53b7 Squashed 'external/toxcore/c-toxcore/' changes from 55752a2e2ef..11ab1d2a723
11ab1d2a723 fix: reduce memory usage in group chats by 75% Significantly reduced the memory usage of groups since all message slots are preallocated for every peer for send and receive buffers of buffer size (hundreds of MiB peak when save contained alot of peers to try to connect to)
4f09f4e147c chore: Fix tsan build by moving it to GitHub CI.
6460c25c9e0 refactor: Use `merge_sort` instead of `qsort` for sorting.
c660bbe8c95 test: Fix crypto_test to initialise its plain text buffer.
0204db6184b cleanup: Fix layering check warnings.
df2211e1548 refactor: Use tox memory allocator for temporary buffers in crypto.
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: 11ab1d2a7232eee19b51ce126ccce267d6578903
2024-12-19 16:27:40 +01:00
d71ebb79aa asan cmake and frame pointer 2024-12-19 16:26:40 +01:00
bb510b685a fix some crashes (how) and bitset wierdness
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-18 21:39:50 +01:00
876f482391 fix sdl image loder io leak and send image popup fixes
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-18 21:12:20 +01:00
42dd6d16d7 fix reading char from empty line
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-18 16:21:11 +01:00
11ae259f67 texture cache refactor to later allow async loading
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-16 00:32:07 +01:00
f2027befc8 fix bitset getting rendered all the time
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-15 22:01:53 +01:00
9777cb81cb remote (combined) bitset have
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-14 23:47:04 +01:00
84ade4d683 local have bitset rendering
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-13 00:53:48 +01:00
f89aeae62b indicate have all on ft
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-12 15:36:16 +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
227 changed files with 4230 additions and 2264 deletions

View File

@ -25,7 +25,7 @@ jobs:
run: sudo apt update && sudo apt -y install libsodium-dev cmake libvpx-dev libopus-dev
- 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
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato
@ -64,6 +64,8 @@ jobs:
strategy:
matrix:
platform:
- vcpkg_toolkit: arm-neon-android
ndk_abi: armeabi-v7a
- vcpkg_toolkit: arm64-android
ndk_abi: arm64-v8a
- vcpkg_toolkit: x64-android
@ -101,7 +103,7 @@ jobs:
- name: Configure CMake
env:
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)
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato
@ -164,7 +166,7 @@ jobs:
#- uses: ilammy/setup-nasm@v1
- 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
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -t tomato

View File

@ -38,6 +38,8 @@ jobs:
strategy:
matrix:
platform:
- vcpkg_toolkit: arm-neon-android
ndk_abi: armeabi-v7a
- vcpkg_toolkit: arm64-android
ndk_abi: arm64-v8a
- vcpkg_toolkit: x64-android
@ -59,9 +61,9 @@ jobs:
distribution: 'temurin'
java-version: '17'
- name: update vcpkg
run: |
git clone https://github.com/microsoft/vcpkg.git
#- name: update vcpkg
# run: |
# git clone https://github.com/microsoft/vcpkg.git
- name: Install Dependencies (host)
run: sudo apt update && sudo apt -y install cmake pkg-config nasm
@ -69,7 +71,8 @@ jobs:
- name: Install Dependencies (target)
env:
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
- name: Configure CMake

View File

@ -20,16 +20,25 @@ 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_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)
message("II TOMATO_TOX_AV: ${TOMATO_TOX_AV}")
if (TOMATO_ASAN)
if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
if (NOT WIN32) # exclude mingw
#link_libraries(-fsanitize=address)
link_libraries(-fsanitize=address,undefined)
#link_libraries(-fsanitize=undefined)
add_compile_options(-fno-omit-frame-pointer)
add_compile_options(-fsanitize=address,undefined)
#add_compile_options(-fsanitize=address,undefined,pointer-compare,pointer-subtract)
#add_compile_options(-fhardened)
#add_compile_options(-D_FORTIFY_SOURCE=3 -D_GLIBCXX_ASSERTIONS -ftrivial-auto-var-init=zero -fPIE -pie -Wl,-z,relro,-z,now -fstack-protector-strong -fstack-clash-protection -fcf-protection=full)
add_link_options(-fno-omit-frame-pointer)
add_link_options(-fsanitize=address,undefined)
#add_link_options(-fsanitize=address,undefined,pointer-compare,pointer-subtract)
#add_link_options(-fhardened)
#add_link_options(-D_FORTIFY_SOURCE=3 -D_GLIBCXX_ASSERTIONS -ftrivial-auto-var-init=zero -fPIE -pie -Wl,-z,relro,-z,now -fstack-protector-strong -fstack-clash-protection -fcf-protection=full)
link_libraries(-static-libasan) # make it "work" on nix
message("II enabled ASAN")
else()
@ -43,6 +52,17 @@ if (TOMATO_ASAN)
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.
# but this also means that we can not compile tomato in the same cmake as plugins
add_compile_definitions(ENTT_API_EXPORT)

View File

@ -24,3 +24,7 @@ add_subdirectory(./libwebp)
add_subdirectory(./qoi)
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

@ -25,7 +25,9 @@ if (NOT TARGET SDL3::SDL3)
#GIT_TAG 6e885d96193a4b0096fe7fed6d4e6c3e5f247283 # tip 09-09-2024
#GIT_TAG 9dd8859240703d886941733ad32c1dc6f50d64f0 # tip 19-09-2024
#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 2654d5d48b8f764148a7c246fea85b32b1133578 # tip 18-10-2024
GIT_TAG f8468d580d903e106640800034a4721aca24264c # tip 15-11-2024
FIND_PACKAGE_ARGS # for the future
)

View File

@ -3,20 +3,15 @@ version: 2
workflows:
version: 2
program-analysis:
circleci:
jobs:
# Dynamic analysis in the Bazel build
- bazel-asan
- bazel-msan
- bazel-tsan
# Dynamic analysis with CMake
- asan
- tsan
- ubsan
# Static analysis
- clang-analyze
- cpplint
- static-analysis
- cimplefmt
- generate-events
jobs:
bazel-asan:
@ -29,20 +24,6 @@ jobs:
- run: .circleci/bazel-test
//c-toxcore/...
bazel-tsan:
working_directory: /tmp/cirrus-ci-build
docker:
- image: toxchat/toktok-stack:latest-tsan
steps:
- checkout
- run: .circleci/bazel-test
//c-toxcore/...
-//c-toxcore/auto_tests:conference_av_test
-//c-toxcore/auto_tests:conference_test
-//c-toxcore/auto_tests:onion_test
-//c-toxcore/auto_tests:tox_many_test
bazel-msan:
working_directory: /tmp/cirrus-ci-build
docker:
@ -53,7 +34,7 @@ jobs:
- run: .circleci/bazel-test
//c-toxcore/auto_tests:lossless_packet_test
asan:
static-analysis:
working_directory: ~/work
docker:
- image: ubuntu
@ -67,6 +48,7 @@ jobs:
clang
cmake
git
libbenchmark-dev
libconfig-dev
libgmock-dev
libgtest-dev
@ -76,39 +58,6 @@ jobs:
llvm-dev
ninja-build
pkg-config
- checkout
- run: git submodule update --init --recursive
- run: CC=clang .circleci/cmake-asan
tsan:
working_directory: ~/work
docker:
- image: ubuntu
steps:
- run: *apt_install
- checkout
- run: git submodule update --init --recursive
- run: CC=clang .circleci/cmake-tsan
ubsan:
working_directory: ~/work
docker:
- image: ubuntu
steps:
- run: *apt_install
- checkout
- run: git submodule update --init --recursive
- run: CC=clang .circleci/cmake-ubsan
static-analysis:
working_directory: ~/work
docker:
- image: ubuntu
steps:
- run: *apt_install
- run:
apt-get install -y --no-install-recommends
ca-certificates
@ -145,3 +94,22 @@ jobs:
- checkout
- run: git submodule update --init --recursive
- run: other/analysis/run-cpplint
cimplefmt:
working_directory: ~/work
machine: { image: ubuntu-2204:current }
steps:
- checkout
- run: git submodule update --init --recursive
- run: other/docker/cimplefmt/run -u $(find tox* -name "*.[ch]")
generate-events:
working_directory: ~/work
machine: { image: ubuntu-2204:current }
steps:
- checkout
- run: git submodule update --init --recursive
- run: other/event_tooling/run
- run: git diff --exit-code

View File

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

View File

@ -36,9 +36,6 @@ add_flag -Wno-padded
# This warns on things like _XOPEN_SOURCE, which we currently need (we
# probably won't need these in the future).
add_flag -Wno-reserved-id-macro
# TODO(iphydf): Clean these up. They are likely not bugs, but still
# potential issues and probably confusing.
add_flag -Wno-sign-compare
# We don't want to have default cases, we want to explicitly define all cases
add_flag -Wno-switch-default
# __attribute__((nonnull)) causes this warning on defensive null checks.

View File

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

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

@ -18,7 +18,7 @@ jobs:
fail-fast: false
matrix:
tool: [autotools, clang-tidy, compcert, cppcheck, doxygen, goblint, infer, freebsd, misra, modules, pkgsrc, rpm, slimcc, sparse, tcc, tokstyle]
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
@ -34,8 +34,25 @@ jobs:
with:
file: other/docker/${{ matrix.tool }}/${{ matrix.tool }}.Dockerfile
sanitizer:
strategy:
fail-fast: false
matrix:
sanitizer: [asan, tsan, ubsan]
runs-on: ubuntu-22.04
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Run sanitizer
run: other/docker/circleci/run "${{ matrix.sanitizer }}"
coverage-linux:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
@ -43,28 +60,8 @@ jobs:
- name: Build, test, and upload coverage
run: other/docker/coverage/run
generate-events:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Run generate_event_c
run: |
other/event_tooling/run
git diff --exit-code
cimplefmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Run cimplefmt
run: other/docker/cimplefmt/run -u $(find tox* -name "*.[ch]")
build-android:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
@ -111,7 +108,7 @@ jobs:
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 --build-config Debug
build-netbsd:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
@ -146,7 +143,7 @@ jobs:
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6
build-freebsd:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
@ -183,7 +180,7 @@ jobs:
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6
mypy:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:

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

@ -1,3 +1,3 @@
[submodule "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
### Merged PRs:
@ -30,6 +60,7 @@
- [#2697](https://github.com/TokTok/c-toxcore/pull/2697) test: Build toxcore on NetBSD (VM).
- [#2696](https://github.com/TokTok/c-toxcore/pull/2696) fix: save_compatibility_test failing on big-endian systems
- [#2695](https://github.com/TokTok/c-toxcore/pull/2695) fix: Don't serve files from websockify.
- [#2691](https://github.com/TokTok/c-toxcore/pull/2691) chore: Release 0.2.19
- [#2689](https://github.com/TokTok/c-toxcore/pull/2689) fix: Correctly pass extended public keys to group moderation code.
- [#2686](https://github.com/TokTok/c-toxcore/pull/2686) chore: Compile libsodium reference implementation with compcert.
- [#2685](https://github.com/TokTok/c-toxcore/pull/2685) cleanup: correct a few nullable annotations
@ -252,6 +283,7 @@
- [#2739](https://github.com/TokTok/c-toxcore/issues/2739) Tox_Options.operating_system is not clear about it being an experimental option
- [#2734](https://github.com/TokTok/c-toxcore/issues/2734) error compiling on fedora
- [#2649](https://github.com/TokTok/c-toxcore/issues/2649) create_extended_keypair should use Random and be made deterministic for fuzzing
- [#2462](https://github.com/TokTok/c-toxcore/issues/2462) Fix code scanning alert - Uncontrolled data used in path expression
- [#2358](https://github.com/TokTok/c-toxcore/issues/2358) resolve_bootstrap_node assert hit
- [#2352](https://github.com/TokTok/c-toxcore/issues/2352) SEGV after infinite loop retrying proxy_socks5_read_connection_response
- [#2335](https://github.com/TokTok/c-toxcore/issues/2335) ipv6 disabled on kernel cmdline disrupts Tox = most tests fail

View File

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

View File

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

View File

@ -78,6 +78,7 @@ extra_data = {
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:tox_dispatch",
"//c-toxcore/toxcore:tox_events",
"//c-toxcore/toxcore:tox_unpack",
"//c-toxcore/toxcore:util",
"//c-toxcore/toxencryptsave",
"@libsodium",

View File

@ -9,7 +9,9 @@ if(TARGET toxcore_static)
else()
target_link_libraries(auto_test_support PRIVATE toxcore_shared)
endif()
if(TARGET PThreads4W::PThreads4W)
if(TARGET pthreads4w::pthreads4w)
target_link_libraries(auto_test_support PRIVATE pthreads4w::pthreads4w)
elseif(TARGET PThreads4W::PThreads4W)
target_link_libraries(auto_test_support PRIVATE PThreads4W::PThreads4W)
elseif(TARGET Threads::Threads)
target_link_libraries(auto_test_support PRIVATE Threads::Threads)
@ -23,7 +25,9 @@ function(auto_test target)
else()
target_link_libraries(auto_${target}_test PRIVATE toxcore_shared)
endif()
if(TARGET PThreads4W::PThreads4W)
if(TARGET pthreads4w::pthreads4w)
target_link_libraries(auto_${target}_test PRIVATE pthreads4w::pthreads4w)
elseif(TARGET PThreads4W::PThreads4W)
target_link_libraries(auto_${target}_test PRIVATE PThreads4W::PThreads4W)
elseif(TARGET Threads::Threads)
target_link_libraries(auto_${target}_test PRIVATE Threads::Threads)
@ -98,7 +102,10 @@ if(BUILD_TOXAV)
auto_test(toxav_basic)
auto_test(toxav_many)
if(MSVC)
if(TARGET libvpx::libvpx)
target_link_libraries(auto_toxav_basic_test PRIVATE libvpx::libvpx)
target_link_libraries(auto_toxav_many_test PRIVATE libvpx::libvpx)
elseif(TARGET PkgConfig::VPX)
target_link_libraries(auto_toxav_basic_test PRIVATE PkgConfig::VPX)
target_link_libraries(auto_toxav_many_test PRIVATE PkgConfig::VPX)
else()

View File

@ -53,7 +53,7 @@ static void test_basic(void)
ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new();
Logger *logger = logger_new(mem);
logger_callback_log(logger, print_debug_logger, nullptr, nullptr);
// Attempt to create a new TCP_Server instance.
@ -74,7 +74,7 @@ static void test_basic(void)
for (uint8_t i = 0; i < NUM_PORTS; i++) {
sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP);
localhost.port = net_htons(ports[i]);
bool ret = net_connect(mem, logger, sock, &localhost);
bool ret = net_connect(ns, mem, logger, sock, &localhost);
ck_assert_msg(ret, "Failed to connect to created TCP relay server on port %d (%d).", ports[i], errno);
// Leave open one connection for the next test.
@ -102,7 +102,7 @@ static void test_basic(void)
random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE);
// Encrypting handshake
int ret = encrypt_data(self_public_key, f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain,
int ret = encrypt_data(mem, self_public_key, f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain,
TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
ck_assert_msg(ret == TCP_CLIENT_HANDSHAKE_SIZE - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE),
"encrypt_data() call failed.");
@ -128,7 +128,7 @@ static void test_basic(void)
uint8_t response_plain[TCP_HANDSHAKE_PLAIN_SIZE];
ck_assert_msg(net_recv(ns, logger, sock, response, TCP_SERVER_HANDSHAKE_SIZE, &localhost) == TCP_SERVER_HANDSHAKE_SIZE,
"Could/did not receive a server response to the initial handshake.");
ret = decrypt_data(self_public_key, f_secret_key, response, response + CRYPTO_NONCE_SIZE,
ret = decrypt_data(mem, self_public_key, f_secret_key, response, response + CRYPTO_NONCE_SIZE,
TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, response_plain);
ck_assert_msg(ret == TCP_HANDSHAKE_PLAIN_SIZE, "Failed to decrypt handshake response.");
uint8_t f_nonce_r[CRYPTO_NONCE_SIZE];
@ -143,7 +143,7 @@ static void test_basic(void)
uint8_t r_req[2 + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE];
uint16_t size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE;
size = net_htons(size);
encrypt_data_symmetric(f_shared_key, f_nonce, r_req_p, 1 + CRYPTO_PUBLIC_KEY_SIZE, r_req + 2);
encrypt_data_symmetric(mem, f_shared_key, f_nonce, r_req_p, 1 + CRYPTO_PUBLIC_KEY_SIZE, r_req + 2);
increment_nonce(f_nonce);
memcpy(r_req, &size, 2);
@ -174,7 +174,7 @@ static void test_basic(void)
"Wrong packet size for request response.");
uint8_t packet_resp_plain[4096];
ret = decrypt_data_symmetric(f_shared_key, f_nonce_r, packet_resp + 2, recv_data_len - 2, packet_resp_plain);
ret = decrypt_data_symmetric(mem, f_shared_key, f_nonce_r, packet_resp + 2, recv_data_len - 2, packet_resp_plain);
ck_assert_msg(ret != -1, "Failed to decrypt the TCP server's response.");
increment_nonce(f_nonce_r);
@ -213,7 +213,7 @@ static struct sec_TCP_con *new_tcp_con(const Logger *logger, const Memory *mem,
localhost.ip = get_loopback();
localhost.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
bool ok = net_connect(mem, logger, sock, &localhost);
bool ok = net_connect(ns, mem, logger, sock, &localhost);
ck_assert_msg(ok, "Failed to connect to the test TCP relay server.");
uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE];
@ -228,7 +228,7 @@ static struct sec_TCP_con *new_tcp_con(const Logger *logger, const Memory *mem,
memcpy(handshake, sec_c->public_key, CRYPTO_PUBLIC_KEY_SIZE);
random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE);
int ret = encrypt_data(tcp_server_public_key(tcp_s), f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain,
int ret = encrypt_data(mem, tcp_server_public_key(tcp_s), f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain,
TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
ck_assert_msg(ret == TCP_CLIENT_HANDSHAKE_SIZE - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE),
"Failed to encrypt the outgoing handshake.");
@ -248,7 +248,7 @@ static struct sec_TCP_con *new_tcp_con(const Logger *logger, const Memory *mem,
uint8_t response_plain[TCP_HANDSHAKE_PLAIN_SIZE];
ck_assert_msg(net_recv(sec_c->ns, logger, sock, response, TCP_SERVER_HANDSHAKE_SIZE, &localhost) == TCP_SERVER_HANDSHAKE_SIZE,
"Failed to receive server handshake response.");
ret = decrypt_data(tcp_server_public_key(tcp_s), f_secret_key, response, response + CRYPTO_NONCE_SIZE,
ret = decrypt_data(mem, tcp_server_public_key(tcp_s), f_secret_key, response, response + CRYPTO_NONCE_SIZE,
TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, response_plain);
ck_assert_msg(ret == TCP_HANDSHAKE_PLAIN_SIZE, "Failed to decrypt server handshake response.");
encrypt_precompute(response_plain, t_secret_key, sec_c->shared_key);
@ -271,7 +271,7 @@ static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP
uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE);
memcpy(packet, &c_length, sizeof(uint16_t));
int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
int len = encrypt_data_symmetric(con->mem, con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
if ((unsigned int)len != (packet_size - sizeof(uint16_t))) {
return -1;
@ -296,7 +296,7 @@ static int read_packet_sec_tcp(const Logger *logger, struct sec_TCP_con *con, ui
int rlen = net_recv(con->ns, logger, con->sock, data, length, &localhost);
ck_assert_msg(rlen == length, "Did not receive packet of correct length. Wanted %i, instead got %i", length, rlen);
rlen = decrypt_data_symmetric(con->shared_key, con->recv_nonce, data + 2, length - 2, data);
rlen = decrypt_data_symmetric(con->mem, con->shared_key, con->recv_nonce, data + 2, length - 2, data);
ck_assert_msg(rlen != -1, "Failed to decrypt a received packet from the Relay server.");
increment_nonce(con->recv_nonce);
return rlen;
@ -312,7 +312,7 @@ static void test_some(void)
ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new();
Logger *logger = logger_new(mem);
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
@ -506,7 +506,7 @@ static void test_client(void)
const Memory *mem = os_memory();
ck_assert(mem != nullptr);
Logger *logger = logger_new();
Logger *logger = logger_new(mem);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
@ -643,7 +643,7 @@ static void test_client_invalid(void)
ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new();
Logger *logger = logger_new(mem);
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
@ -721,7 +721,7 @@ static void test_tcp_connection(void)
ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new();
Logger *logger = logger_new(mem);
tcp_data_callback_called = 0;
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
@ -834,7 +834,7 @@ static void test_tcp_connection2(void)
ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new();
Logger *logger = logger_new(mem);
tcp_oobdata_callback_called = 0;
tcp_data_callback_called = 0;

View File

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

View File

@ -420,7 +420,7 @@ static void test_groupav(AutoTox *autotoxes)
tox_events_callback_conference_connected(autotoxes[i].dispatch, handle_conference_connected);
}
ck_assert_msg(toxav_add_av_groupchat(autotoxes[0].tox, audio_callback, &autotoxes[0]) != UINT32_MAX,
ck_assert_msg(toxav_add_av_groupchat(autotoxes[0].tox, audio_callback, &autotoxes[0]) != -1,
"failed to create group");
printf("tox #%u: inviting its first friend\n", autotoxes[0].index);
ck_assert_msg(tox_conference_invite(autotoxes[0].tox, 0, 0, nullptr) != 0, "failed to invite friend");

View File

@ -28,7 +28,7 @@ static void handle_conference_invite(
ck_assert_msg(!state->joined, "invitation callback generated for already joined conference");
if (friend_number != -1) {
if (friend_number != UINT32_MAX) {
Tox_Err_Conference_Join err;
state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err);
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,

View File

@ -21,7 +21,7 @@ static void handle_conference_invite(
const uint8_t *cookie = tox_event_conference_invite_get_cookie(event);
const size_t length = tox_event_conference_invite_get_cookie_length(event);
if (friend_number != -1) {
if (friend_number != UINT32_MAX) {
Tox_Err_Conference_Join err;
state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err);
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,

View File

@ -80,6 +80,9 @@ static const uint8_t test_c[147] = {
static void test_known(void)
{
const Memory *mem = os_memory();
ck_assert(mem != nullptr);
uint8_t c[147];
uint8_t m[131];
@ -88,12 +91,12 @@ static void test_known(void)
ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed");
ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed");
const uint16_t clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c);
const uint16_t clen = encrypt_data(mem, bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c);
ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector");
ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length");
const uint16_t mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m);
const uint16_t mlen = decrypt_data(mem, bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m);
ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector");
ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length");
@ -101,6 +104,9 @@ static void test_known(void)
static void test_fast_known(void)
{
const Memory *mem = os_memory();
ck_assert(mem != nullptr);
uint8_t k[CRYPTO_SHARED_KEY_SIZE];
uint8_t c[147];
uint8_t m[131];
@ -112,12 +118,12 @@ static void test_fast_known(void)
ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed");
ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed");
const uint16_t clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c);
const uint16_t clen = encrypt_data_symmetric(mem, k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c);
ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector");
ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length");
const uint16_t mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m);
const uint16_t mlen = decrypt_data_symmetric(mem, k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m);
ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector");
ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length");
@ -125,6 +131,8 @@ static void test_fast_known(void)
static void test_endtoend(void)
{
const Memory *mem = os_memory();
ck_assert(mem != nullptr);
const Random *rng = os_random();
ck_assert(rng != nullptr);
@ -166,10 +174,10 @@ static void test_endtoend(void)
ck_assert_msg(memcmp(k1, k2, CRYPTO_SHARED_KEY_SIZE) == 0, "encrypt_precompute: bad");
//Encrypt all four ways
const uint16_t c1len = encrypt_data(pk2, sk1, n, m, mlen, c1);
const uint16_t c2len = encrypt_data(pk1, sk2, n, m, mlen, c2);
const uint16_t c3len = encrypt_data_symmetric(k1, n, m, mlen, c3);
const uint16_t c4len = encrypt_data_symmetric(k2, n, m, mlen, c4);
const uint16_t c1len = encrypt_data(mem, pk2, sk1, n, m, mlen, c1);
const uint16_t c2len = encrypt_data(mem, pk1, sk2, n, m, mlen, c2);
const uint16_t c3len = encrypt_data_symmetric(mem, k1, n, m, mlen, c3);
const uint16_t c4len = encrypt_data_symmetric(mem, k2, n, m, mlen, c4);
ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ");
ck_assert_msg(c1len == mlen + (uint16_t)CRYPTO_MAC_SIZE, "wrong cyphertext length");
@ -177,10 +185,10 @@ static void test_endtoend(void)
&& memcmp(c1, c4, c1len) == 0, "crypertexts differ");
//Decrypt all four ways
const uint16_t m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1);
const uint16_t m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2);
const uint16_t m3len = decrypt_data_symmetric(k1, n, c1, c1len, m3);
const uint16_t m4len = decrypt_data_symmetric(k2, n, c1, c1len, m4);
const uint16_t m1len = decrypt_data(mem, pk2, sk1, n, c1, c1len, m1);
const uint16_t m2len = decrypt_data(mem, pk1, sk2, n, c1, c1len, m2);
const uint16_t m3len = decrypt_data_symmetric(mem, k1, n, c1, c1len, m3);
const uint16_t m4len = decrypt_data_symmetric(mem, k2, n, c1, c1len, m4);
ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ");
ck_assert_msg(m1len == mlen, "wrong decrypted text length");
@ -192,6 +200,8 @@ static void test_endtoend(void)
static void test_large_data(void)
{
const Memory *mem = os_memory();
ck_assert(mem != nullptr);
const Random *rng = os_random();
ck_assert(rng != nullptr);
uint8_t k[CRYPTO_SHARED_KEY_SIZE];
@ -216,13 +226,13 @@ static void test_large_data(void)
//Generate key
rand_bytes(rng, k, CRYPTO_SHARED_KEY_SIZE);
const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1);
const uint16_t c2len = encrypt_data_symmetric(k, n, m2, m2_size, c2);
const uint16_t c1len = encrypt_data_symmetric(mem, k, n, m1, m1_size, c1);
const uint16_t c2len = encrypt_data_symmetric(mem, k, n, m2, m2_size, c2);
ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt");
ck_assert_msg(c2len == m2_size + CRYPTO_MAC_SIZE, "could not encrypt");
const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime);
const uint16_t m1plen = decrypt_data_symmetric(mem, k, n, c1, c1len, m1prime);
ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ");
ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ");
@ -236,6 +246,8 @@ static void test_large_data(void)
static void test_large_data_symmetric(void)
{
const Memory *mem = os_memory();
ck_assert(mem != nullptr);
const Random *rng = os_random();
ck_assert(rng != nullptr);
uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE];
@ -256,10 +268,10 @@ static void test_large_data_symmetric(void)
//Generate key
new_symmetric_key(rng, k);
const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1);
const uint16_t c1len = encrypt_data_symmetric(mem, k, n, m1, m1_size, c1);
ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt data");
const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime);
const uint16_t m1plen = decrypt_data_symmetric(mem, k, n, c1, c1len, m1prime);
ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ");
ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ");
@ -271,6 +283,8 @@ static void test_large_data_symmetric(void)
static void test_very_large_data(void)
{
const Memory *mem = os_memory();
ck_assert(mem != nullptr);
const Random *rng = os_random();
ck_assert(rng != nullptr);
@ -287,7 +301,9 @@ static void test_very_large_data(void)
ck_assert(plain != nullptr);
ck_assert(encrypted != nullptr);
encrypt_data(pk, sk, nonce, plain, plain_size, encrypted);
memset(plain, 0, plain_size);
encrypt_data(mem, pk, sk, nonce, plain, plain_size, encrypted);
free(encrypted);
free(plain);

View File

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

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));
ck_assert(subtox != nullptr);
subtox->log = logger_new();
subtox->log = logger_new(mem);
ck_assert(subtox->log != nullptr);
logger_callback_log(subtox->log, print_debug_logger, nullptr, index);
subtox->mono_time = mono_time_new(mem, nullptr, nullptr);

View File

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

View File

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

View File

@ -109,7 +109,7 @@ static int handle_test_3(void *object, const IP_Port *source, const uint8_t *pac
#if 0
print_client_id(packet, length);
#endif
int len = decrypt_data(test_3_pub_key, dht_get_self_secret_key(onion->dht),
int len = decrypt_data(onion->mem, test_3_pub_key, dht_get_self_secret_key(onion->dht),
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE,
2 + CRYPTO_SHA256_SIZE + CRYPTO_MAC_SIZE, plain);
@ -144,7 +144,7 @@ static int handle_test_3_old(void *object, const IP_Port *source, const uint8_t
#if 0
print_client_id(packet, length);
#endif
int len = decrypt_data(test_3_pub_key, dht_get_self_secret_key(onion->dht),
int len = decrypt_data(onion->mem, test_3_pub_key, dht_get_self_secret_key(onion->dht),
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE,
1 + CRYPTO_SHA256_SIZE + CRYPTO_MAC_SIZE, plain);
@ -182,7 +182,7 @@ static int handle_test_4(void *object, const IP_Port *source, const uint8_t *pac
return 1;
}
int len = decrypt_data(packet + 1 + CRYPTO_NONCE_SIZE, dht_get_self_secret_key(onion->dht), packet + 1,
int len = decrypt_data(onion->mem, packet + 1 + CRYPTO_NONCE_SIZE, dht_get_self_secret_key(onion->dht), packet + 1,
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, sizeof("Install gentoo") + CRYPTO_MAC_SIZE, plain);
if (len == -1) {
@ -202,10 +202,10 @@ static int handle_test_4(void *object, const IP_Port *source, const uint8_t *pac
* Use Onion_Path path to send data of length to dest.
* Maximum length of data is ONION_MAX_DATA_SIZE.
*/
static void send_onion_packet(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length)
static void send_onion_packet(const Networking_Core *net, const Memory *mem, const Random *rng, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length)
{
uint8_t packet[ONION_MAX_PACKET_SIZE];
const int len = create_onion_packet(rng, packet, sizeof(packet), path, dest, data, length);
const int len = create_onion_packet(mem, rng, packet, sizeof(packet), path, dest, data, length);
ck_assert_msg(len != -1, "failed to create onion packet");
ck_assert_msg(sendpacket(net, &path->ip_port1, packet, len) == len, "failed to send onion packet");
}
@ -228,9 +228,9 @@ static void test_basic(void)
const Random *rng = os_random();
ck_assert(rng != nullptr);
Logger *log1 = logger_new();
Logger *log1 = logger_new(mem);
logger_callback_log(log1, print_debug_logger, nullptr, &index[0]);
Logger *log2 = logger_new();
Logger *log2 = logger_new(mem);
logger_callback_log(log2, print_debug_logger, nullptr, &index[1]);
Mono_Time *mono_time1 = mono_time_new(mem, nullptr, nullptr);
@ -264,7 +264,7 @@ static void test_basic(void)
nodes[3] = n2;
Onion_Path path;
create_onion_path(rng, onion1->dht, &path, nodes);
send_onion_packet(onion1->net, rng, &path, &nodes[3].ip_port, req_packet, sizeof(req_packet));
send_onion_packet(onion1->net, onion1->mem, rng, &path, &nodes[3].ip_port, req_packet, sizeof(req_packet));
handled_test_1 = 0;
@ -291,7 +291,7 @@ static void test_basic(void)
uint64_t s;
memcpy(&s, sb_data, sizeof(uint64_t));
memcpy(test_3_pub_key, nodes[3].public_key, CRYPTO_PUBLIC_KEY_SIZE);
int ret = send_announce_request(log1, onion1->net, rng, &path, &nodes[3],
int ret = send_announce_request(log1, onion1->mem, onion1->net, rng, &path, &nodes[3],
dht_get_self_public_key(onion1->dht),
dht_get_self_secret_key(onion1->dht),
zeroes,
@ -313,7 +313,7 @@ static void test_basic(void)
memcpy(onion_announce_entry_public_key(onion2_a, 1), dht_get_self_public_key(onion2->dht), CRYPTO_PUBLIC_KEY_SIZE);
onion_announce_entry_set_time(onion2_a, 1, mono_time_get(mono_time2));
networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1);
send_announce_request(log1, onion1->net, rng, &path, &nodes[3],
send_announce_request(log1, onion1->mem, onion1->net, rng, &path, &nodes[3],
dht_get_self_public_key(onion1->dht),
dht_get_self_secret_key(onion1->dht),
test_3_ping_id,
@ -329,7 +329,7 @@ static void test_basic(void)
CRYPTO_PUBLIC_KEY_SIZE) != 0);
c_sleep(1000);
Logger *log3 = logger_new();
Logger *log3 = logger_new(mem);
logger_callback_log(log3, print_debug_logger, nullptr, &index[2]);
Mono_Time *mono_time3 = mono_time_new(mem, nullptr, nullptr);
@ -338,7 +338,7 @@ static void test_basic(void)
ck_assert_msg((onion3 != nullptr), "Onion failed initializing.");
random_nonce(rng, nonce);
ret = send_data_request(log3, onion3->net, rng, &path, &nodes[3].ip_port,
ret = send_data_request(log3, onion3->mem, onion3->net, rng, &path, &nodes[3].ip_port,
dht_get_self_public_key(onion1->dht),
dht_get_self_public_key(onion1->dht),
nonce, (const uint8_t *)"Install gentoo", sizeof("Install gentoo"));
@ -412,7 +412,7 @@ static Onions *new_onions(const Memory *mem, const Random *rng, uint16_t port, u
return nullptr;
}
on->log = logger_new();
on->log = logger_new(mem);
if (!on->log) {
free(on);

View File

@ -168,29 +168,33 @@ static void test_av_three_calls(void)
Time_Data time_data;
pthread_mutex_init(&time_data.lock, nullptr);
{
Tox_Options *opts = tox_options_new(nullptr);
ck_assert(opts != nullptr);
tox_options_set_experimental_thread_safety(opts, true);
Tox_Err_New error;
bootstrap = tox_new_log(nullptr, &error, &index[0]);
bootstrap = tox_new_log(opts, &error, &index[0]);
ck_assert(error == TOX_ERR_NEW_OK);
time_data.clock = current_time_monotonic(bootstrap->mono_time);
set_current_time_callback(bootstrap, &time_data);
alice = tox_new_log(nullptr, &error, &index[1]);
alice = tox_new_log(opts, &error, &index[1]);
ck_assert(error == TOX_ERR_NEW_OK);
set_current_time_callback(alice, &time_data);
bobs[0] = tox_new_log(nullptr, &error, &index[2]);
bobs[0] = tox_new_log(opts, &error, &index[2]);
ck_assert(error == TOX_ERR_NEW_OK);
set_current_time_callback(bobs[0], &time_data);
bobs[1] = tox_new_log(nullptr, &error, &index[3]);
bobs[1] = tox_new_log(opts, &error, &index[3]);
ck_assert(error == TOX_ERR_NEW_OK);
set_current_time_callback(bobs[1], &time_data);
bobs[2] = tox_new_log(nullptr, &error, &index[4]);
bobs[2] = tox_new_log(opts, &error, &index[4]);
ck_assert(error == TOX_ERR_NEW_OK);
set_current_time_callback(bobs[2], &time_data);
tox_options_free(opts);
}
printf("Created 5 instances of Tox\n");

View File

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

View File

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

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.
AC_PREREQ([2.65])
AC_INIT([tox], [0.2.19])
AC_INIT([tox], [0.2.20])
AC_CONFIG_AUX_DIR(configure_aux)
AC_CONFIG_SRCDIR([toxcore/net_crypto.c])
AM_INIT_AUTOMAKE([foreign 1.10 -Wall -Werror subdir-objects tar-ustar])

View File

@ -21,10 +21,15 @@ cc_binary(
"//c-toxcore/toxcore:Messenger",
"//c-toxcore/toxcore:TCP_server",
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:crypto_core",
"//c-toxcore/toxcore:forwarding",
"//c-toxcore/toxcore:group_announce",
"//c-toxcore/toxcore:group_onion_announce",
"//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mem",
"//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:network",
"//c-toxcore/toxcore:onion",
"//c-toxcore/toxcore:onion_announce",
"//c-toxcore/toxcore:tox",
],

View File

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

View File

@ -15,7 +15,7 @@ CPPFLAGS+=("-Itoxav")
CPPFLAGS+=("-Itoxencryptsave")
CPPFLAGS+=("-Ithird_party/cmp")
LDFLAGS=("-lopus" "-lsodium" "-lvpx" "-lpthread" "-lconfig" "-lgmock" "-lgtest")
LDFLAGS=("-lopus" "-lsodium" "-lvpx" "-lpthread" "-lconfig" "-lgmock" "-lgtest" "-lbenchmark")
LDFLAGS+=("-fuse-ld=gold")
LDFLAGS+=("-Wl,--detect-odr-violations")
LDFLAGS+=("-Wl,--warn-common")
@ -27,7 +27,7 @@ put() {
if [ "$SKIP_LINES" = "" ]; then
echo "#line 1 \"$1\"" >>amalgamation.cc
fi
cat "$1" >>amalgamation.cc
grep -v '^BENCHMARK_MAIN' "$1" >>amalgamation.cc
}
putmain() {

View File

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

View File

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

View File

@ -6,16 +6,24 @@ cc_binary(
"src/*.c",
"src/*.h",
]),
tags = ["no-windows"],
deps = [
"//c-toxcore/other:bootstrap_node_packets",
"//c-toxcore/toxcore:DHT",
"//c-toxcore/toxcore:LAN_discovery",
"//c-toxcore/toxcore:TCP_server",
"//c-toxcore/toxcore:announce",
"//c-toxcore/toxcore:attributes",
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:crypto_core",
"//c-toxcore/toxcore:forwarding",
"//c-toxcore/toxcore:group_announce",
"//c-toxcore/toxcore:group_onion_announce",
"//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mem",
"//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:network",
"//c-toxcore/toxcore:onion",
"//c-toxcore/toxcore:onion_announce",
"//c-toxcore/toxcore:tox",
"@libconfig",

View File

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

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,
int *enable_ipv6, int *enable_ipv4_fallback, int *enable_lan_discovery, int *enable_tcp_relay,
uint16_t **tcp_relay_ports, int *tcp_relay_port_count, int *enable_motd, char **motd)
bool *enable_ipv6, bool *enable_ipv4_fallback, bool *enable_lan_discovery, bool *enable_tcp_relay,
uint16_t **tcp_relay_ports, int *tcp_relay_port_count, bool *enable_motd, char **motd)
{
config_t cfg;
@ -207,14 +218,14 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
memcpy(*keys_file_path, tmp_keys_file, keys_file_path_len);
// Get IPv6 option
if (config_lookup_bool(&cfg, NAME_ENABLE_IPV6, enable_ipv6) == CONFIG_FALSE) {
if (tox_config_lookup_bool(&cfg, NAME_ENABLE_IPV6, enable_ipv6) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_IPV6);
log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_IPV6, DEFAULT_ENABLE_IPV6 ? "true" : "false");
*enable_ipv6 = DEFAULT_ENABLE_IPV6;
}
// Get IPv4 fallback option
if (config_lookup_bool(&cfg, NAME_ENABLE_IPV4_FALLBACK, enable_ipv4_fallback) == CONFIG_FALSE) {
if (tox_config_lookup_bool(&cfg, NAME_ENABLE_IPV4_FALLBACK, enable_ipv4_fallback) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_IPV4_FALLBACK);
log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_IPV4_FALLBACK,
DEFAULT_ENABLE_IPV4_FALLBACK ? "true" : "false");
@ -222,7 +233,7 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
}
// Get LAN discovery option
if (config_lookup_bool(&cfg, NAME_ENABLE_LAN_DISCOVERY, enable_lan_discovery) == CONFIG_FALSE) {
if (tox_config_lookup_bool(&cfg, NAME_ENABLE_LAN_DISCOVERY, enable_lan_discovery) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_LAN_DISCOVERY);
log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_LAN_DISCOVERY,
DEFAULT_ENABLE_LAN_DISCOVERY ? "true" : "false");
@ -230,28 +241,28 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
}
// Get TCP relay option
if (config_lookup_bool(&cfg, NAME_ENABLE_TCP_RELAY, enable_tcp_relay) == CONFIG_FALSE) {
if (tox_config_lookup_bool(&cfg, NAME_ENABLE_TCP_RELAY, enable_tcp_relay) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_TCP_RELAY);
log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_TCP_RELAY,
DEFAULT_ENABLE_TCP_RELAY ? "true" : "false");
*enable_tcp_relay = DEFAULT_ENABLE_TCP_RELAY;
}
if (*enable_tcp_relay != 0) {
if (*enable_tcp_relay) {
parse_tcp_relay_ports_config(&cfg, tcp_relay_ports, tcp_relay_port_count);
} else {
*tcp_relay_port_count = 0;
}
// Get MOTD option
if (config_lookup_bool(&cfg, NAME_ENABLE_MOTD, enable_motd) == CONFIG_FALSE) {
if (tox_config_lookup_bool(&cfg, NAME_ENABLE_MOTD, enable_motd) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_MOTD);
log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_MOTD,
DEFAULT_ENABLE_MOTD ? "true" : "false");
*enable_motd = DEFAULT_ENABLE_MOTD;
}
if (*enable_motd != 0) {
if (*enable_motd) {
// Get MOTD
const char *tmp_motd;
@ -273,14 +284,14 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_PID_FILE_PATH, *pid_file_path);
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_KEYS_FILE_PATH, *keys_file_path);
log_write(LOG_LEVEL_INFO, "'%s': %d\n", NAME_PORT, *port);
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV6, *enable_ipv6 != 0 ? "true" : "false");
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV4_FALLBACK, *enable_ipv4_fallback != 0 ? "true" : "false");
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, *enable_lan_discovery != 0 ? "true" : "false");
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV6, *enable_ipv6 ? "true" : "false");
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV4_FALLBACK, *enable_ipv4_fallback ? "true" : "false");
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, *enable_lan_discovery ? "true" : "false");
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_TCP_RELAY, *enable_tcp_relay != 0 ? "true" : "false");
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_TCP_RELAY, *enable_tcp_relay ? "true" : "false");
// Show info about tcp ports only if tcp relay is enabled
if (*enable_tcp_relay != 0) {
if (*enable_tcp_relay) {
if (*tcp_relay_port_count == 0) {
log_write(LOG_LEVEL_ERROR, "No TCP ports could be read.\n");
} else {
@ -292,9 +303,9 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
}
}
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_MOTD, *enable_motd != 0 ? "true" : "false");
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_MOTD, *enable_motd ? "true" : "false");
if (*enable_motd != 0) {
if (*enable_motd) {
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_MOTD, *motd);
}
@ -379,6 +390,9 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6
bool address_resolved;
uint8_t *bs_public_key_bin;
// TODO(iphydf): Maybe disable it and only use IP addresses?
const bool dns_enabled = true;
node = config_setting_get_elem(node_list, 0);
if (node == nullptr) {
@ -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);
address_resolved = dht_bootstrap_from_address(dht, bs_address, enable_ipv6, net_htons(bs_port),
address_resolved = dht_bootstrap_from_address(dht, bs_address, enable_ipv6, dns_enabled, net_htons(bs_port),
bs_public_key_bin);
free(bs_public_key_bin);

View File

@ -17,14 +17,14 @@
*
* Important: You are responsible for freeing `pid_file_path` and `keys_file_path`
* also, iff `tcp_relay_ports_count` > 0, then you are responsible for freeing `tcp_relay_ports`
* and also `motd` iff `enable_motd` is set.
* and also `motd` iff `enable_motd` is true.
*
* @return true on success,
* false on failure, doesn't modify any data pointed by arguments.
*/
bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **keys_file_path, int *port,
int *enable_ipv6, int *enable_ipv4_fallback, int *enable_lan_discovery, int *enable_tcp_relay,
uint16_t **tcp_relay_ports, int *tcp_relay_port_count, int *enable_motd, char **motd);
bool *enable_ipv6, bool *enable_ipv4_fallback, bool *enable_lan_discovery, bool *enable_tcp_relay,
uint16_t **tcp_relay_ports, int *tcp_relay_port_count, bool *enable_motd, char **motd);
/**
* Bootstraps off nodes listed in the config file.

View File

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

View File

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

View File

@ -4,4 +4,4 @@ go 1.17
require github.com/gorilla/websocket v1.5.1
require golang.org/x/net v0.17.0 // indirect
require golang.org/x/net v0.23.0 // indirect

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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@ -11,8 +13,10 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -24,17 +28,22 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=

View File

@ -1,18 +1,18 @@
################################################
# cmake-asan
FROM ubuntu:20.04
FROM ubuntu:24.04
RUN apt-get update && \
DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \
clang \
cmake \
libclang-rt-dev \
libconfig-dev \
libgmock-dev \
libgtest-dev \
libopus-dev \
libsodium-dev \
libvpx-dev \
llvm-dev \
ninja-build \
pkg-config \
&& apt-get clean \
@ -22,8 +22,8 @@ COPY entrypoint.sh /
RUN ["chmod", "755", "/entrypoint.sh"]
WORKDIR /home/builder
RUN groupadd -r -g 1000 builder \
&& useradd --no-log-init -r -g builder -u 1000 builder \
RUN groupadd -r -g 987 builder \
&& useradd --no-log-init -r -g builder -u 987 builder \
&& chown builder:builder /home/builder
USER builder

View File

@ -1,9 +1,9 @@
#!/bin/sh
set -eu
set -eux
SANITIZER="${1:-asan}"
cp -a /c-toxcore .
cd c-toxcore
.circleci/cmake-"$SANITIZER"
.circleci/cmake-"$SANITIZER" || (cat /home/builder/c-toxcore/_build/CMakeFiles/CMakeError.log && false)

View File

@ -1,6 +1,14 @@
#!/bin/sh
set -eux
SANITIZER="${1:-asan}"
if [ -t 0 ]; then
TTY=true
else
TTY=false
fi
docker build -t toxchat/c-toxcore:circleci other/docker/circleci
docker run --name toxcore-circleci --rm -it -v "$PWD:/c-toxcore" toxchat/c-toxcore:circleci "$SANITIZER"
docker run --name toxcore-circleci --rm --interactive="$TTY" --tty="$TTY" --volume "$PWD:/c-toxcore" toxchat/c-toxcore:circleci "$SANITIZER"

View File

@ -9,6 +9,7 @@ cc_binary(
"main/tox_main.h",
],
deps = [
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:tox_events",
],

View File

@ -50,6 +50,10 @@ module "//c-toxcore/third_party:cmp" {
module "//c-toxcore/toxencryptsave:defines" {
header "toxencryptsave/defines.h"
}
module "@benchmark" {
textual header "/usr/include/benchmark/benchmark.h"
use std
}
module "@com_google_googletest//:gtest" {
textual header "/usr/include/gmock/gmock.h"
textual header "/usr/include/gtest/gtest.h"
@ -83,9 +87,9 @@ class Context:
pass
def bzl_exports_files(
self,
srcs: list[str],
visibility: Optional[list[str]] = None,
self,
srcs: list[str],
visibility: Optional[list[str]] = None,
) -> None:
pass
@ -110,7 +114,7 @@ class Context:
hdrs,
}
def bzl_cc_test(
def bzl_cc_binary(
self,
name: str,
srcs: Iterable[str] = tuple(),
@ -161,7 +165,8 @@ def main() -> None:
"load": ctx.bzl_load,
"exports_files": ctx.bzl_exports_files,
"cc_library": ctx.bzl_cc_library,
"cc_test": ctx.bzl_cc_test,
"cc_binary": ctx.bzl_cc_binary,
"cc_test": ctx.bzl_cc_binary,
"cc_fuzz_test": ctx.bzl_cc_fuzz_test,
"select": ctx.bzl_select,
"glob": ctx.bzl_glob,

View File

@ -3,6 +3,7 @@ FROM alpine:3.19.0
RUN ["apk", "add", "--no-cache", \
"bash", \
"benchmark-dev", \
"clang", \
"gtest-dev", \
"libconfig-dev", \

View File

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

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"]
WORKDIR /work/pkgsrc/chat/toxcore
RUN ["sed", "-i", "-e", "s/libtoxcore.so.2.18.0/libtoxcore.so.2.19.0/g", "PLIST"]
RUN ["sed", "-i", "-e", "s/libtoxcore.so.2.18.0/libtoxcore.so.2.20.0/g", "PLIST"]
RUN ["bmake", "clean"]
RUN ["bmake", "DISTFILES=c-toxcore.tar.gz", "DISTDIR=/work", "NO_CHECKSUM=yes"]
RUN ["bmake", "install"]

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 << " event.type = TOX_EVENT_" << str_toupper(event_name) << ";\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";
// unpack

View File

@ -137,7 +137,7 @@ int main(int argc, char *argv[])
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]);
Tox_Err_Friend_Add friend_err;
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);
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);
*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);
fclose(f);
return -2; // -2 means file reading fail
@ -55,13 +55,13 @@ int main(int argc, char *argv[])
crypto_sign_ed25519_keypair(pk, sk);
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("\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]);
}

View File

@ -117,7 +117,7 @@ int main(int argc, char *argv[])
#endif
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) {
found = 1;
break;

View File

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

View File

@ -4,4 +4,5 @@ cc_binary(
name = "grencez_tok5",
srcs = ["grencez_tok5.c"],
copts = ["-Wno-unused-result"],
tags = ["no-windows"],
)

View File

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

View File

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

View File

@ -10,22 +10,34 @@ ENV NO_ARCH_OPT 1
RUN apt-get update && \
apt-get -y install --no-install-suggests --no-install-recommends \
apt-transport-https \
apt-utils \
automake \
ninja-build \
bash-completion \
bison flex \
build-essential \
git \
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 \
ca-certificates \
cmake \
parallel \
dialog \
git \
gnupg \
gnuplot-nox \
jupp \
less \
libglib2.0-dev \
libpixman-1-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/*
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 && \
apt-get -y install --no-install-suggests --no-install-recommends \
gcc-10 g++-10 gcc-10-plugin-dev gcc-10-multilib gcc-multilib gdb lcov \
clang-12 clang-tools-12 libc++1-12 libc++-12-dev \
libc++abi1-12 libc++abi-12-dev libclang1-12 libclang-12-dev \
libclang-common-12-dev libclang-cpp12 libclang-cpp12-dev liblld-12 \
liblld-12-dev liblldb-12 liblldb-12-dev libllvm12 libomp-12-dev \
libomp5-12 lld-12 lldb-12 llvm-12 llvm-12-dev llvm-12-runtime llvm-12-tools \
clang-12 \
clang-tools-12 \
g++-10 \
gcc-10 \
gcc-10-multilib \
gcc-10-plugin-dev \
gcc-multilib \
gdb \
lcov \
libc++-12-dev \
libc++1-12 \
libc++abi-12-dev \
libc++abi1-12 \
libclang-12-dev \
libclang-common-12-dev \
libclang-cpp12 \
libclang-cpp12-dev \
libclang1-12 \
liblld-12 \
liblld-12-dev \
liblldb-12 \
liblldb-12-dev \
libllvm12 \
libomp-12-dev \
libomp5-12 \
lld-12 \
lldb-12 \
llvm-12 \
llvm-12-dev \
llvm-12-runtime \
llvm-12-tools \
&& rm -rf /var/lib/apt/lists/*
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 0

View File

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

View File

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

View File

@ -48,6 +48,7 @@ cc_fuzz_test(
deps = [
":fuzz_support",
":fuzz_tox",
"//c-toxcore/toxcore:crypto_core",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:tox_dispatch",
"//c-toxcore/toxcore:tox_events",
@ -102,6 +103,7 @@ cc_test(
deps = [
":fuzz_support",
":fuzz_tox",
"//c-toxcore/toxcore:crypto_core",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:tox_dispatch",
"//c-toxcore/toxcore:tox_events",
@ -117,6 +119,7 @@ cc_fuzz_test(
deps = [
":fuzz_support",
":fuzz_tox",
"//c-toxcore/toxcore:crypto_core",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:tox_dispatch",
"//c-toxcore/toxcore:tox_events",

View File

@ -4,8 +4,15 @@
#include "fuzz_support.hh"
#ifdef _WIN32
#include <winsock2.h>
// Comment line here to avoid reordering by source code formatters.
#include <windows.h>
#include <ws2tcpip.h>
#else
#include <arpa/inet.h>
#include <sys/socket.h>
#endif
#include <algorithm>
#include <cassert>
@ -111,6 +118,7 @@ static constexpr Network_Funcs fuzz_network_funcs = {
/* .accept = */ ![](Fuzz_System *self, Socket sock) { return Socket{1337}; },
/* .bind = */ ![](Fuzz_System *self, Socket sock, const Network_Addr *addr) { return 0; },
/* .listen = */ ![](Fuzz_System *self, Socket sock, int backlog) { return 0; },
/* .connect = */ ![](Fuzz_System *self, Socket sock, const Network_Addr *addr) { return 0; },
/* .recvbuf = */
![](Fuzz_System *self, Socket sock) {
assert(sock.value == 42 || sock.value == 1337);
@ -225,6 +233,7 @@ static constexpr Network_Funcs null_network_funcs = {
/* .accept = */ ![](Null_System *self, Socket sock) { return Socket{1337}; },
/* .bind = */ ![](Null_System *self, Socket sock, const Network_Addr *addr) { return 0; },
/* .listen = */ ![](Null_System *self, Socket sock, int backlog) { return 0; },
/* .connect = */ ![](Null_System *self, Socket sock, const Network_Addr *addr) { return 0; },
/* .recvbuf = */ ![](Null_System *self, Socket sock) { return 0; },
/* .recv = */
![](Null_System *self, Socket sock, uint8_t *buf, size_t len) {
@ -341,6 +350,7 @@ static constexpr Network_Funcs record_network_funcs = {
return 0;
},
/* .listen = */ ![](Record_System *self, Socket sock, int backlog) { return 0; },
/* .connect = */ ![](Record_System *self, Socket sock, const Network_Addr *addr) { return 0; },
/* .recvbuf = */ ![](Record_System *self, Socket sock) { return 0; },
/* .recv = */
![](Record_System *self, Socket sock, uint8_t *buf, size_t len) {

View File

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

View File

@ -42,127 +42,32 @@ cc_library(
)
cc_library(
name = "bwcontroller",
srcs = ["bwcontroller.c"],
hdrs = ["bwcontroller.h"],
name = "toxav",
srcs = glob(
[
"*.c",
"*.h",
],
exclude = ["toxav.h"],
),
hdrs = ["toxav.h"],
visibility = ["//c-toxcore:__subpackages__"],
deps = [
":ring_buffer",
"//c-toxcore/toxcore",
"//c-toxcore/toxcore:Messenger",
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:util",
],
)
cc_library(
name = "rtp",
srcs = ["rtp.c"],
hdrs = ["rtp.h"],
deps = [
":bwcontroller",
"//c-toxcore/toxcore:Messenger",
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:util",
],
)
cc_test(
name = "rtp_test",
size = "small",
srcs = ["rtp_test.cc"],
deps = [
":rtp",
"//c-toxcore/toxcore:crypto_core",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "audio",
srcs = ["audio.c"],
hdrs = ["audio.h"],
deps = [
":public_api",
":rtp",
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:util",
"@opus",
],
)
cc_library(
name = "video",
srcs = [
"msi.c",
"video.c",
],
hdrs = [
"msi.h",
"video.h",
],
deps = [
":audio",
":public_api",
":ring_buffer",
":rtp",
"//c-toxcore/toxcore:Messenger",
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:network",
"//c-toxcore/toxcore:util",
"@libvpx",
],
)
cc_library(
name = "groupav",
srcs = ["groupav.c"],
hdrs = ["groupav.h"],
deps = [
"//c-toxcore/toxcore",
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:group",
"//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:net_crypto",
"//c-toxcore/toxcore:network",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:util",
"@libsodium",
"@libvpx",
"@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(
name = "cimple_files",
srcs = glob([

View File

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

View File

@ -13,6 +13,7 @@
#include "../toxcore/ccompat.h"
#include "../toxcore/logger.h"
#include "../toxcore/mono_time.h"
#include "../toxcore/network.h"
static struct JitterBuffer *jbuf_new(uint32_t capacity);
static void jbuf_clear(struct JitterBuffer *q);
@ -25,6 +26,8 @@ static bool reconfigure_audio_encoder(const Logger *log, OpusEncoder **e, uint32
uint8_t new_ch, uint32_t *old_br, uint32_t *old_sr, uint8_t *old_ch);
static bool reconfigure_audio_decoder(ACSession *ac, uint32_t sampling_rate, uint8_t channels);
ACSession *ac_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t friend_number,
toxav_audio_receive_frame_cb *cb, void *cb_data)
{
@ -150,9 +153,9 @@ void ac_iterate(ACSession *ac)
ac->lp_channel_count = opus_packet_get_nb_channels(msg->data + 4);
/* NOTE: even though OPUS supports decoding mono frames with stereo decoder and vice versa,
* it didn't work quite well.
*/
/** NOTE: even though OPUS supports decoding mono frames with stereo decoder and vice versa,
* it didn't work quite well.
*/
if (!reconfigure_audio_decoder(ac, ac->lp_sampling_rate, ac->lp_channel_count)) {
LOGGER_WARNING(ac->log, "Failed to reconfigure decoder!");
free(msg);
@ -273,6 +276,7 @@ static struct JitterBuffer *jbuf_new(uint32_t capacity)
q->capacity = capacity;
return q;
}
static void jbuf_clear(struct JitterBuffer *q)
{
while (q->bottom != q->top) {
@ -281,6 +285,7 @@ static void jbuf_clear(struct JitterBuffer *q)
++q->bottom;
}
}
static void jbuf_free(struct JitterBuffer *q)
{
if (q == nullptr) {
@ -291,6 +296,11 @@ static void jbuf_free(struct JitterBuffer *q)
free(q->queue);
free(q);
}
/*
* if -1 is returned the RTPMessage m needs to be free'd by the caller
* if 0 is returned the RTPMessage m is stored in the ringbuffer and must NOT be freed by the caller
*/
static int jbuf_write(const Logger *log, struct JitterBuffer *q, struct RTPMessage *m)
{
const uint16_t sequnum = m->header.sequnum;
@ -319,6 +329,7 @@ static int jbuf_write(const Logger *log, struct JitterBuffer *q, struct RTPMessa
return 0;
}
static struct RTPMessage *jbuf_read(struct JitterBuffer *q, int32_t *success)
{
if (q->top == q->bottom) {

View File

@ -10,12 +10,16 @@
#include <string.h>
#include "ring_buffer.h"
#include "toxav_hacks.h"
#include "../toxcore/ccompat.h"
#include "../toxcore/logger.h"
#include "../toxcore/mono_time.h"
#include "../toxcore/network.h"
#include "../toxcore/tox_private.h"
#include "../toxcore/util.h"
#define BWC_PACKET_ID 196
#define BWC_SEND_INTERVAL_MS 950 // 0.95s
#define BWC_AVG_PKT_COUNT 20
@ -38,9 +42,8 @@ typedef struct BWCRcvPkt {
struct BWController {
m_cb *mcb;
void *mcb_user_data;
Messenger *m;
Tox *tox;
const Logger *log;
uint32_t friend_number;
BWCCycle cycle;
@ -49,6 +52,7 @@ struct BWController {
uint32_t packet_loss_counted_cycles;
Mono_Time *bwc_mono_time;
bool bwc_receive_active; /* if this is set to false then incoming bwc packets will not be processed by bwc_handle_data() */
};
struct BWCMessage {
@ -56,11 +60,11 @@ struct BWCMessage {
uint32_t recv;
};
static int bwc_handle_data(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object);
static int bwc_send_custom_lossy_packet(Tox *tox, int32_t friendnumber, const uint8_t *data, uint32_t length);
static void bwc_handle_data(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data);
static void send_update(BWController *bwc);
BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb, void *mcb_user_data,
BWController *bwc_new(const Logger *log, Tox *tox, uint32_t friendnumber, m_cb *mcb, void *mcb_user_data,
Mono_Time *bwc_mono_time)
{
BWController *retu = (BWController *)calloc(1, sizeof(BWController));
@ -69,16 +73,18 @@ BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb,
return nullptr;
}
LOGGER_DEBUG(m->log, "Creating bandwidth controller");
LOGGER_DEBUG(log, "Creating bandwidth controller");
retu->mcb = mcb;
retu->mcb_user_data = mcb_user_data;
retu->m = m;
retu->friend_number = friendnumber;
retu->bwc_mono_time = bwc_mono_time;
const uint64_t now = current_time_monotonic(bwc_mono_time);
retu->cycle.last_sent_timestamp = now;
retu->cycle.last_refresh_timestamp = now;
retu->tox = tox;
retu->log = log;
retu->bwc_receive_active = true;
retu->rcvpkt.rb = rb_new(BWC_AVG_PKT_COUNT);
retu->cycle.lost = 0;
retu->cycle.recv = 0;
@ -89,7 +95,6 @@ BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb,
rb_write(retu->rcvpkt.rb, &retu->rcvpkt.packet_length_array[i]);
}
m_callback_rtp_packet(m, friendnumber, BWC_PACKET_ID, bwc_handle_data, retu);
return retu;
}
@ -99,7 +104,6 @@ void bwc_kill(BWController *bwc)
return;
}
m_callback_rtp_packet(bwc->m, bwc->friend_number, BWC_PACKET_ID, nullptr, nullptr);
rb_kill(bwc->rcvpkt.rb);
free(bwc);
}
@ -111,7 +115,7 @@ void bwc_add_lost(BWController *bwc, uint32_t bytes_lost)
}
if (bytes_lost > 0) {
LOGGER_DEBUG(bwc->m->log, "BWC lost(1): %d", (int)bytes_lost);
LOGGER_DEBUG(bwc->log, "BWC lost(1): %d", (int)bytes_lost);
bwc->cycle.lost += bytes_lost;
send_update(bwc);
}
@ -135,7 +139,7 @@ static void send_update(BWController *bwc)
bwc->packet_loss_counted_cycles = 0;
if (bwc->cycle.lost != 0) {
LOGGER_DEBUG(bwc->m->log, "%p Sent update rcv: %u lost: %u percent: %f %%",
LOGGER_DEBUG(bwc->log, "%p Sent update rcv: %u lost: %u percent: %f %%",
(void *)bwc, bwc->cycle.recv, bwc->cycle.lost,
((double)bwc->cycle.lost / (bwc->cycle.recv + bwc->cycle.lost)) * 100.0);
uint8_t bwc_packet[sizeof(struct BWCMessage) + 1];
@ -148,13 +152,11 @@ static void send_update(BWController *bwc)
offset += net_pack_u32(bwc_packet + offset, bwc->cycle.recv);
assert(offset == sizeof(bwc_packet));
if (bwc_send_custom_lossy_packet(bwc->tox, bwc->friend_number, bwc_packet, sizeof(bwc_packet)) == -1) {
char *netstrerror = net_new_strerror(net_error());
char *stdstrerror = net_new_strerror(errno);
LOGGER_WARNING(bwc->m->log, "BWC send failed (len: %u)! std error: %s, net error %s",
(unsigned)sizeof(bwc_packet), stdstrerror, netstrerror);
net_kill_strerror(stdstrerror);
net_kill_strerror(netstrerror);
Tox_Err_Friend_Custom_Packet error;
tox_friend_send_lossy_packet(bwc->tox, bwc->friend_number, bwc_packet, sizeof(bwc_packet), &error);
if (error != TOX_ERR_FRIEND_CUSTOM_PACKET_OK) {
LOGGER_WARNING(bwc->log, "BWC send failed: %d", error);
}
}
@ -166,11 +168,11 @@ static void send_update(BWController *bwc)
static int on_update(BWController *bwc, const struct BWCMessage *msg)
{
LOGGER_DEBUG(bwc->m->log, "%p Got update from peer", (void *)bwc);
LOGGER_DEBUG(bwc->log, "%p Got update from peer", (void *)bwc);
/* Peers sent update too soon */
if (bwc->cycle.last_recv_timestamp + BWC_SEND_INTERVAL_MS > current_time_monotonic(bwc->bwc_mono_time)) {
LOGGER_INFO(bwc->m->log, "%p Rejecting extra update", (void *)bwc);
LOGGER_INFO(bwc->log, "%p Rejecting extra update", (void *)bwc);
return -1;
}
@ -180,8 +182,8 @@ static int on_update(BWController *bwc, const struct BWCMessage *msg)
if (lost != 0 && bwc->mcb != nullptr) {
const uint32_t recv = msg->recv;
LOGGER_DEBUG(bwc->m->log, "recved: %u lost: %u percentage: %f %%", recv, lost,
((double)lost / (recv + lost)) * 100.0);
LOGGER_DEBUG(bwc->log, "recved: %u lost: %u percentage: %f %%", recv, lost,
((double) lost / (recv + lost)) * 100.0);
bwc->mcb(bwc, bwc->friend_number,
(float)lost / (recv + lost),
bwc->mcb_user_data);
@ -190,28 +192,41 @@ static int on_update(BWController *bwc, const struct BWCMessage *msg)
return 0;
}
/*
* return -1 on failure, 0 on success
*
*/
static int bwc_send_custom_lossy_packet(Tox *tox, int32_t friendnumber, const uint8_t *data, uint32_t length)
static void bwc_handle_data(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data)
{
Tox_Err_Friend_Custom_Packet error;
tox_friend_send_lossy_packet(tox, friendnumber, data, (size_t)length, &error);
/* get BWController object from Tox and friend number */
ToxAV *toxav = (ToxAV *)tox_get_av_object(tox);
if (error == TOX_ERR_FRIEND_CUSTOM_PACKET_OK) {
return 0;
if (toxav == nullptr) {
// LOGGER_ERROR(log, "Could not get ToxAV object from Tox");
return;
}
return -1;
}
static int bwc_handle_data(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object)
{
BWController *bwc = (BWController *)object;
const Logger *log = toxav_get_logger(toxav);
if (length - 1 != sizeof(struct BWCMessage)) {
return -1;
LOGGER_ERROR(log, "Got BWCMessage of insufficient size.");
return;
}
const ToxAVCall *call = call_get(toxav, friend_number);
if (call == nullptr) {
LOGGER_ERROR(log, "Could not get ToxAVCall object from ToxAV.");
return;
}
/* get Call object from Tox and friend number */
BWController *bwc = bwc_controller_get(call);
if (bwc == nullptr) {
LOGGER_WARNING(log, "No session!");
return;
}
if (!bwc->bwc_receive_active) {
LOGGER_WARNING(log, "receiving not allowed!");
return;
}
size_t offset = 1; // Ignore packet id.
@ -220,5 +235,15 @@ static int bwc_handle_data(Messenger *m, uint32_t friend_number, const uint8_t *
offset += net_unpack_u32(data + offset, &msg.recv);
assert(offset == length);
return on_update(bwc, &msg);
on_update(bwc, &msg);
}
void bwc_allow_receiving(Tox *tox)
{
tox_callback_friend_lossy_packet_per_pktid(tox, bwc_handle_data, BWC_PACKET_ID);
}
void bwc_stop_receiving(Tox *tox)
{
tox_callback_friend_lossy_packet_per_pktid(tox, nullptr, BWC_PACKET_ID);
}

View File

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

View File

@ -476,7 +476,7 @@ int groupchat_enable_av(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t
return -1;
}
for (uint32_t i = 0; i < numpeers; ++i) {
for (uint32_t i = 0; i < (uint32_t)numpeers; ++i) {
group_av_peer_new(group_av, conference_number, i);
}
@ -508,7 +508,7 @@ int groupchat_disable_av(const Group_Chats *g_c, uint32_t conference_number)
return -1;
}
for (uint32_t i = 0; i < numpeers; ++i) {
for (uint32_t i = 0; i < (uint32_t)numpeers; ++i) {
group_av_peer_delete(group_av, conference_number, group_peer_get_object(g_c, conference_number, i));
group_peer_set_object(g_c, conference_number, i, nullptr);
}

View File

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

View File

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

View File

@ -9,12 +9,16 @@
#include <stdlib.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/logger.h"
#include "../toxcore/mono_time.h"
#include "../toxcore/net_crypto.h"
#include "../toxcore/tox_private.h"
#include "../toxcore/util.h"
/**
@ -23,30 +27,15 @@
*/
#define VIDEO_KEEP_KEYFRAME_IN_BUFFER_FOR_MS 15
/**
* return -1 on failure, 0 on success
*
*/
static int rtp_send_custom_lossy_packet(Tox *tox, int32_t friendnumber, const uint8_t *data, uint32_t length)
{
Tox_Err_Friend_Custom_Packet error;
tox_friend_send_lossy_packet(tox, friendnumber, data, (size_t)length, &error);
if (error == TOX_ERR_FRIEND_CUSTOM_PACKET_OK) {
return 0;
}
return -1;
}
// allocate_len is NOT including header!
static struct RTPMessage *new_message(const struct RTPHeader *header, size_t allocate_len, const uint8_t *data,
uint16_t data_length)
static struct RTPMessage *new_message(const Logger *log, const struct RTPHeader *header, size_t allocate_len,
const uint8_t *data, uint16_t data_length)
{
assert(allocate_len >= data_length);
struct RTPMessage *msg = (struct RTPMessage *)calloc(1, sizeof(struct RTPMessage) + allocate_len);
if (msg == nullptr) {
LOGGER_DEBUG(log, "Could not allocate RTPMessage buffer");
return nullptr;
}
@ -241,7 +230,7 @@ static struct RTPMessage *process_frame(const Logger *log, struct RTPWorkBufferL
}
/**
* @param log A logger.
* @param log A pointer to the Logger object.
* @param wkbl The list of in-progress frames, i.e. all the slots.
* @param slot_id The slot we want to fill the data into.
* @param is_keyframe Whether the data is part of a key frame.
@ -309,7 +298,7 @@ static bool fill_data_into_slot(const Logger *log, struct RTPWorkBufferList *wkb
return slot->received_len == header->data_length_full;
}
static void update_bwc_values(const Logger *log, RTPSession *session, const struct RTPMessage *msg)
static void update_bwc_values(RTPSession *session, const struct RTPMessage *msg)
{
if (session->first_packets_counter < DISMISS_FIRST_LOST_VIDEO_PACKET_COUNT) {
++session->first_packets_counter;
@ -319,7 +308,7 @@ static void update_bwc_values(const Logger *log, RTPSession *session, const stru
bwc_add_recv(session->bwc, data_length_full);
if (received_length_full < data_length_full) {
LOGGER_DEBUG(log, "BWC: full length=%u received length=%d", data_length_full, received_length_full);
LOGGER_DEBUG(session->log, "BWC: full length=%u received length=%d", data_length_full, received_length_full);
bwc_add_lost(session->bwc, data_length_full - received_length_full);
}
}
@ -347,22 +336,16 @@ static void update_bwc_values(const Logger *log, RTPSession *session, const stru
* @retval -1 on error.
* @retval 0 on success.
*/
static int handle_video_packet(RTPSession *session, const struct RTPHeader *header,
const uint8_t *incoming_data, uint16_t incoming_data_length, const Logger *log)
static int handle_video_packet(const Logger *log, RTPSession *session, const struct RTPHeader *header,
const uint8_t *incoming_data, uint16_t incoming_data_length)
{
// Full frame length in bytes. The frame may be split into multiple packets,
// but this value is the complete assembled frame size.
const uint32_t full_frame_length = header->data_length_full;
// Current offset in the frame. If this is the first packet of a multipart
// frame or it's not a multipart frame, then this value is 0.
const uint32_t offset = header->offset_full; // without header
// The sender tells us whether this is a key frame.
const bool is_keyframe = (header->flags & RTP_KEY_FRAME) != 0;
LOGGER_DEBUG(log, "-- handle_video_packet -- full lens=%u len=%u offset=%u is_keyframe=%s",
(unsigned)incoming_data_length, (unsigned)full_frame_length, (unsigned)offset, is_keyframe ? "K" : ".");
LOGGER_DEBUG(log, "wkbl->next_free_entry:003=%d", session->work_buffer_list->next_free_entry);
const bool is_multipart = full_frame_length != incoming_data_length;
@ -387,10 +370,13 @@ static int handle_video_packet(RTPSession *session, const struct RTPHeader *head
// get_slot just told us it's full, so process_frame must return non-null.
assert(m_new != nullptr);
LOGGER_DEBUG(log, "-- handle_video_packet -- CALLBACK-001a b0=%d b1=%d", (int)m_new->data[0], (int)m_new->data[1]);
update_bwc_values(log, session, m_new);
LOGGER_DEBUG(log, "-- handle_video_packet -- CALLBACK-001a b0=%d b1=%d", (int)m_new->data[0],
(int)m_new->data[1]);
update_bwc_values(session, m_new);
// Pass ownership of m_new to the callback.
session->mcb(session->m->mono_time, session->cs, m_new);
Mono_Time *mt = toxav_get_av_mono_time(session->toxav);
assert(mt != nullptr);
session->mcb(mt, session->cs, m_new);
// Now we no longer own m_new.
m_new = nullptr;
@ -425,9 +411,12 @@ static int handle_video_packet(RTPSession *session, const struct RTPHeader *head
struct RTPMessage *m_new = process_frame(log, session->work_buffer_list, slot_id);
if (m_new != nullptr) {
LOGGER_DEBUG(log, "-- handle_video_packet -- CALLBACK-003a b0=%d b1=%d", (int)m_new->data[0], (int)m_new->data[1]);
update_bwc_values(log, session, m_new);
session->mcb(session->m->mono_time, session->cs, m_new);
LOGGER_DEBUG(log, "-- handle_video_packet -- CALLBACK-003a b0=%d b1=%d", (int)m_new->data[0],
(int)m_new->data[1]);
update_bwc_values(session, m_new);
Mono_Time *mt = toxav_get_av_mono_time(session->toxav);
assert(mt != nullptr);
session->mcb(mt, session->cs, m_new);
m_new = nullptr;
}
@ -436,80 +425,113 @@ static int handle_video_packet(RTPSession *session, const struct RTPHeader *head
}
/**
* @retval -1 on error.
* @retval 0 on success.
* receive custom lossypackets and process them. they can be incoming audio or video packets
*/
static int handle_rtp_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object)
void handle_rtp_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data)
{
RTPSession *session = (RTPSession *)object;
ToxAV *toxav = (ToxAV *)tox_get_av_object(tox);
if (session == nullptr || length < RTP_HEADER_SIZE + 1) {
LOGGER_WARNING(m->log, "No session or invalid length of received buffer!");
return -1;
if (toxav == nullptr) {
// LOGGER_WARNING(log, "ToxAV is NULL!");
return;
}
const Logger *log = toxav_get_logger(toxav);
if (length < RTP_HEADER_SIZE + 1) {
LOGGER_WARNING(log, "Invalid length of received buffer!");
return;
}
ToxAVCall *call = call_get(toxav, friend_number);
if (call == nullptr) {
LOGGER_WARNING(log, "ToxAVCall is NULL!");
return;
}
RTPSession *session = rtp_session_get(call, data[0]);
if (session == nullptr) {
LOGGER_WARNING(log, "No session!");
return;
}
if (!session->rtp_receive_active) {
LOGGER_WARNING(log, "receiving not allowed!");
return;
}
// Get the packet type.
const uint8_t packet_type = data[0];
++data;
--length;
const uint8_t *payload = &data[1];
// TODO(Zoff): is this ok?
const uint16_t payload_size = (uint16_t)length - 1;
// Unpack the header.
struct RTPHeader header;
rtp_header_unpack(data, &header);
rtp_header_unpack(payload, &header);
if (header.pt != packet_type % 128) {
LOGGER_WARNING(m->log, "RTPHeader packet type and Tox protocol packet type did not agree: %d != %d",
LOGGER_WARNING(log, "RTPHeader packet type and Tox protocol packet type did not agree: %d != %d",
header.pt, packet_type % 128);
return -1;
return;
}
if (header.pt != session->payload_type % 128) {
LOGGER_WARNING(m->log, "RTPHeader packet type does not match this session's payload type: %d != %d",
LOGGER_WARNING(log, "RTPHeader packet type does not match this session's payload type: %d != %d",
header.pt, session->payload_type % 128);
return -1;
return;
}
if ((header.flags & RTP_LARGE_FRAME) != 0 && header.offset_full >= header.data_length_full) {
LOGGER_ERROR(m->log, "Invalid video packet: frame offset (%u) >= full frame length (%u)",
LOGGER_ERROR(log, "Invalid video packet: frame offset (%u) >= full frame length (%u)",
(unsigned)header.offset_full, (unsigned)header.data_length_full);
return -1;
return;
}
if (header.offset_lower >= header.data_length_lower) {
LOGGER_ERROR(m->log, "Invalid old protocol video packet: frame offset (%u) >= full frame length (%u)",
LOGGER_ERROR(log, "Invalid old protocol video packet: frame offset (%u) >= full frame length (%u)",
(unsigned)header.offset_lower, (unsigned)header.data_length_lower);
return -1;
return;
}
LOGGER_DEBUG(m->log, "header.pt %d, video %d", (uint8_t)header.pt, RTP_TYPE_VIDEO % 128);
LOGGER_DEBUG(log, "header.pt %d, video %d", (uint8_t)header.pt, RTP_TYPE_VIDEO % 128);
// The sender uses the new large-frame capable protocol and is sending a
// video packet.
if ((header.flags & RTP_LARGE_FRAME) != 0 && header.pt == (RTP_TYPE_VIDEO % 128)) {
return handle_video_packet(session, &header, data + RTP_HEADER_SIZE, length - RTP_HEADER_SIZE, m->log);
handle_video_packet(log, session, &header, &payload[RTP_HEADER_SIZE], payload_size - RTP_HEADER_SIZE);
return;
}
// everything below here is for the old 16 bit protocol ------------------
if (header.data_length_lower == length - RTP_HEADER_SIZE) {
if (header.data_length_lower == payload_size - RTP_HEADER_SIZE) {
/* The message is sent in single part */
/* Message is not late; pick up the latest parameters */
session->rsequnum = header.sequnum;
session->rtimestamp = header.timestamp;
bwc_add_recv(session->bwc, length);
bwc_add_recv(session->bwc, payload_size);
/* Invoke processing of active multiparted message */
if (session->mp != nullptr) {
session->mcb(session->m->mono_time, session->cs, session->mp);
Mono_Time *mt = toxav_get_av_mono_time(session->toxav);
assert(mt != nullptr);
session->mcb(mt, session->cs, session->mp);
session->mp = nullptr;
}
/* The message came in the allowed time;
*/
return session->mcb(session->m->mono_time, session->cs, new_message(&header, length - RTP_HEADER_SIZE,
data + RTP_HEADER_SIZE, length - RTP_HEADER_SIZE));
session->mp = new_message(log, &header, payload_size - RTP_HEADER_SIZE, &payload[RTP_HEADER_SIZE], payload_size - RTP_HEADER_SIZE);
Mono_Time *mt = toxav_get_av_mono_time(session->toxav);
assert(mt != nullptr);
session->mcb(mt, session->cs, session->mp);
session->mp = nullptr;
return;
}
/* The message is sent in multiple parts */
@ -527,24 +549,26 @@ static int handle_rtp_packet(Messenger *m, uint32_t friend_number, const uint8_t
/* First case */
/* Make sure we have enough allocated memory */
if (session->mp->header.data_length_lower - session->mp->len < length - RTP_HEADER_SIZE ||
if (session->mp->header.data_length_lower - session->mp->len < payload_size - RTP_HEADER_SIZE ||
session->mp->header.data_length_lower <= header.offset_lower) {
/* There happened to be some corruption on the stream;
* continue wihtout this part
*/
return 0;
return;
}
memcpy(session->mp->data + header.offset_lower, data + RTP_HEADER_SIZE,
length - RTP_HEADER_SIZE);
session->mp->len += length - RTP_HEADER_SIZE;
bwc_add_recv(session->bwc, length);
memcpy(session->mp->data + header.offset_lower, &payload[RTP_HEADER_SIZE],
payload_size - RTP_HEADER_SIZE);
session->mp->len += payload_size - RTP_HEADER_SIZE;
bwc_add_recv(session->bwc, payload_size);
if (session->mp->len == session->mp->header.data_length_lower) {
/* Received a full message; now push it for the further
* processing.
*/
session->mcb(session->m->mono_time, session->cs, session->mp);
Mono_Time *mt = toxav_get_av_mono_time(session->toxav);
assert(mt != nullptr);
session->mcb(mt, session->cs, session->mp);
session->mp = nullptr;
}
} else {
@ -553,17 +577,19 @@ static int handle_rtp_packet(Messenger *m, uint32_t friend_number, const uint8_t
/* The received message part is from the old message;
* discard it.
*/
return 0;
return;
}
/* Push the previous message for processing */
session->mcb(session->m->mono_time, session->cs, session->mp);
Mono_Time *mt = toxav_get_av_mono_time(session->toxav);
assert(mt != nullptr);
session->mcb(mt, session->cs, session->mp);
session->mp = nullptr;
goto NEW_MULTIPARTED;
}
} else {
/* In this case threat the message as if it was received in order
/* In this case treat the message as if it was received in order
*/
/* This is also a point for new multiparted messages */
NEW_MULTIPARTED:
@ -571,21 +597,21 @@ NEW_MULTIPARTED:
/* Message is not late; pick up the latest parameters */
session->rsequnum = header.sequnum;
session->rtimestamp = header.timestamp;
bwc_add_recv(session->bwc, length);
bwc_add_recv(session->bwc, payload_size);
/* Store message.
*/
session->mp = new_message(&header, header.data_length_lower, data + RTP_HEADER_SIZE, length - RTP_HEADER_SIZE);
session->mp = new_message(log, &header, header.data_length_lower, &payload[RTP_HEADER_SIZE], payload_size - RTP_HEADER_SIZE);
if (session->mp != nullptr) {
memmove(session->mp->data + header.offset_lower, session->mp->data, session->mp->len);
} else {
LOGGER_WARNING(m->log, "new_message() returned a null pointer");
return -1;
LOGGER_WARNING(log, "new_message() returned a null pointer");
return;
}
}
return 0;
return;
}
size_t rtp_header_pack(uint8_t *const rdata, const struct RTPHeader *header)
@ -647,24 +673,29 @@ size_t rtp_header_unpack(const uint8_t *data, struct RTPHeader *header)
return p - data;
}
RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnumber,
static uint32_t rtp_random_u32(void)
{
// HINT: uses libsodium function
return randombytes_random();
}
RTPSession *rtp_new(const Logger *log, int payload_type, Tox *tox, ToxAV *toxav, uint32_t friendnumber,
BWController *bwc, void *cs, rtp_m_cb *mcb)
{
assert(mcb != nullptr);
assert(cs != nullptr);
assert(m != nullptr);
RTPSession *session = (RTPSession *)calloc(1, sizeof(RTPSession));
if (session == nullptr) {
LOGGER_WARNING(m->log, "Alloc failed! Program might misbehave!");
LOGGER_WARNING(log, "Alloc failed! Program might misbehave!");
return nullptr;
}
session->work_buffer_list = (struct RTPWorkBufferList *)calloc(1, sizeof(struct RTPWorkBufferList));
if (session->work_buffer_list == nullptr) {
LOGGER_ERROR(m->log, "out of memory while allocating work buffer list");
LOGGER_ERROR(log, "out of memory while allocating work buffer list");
free(session);
return nullptr;
}
@ -672,11 +703,12 @@ RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnum
// First entry is free.
session->work_buffer_list->next_free_entry = 0;
session->ssrc = payload_type == RTP_TYPE_VIDEO ? 0 : random_u32(m->rng);
session->ssrc = payload_type == RTP_TYPE_VIDEO ? 0 : rtp_random_u32(); // Zoff: what is this??
session->payload_type = payload_type;
session->m = m;
session->tox = tox;
session->toxav = toxav;
session->friend_number = friendnumber;
session->rtp_receive_active = true;
// set NULL just in case
session->mp = nullptr;
@ -687,26 +719,18 @@ RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnum
session->cs = cs;
session->mcb = mcb;
if (-1 == rtp_allow_receiving(session)) {
LOGGER_WARNING(m->log, "Failed to start rtp receiving mode");
free(session->work_buffer_list);
free(session);
return nullptr;
}
return session;
}
void rtp_kill(RTPSession *session)
void rtp_kill(const Logger *log, RTPSession *session)
{
if (session == nullptr) {
LOGGER_WARNING(log, "No session");
return;
}
LOGGER_DEBUG(session->m->log, "Terminated RTP session: %p", (void *)session);
rtp_stop_receiving(session);
LOGGER_DEBUG(session->m->log, "Terminated RTP session V3 work_buffer_list->next_free_entry: %d",
LOGGER_DEBUG(log, "Terminated RTP session: %p", (void *)session);
LOGGER_DEBUG(log, "Terminated RTP session V3 work_buffer_list->next_free_entry: %d",
(int)session->work_buffer_list->next_free_entry);
for (int8_t i = 0; i < session->work_buffer_list->next_free_entry; ++i) {
@ -716,36 +740,95 @@ void rtp_kill(RTPSession *session)
free(session);
}
int rtp_allow_receiving(RTPSession *session)
void rtp_allow_receiving_mark(RTPSession *session)
{
if (session == nullptr) {
return -1;
if (session != nullptr) {
session->rtp_receive_active = true;
}
if (m_callback_rtp_packet(session->m, session->friend_number, session->payload_type,
handle_rtp_packet, session) == -1) {
LOGGER_WARNING(session->m->log, "Failed to register rtp receive handler");
return -1;
}
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) {
return -1;
if (session != nullptr) {
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);
return 0;
if (is_keyframe) {
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 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
* audio frame, this parameter is ignored.
*/
int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length,
bool is_keyframe, const Logger *log)
int rtp_send_data(const Logger *log, RTPSession *session, const uint8_t *data, uint32_t length,
bool is_keyframe)
{
if (session == nullptr) {
LOGGER_ERROR(log, "No session!");
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);
VLA(uint8_t, rdata, rdata_size);
memset(rdata, 0, rdata_size);
rdata[0] = session->payload_type; // packet id == payload_type
struct RTPHeader header = rtp_default_header(session, length, is_keyframe);
if (MAX_CRYPTO_DATA_SIZE > (length + RTP_HEADER_SIZE + 1)) {
/*
* The length is lesser than the maximum allowed length (including header)
* Send the packet in single piece.
*/
rtp_header_pack(rdata + 1, &header);
memcpy(rdata + 1 + RTP_HEADER_SIZE, data, length);
if (-1 == rtp_send_custom_lossy_packet(session->tox, session->friend_number, rdata, rdata_size)) {
char *netstrerror = net_new_strerror(net_error());
LOGGER_WARNING(session->m->log, "RTP send failed (len: %u)! net error: %s",
rdata_size, netstrerror);
net_kill_strerror(netstrerror);
}
assert(length < UINT16_MAX);
rtp_send_piece(log, session->tox, session->friend_number, &header, data, rdata, length);
} else {
/*
* The length is greater than the maximum allowed length (including header)
@ -833,16 +866,7 @@ int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length,
uint16_t piece = MAX_CRYPTO_DATA_SIZE - (RTP_HEADER_SIZE + 1);
while ((length - sent) + RTP_HEADER_SIZE + 1 > MAX_CRYPTO_DATA_SIZE) {
rtp_header_pack(rdata + 1, &header);
memcpy(rdata + 1 + RTP_HEADER_SIZE, data + sent, piece);
if (-1 == rtp_send_custom_lossy_packet(session->tox, session->friend_number,
rdata, piece + RTP_HEADER_SIZE + 1)) {
char *netstrerror = net_new_strerror(net_error());
LOGGER_WARNING(session->m->log, "RTP send failed (len: %d)! net error: %s",
piece + RTP_HEADER_SIZE + 1, netstrerror);
net_kill_strerror(netstrerror);
}
rtp_send_piece(log, session->tox, session->friend_number, &header, data + sent, rdata, piece);
sent += piece;
header.offset_lower = sent;
@ -853,16 +877,7 @@ int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length,
piece = length - sent;
if (piece != 0) {
rtp_header_pack(rdata + 1, &header);
memcpy(rdata + 1 + RTP_HEADER_SIZE, data + sent, piece);
if (-1 == rtp_send_custom_lossy_packet(session->tox, session->friend_number, rdata,
piece + RTP_HEADER_SIZE + 1)) {
char *netstrerror = net_new_strerror(net_error());
LOGGER_WARNING(session->m->log, "RTP send failed (len: %d)! net error: %s",
piece + RTP_HEADER_SIZE + 1, netstrerror);
net_kill_strerror(netstrerror);
}
rtp_send_piece(log, session->tox, session->friend_number, &header, data + sent, rdata, piece);
}
}

View File

@ -9,7 +9,6 @@
#include "bwcontroller.h"
#include "../toxcore/Messenger.h"
#include "../toxcore/logger.h"
#include "../toxcore/tox.h"
@ -36,6 +35,11 @@ typedef enum RTP_Type {
RTP_TYPE_VIDEO = 193,
} RTP_Type;
#ifndef TOXAV_DEFINED
#define TOXAV_DEFINED
typedef struct ToxAV ToxAV;
#endif /* TOXAV_DEFINED */
/**
* A bit mask (up to 64 bits) specifying features of the current frame affecting
* the behaviour of the decoder.
@ -157,14 +161,19 @@ typedef struct RTPSession {
struct RTPMessage *mp; /* Expected parted message */
struct RTPWorkBufferList *work_buffer_list;
uint8_t first_packets_counter; /* dismiss first few lost video packets */
Messenger *m;
const Logger *log;
Tox *tox;
ToxAV *toxav;
uint32_t friend_number;
bool rtp_receive_active; /* if this is set to false then incoming rtp packets will not be processed by handle_rtp_packet() */
BWController *bwc;
void *cs;
rtp_m_cb *mcb;
} RTPSession;
void handle_rtp_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data);
/**
* Serialise an RTPHeader to bytes to be sent over the network.
*
@ -183,13 +192,16 @@ size_t rtp_header_pack(uint8_t *rdata, const struct RTPHeader *header);
*/
size_t rtp_header_unpack(const uint8_t *data, struct RTPHeader *header);
RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnumber,
RTPSession *rtp_new(const Logger *log, int payload_type, Tox *tox, ToxAV *toxav, uint32_t friendnumber,
BWController *bwc, void *cs, rtp_m_cb *mcb);
void rtp_kill(RTPSession *session);
int rtp_allow_receiving(RTPSession *session);
int rtp_stop_receiving(RTPSession *session);
void rtp_kill(const Logger *log, RTPSession *session);
void rtp_allow_receiving_mark(RTPSession *session);
void rtp_stop_receiving_mark(RTPSession *session);
void rtp_allow_receiving(Tox *tox);
void rtp_stop_receiving(Tox *tox);
/**
* Send a frame of audio or video data, chunked in @ref RTPMessage instances.
* @brief Send a frame of audio or video data, chunked in @ref RTPMessage instances.
*
* @param session The A/V session to send the data for.
* @param data A byte array of length @p length.
@ -197,8 +209,8 @@ int rtp_stop_receiving(RTPSession *session);
* @param is_keyframe Whether this video frame is a key frame. If it is an
* audio frame, this parameter is ignored.
*/
int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length,
bool is_keyframe, const Logger *log);
int rtp_send_data(const Logger *log, RTPSession *session, const uint8_t *data, uint32_t length,
bool is_keyframe);
#ifdef __cplusplus
} /* extern "C" */

View File

@ -12,11 +12,15 @@
#include "msi.h"
#include "rtp.h"
#include "toxav_hacks.h"
#include "../toxcore/Messenger.h"
#include "../toxcore/ccompat.h"
#include "../toxcore/logger.h"
#include "../toxcore/mono_time.h"
#include "../toxcore/net_crypto.h"
#include "../toxcore/network.h"
#include "../toxcore/tox.h"
#include "../toxcore/tox_private.h"
#include "../toxcore/tox_struct.h"
#include "../toxcore/util.h"
@ -36,7 +40,12 @@
// iteration interval that is used when no call is active
#define IDLE_ITERATION_INTERVAL_MS 200
typedef struct ToxAVCall {
#ifndef TOXAV_CALL_DEFINED
#define TOXAV_CALL_DEFINED
typedef struct ToxAVCall ToxAVCall;
#endif /* TOXAV_CALL_DEFINED */
struct ToxAVCall {
ToxAV *av;
pthread_mutex_t mutex_audio[1];
@ -63,7 +72,7 @@ typedef struct ToxAVCall {
struct ToxAVCall *prev;
struct ToxAVCall *next;
} ToxAVCall;
};
/** Decode time statistics */
typedef struct DecodeTimeStats {
@ -79,8 +88,8 @@ typedef struct DecodeTimeStats {
} DecodeTimeStats;
struct ToxAV {
Logger *log;
Tox *tox;
Messenger *m;
MSISession *msi;
/* Two-way storage: first is array of calls and second is list of calls with head and tail */
@ -111,8 +120,8 @@ struct ToxAV {
/* keep track of decode times for audio and video */
DecodeTimeStats audio_stats;
DecodeTimeStats video_stats;
/** ToxAV's own mono_time instance */
Mono_Time *toxav_mono_time;
Mono_Time *toxav_mono_time; // ToxAV's own mono_time instance
};
static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *user_data);
@ -127,11 +136,55 @@ static bool audio_bit_rate_invalid(uint32_t bit_rate);
static bool video_bit_rate_invalid(uint32_t bit_rate);
static bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state);
static ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, Toxav_Err_Call *error);
static ToxAVCall *call_get(ToxAV *av, uint32_t friend_number);
static ToxAVCall *call_remove(ToxAVCall *call);
static bool call_prepare_transmission(ToxAVCall *call);
static void call_kill_transmission(ToxAVCall *call);
MSISession *tox_av_msi_get(const ToxAV *av)
{
if (av == nullptr) {
return nullptr;
}
return av->msi;
}
ToxAVCall *call_get(ToxAV *av, uint32_t friend_number)
{
if (av == nullptr) {
return nullptr;
}
/* Assumes mutex locked */
if (av->calls == nullptr || av->calls_tail < friend_number) {
return nullptr;
}
return av->calls[friend_number];
}
RTPSession *rtp_session_get(ToxAVCall *call, int payload_type)
{
if (call == nullptr) {
return nullptr;
}
if (payload_type == RTP_TYPE_VIDEO) {
return call->video_rtp;
} else {
return call->audio_rtp;
}
}
BWController *bwc_controller_get(const ToxAVCall *call)
{
if (call == nullptr) {
return nullptr;
}
return call->bwc;
}
/**
* @brief initialize d with default values
* @param d struct to be initialized, must not be nullptr
@ -155,33 +208,26 @@ ToxAV *toxav_new(Tox *tox, Toxav_Err_New *error)
goto RETURN;
}
// TODO(iphydf): Don't rely on toxcore internals.
Messenger *m;
m = tox->m;
if (m->msi_packet != nullptr) {
rc = TOXAV_ERR_NEW_MULTIPLE;
goto RETURN;
}
av = (ToxAV *)calloc(1, sizeof(ToxAV));
if (av == nullptr) {
LOGGER_WARNING(m->log, "Allocation failed!");
rc = TOXAV_ERR_NEW_MALLOC;
goto RETURN;
}
if (create_recursive_mutex(av->mutex) != 0) {
LOGGER_WARNING(m->log, "Mutex creation failed!");
rc = TOXAV_ERR_NEW_MALLOC;
goto RETURN;
}
av->log = tox->m->log;
av->tox = tox;
av->m = m;
av->msi = msi_new(av->log, av->tox);
rtp_allow_receiving(av->tox);
bwc_allow_receiving(av->tox);
av->toxav_mono_time = mono_time_new(tox->sys.mem, nullptr, nullptr);
av->msi = msi_new(av->m);
if (av->msi == nullptr) {
pthread_mutex_destroy(av->mutex);
@ -193,6 +239,9 @@ ToxAV *toxav_new(Tox *tox, Toxav_Err_New *error)
init_decode_time_stats(&av->video_stats);
av->msi->av = av;
// save ToxAV object into toxcore
tox_set_av_object(av->tox, av);
msi_callback_invite(av->msi, callback_invite);
msi_callback_start(av->msi, callback_start);
msi_callback_end(av->msi, callback_end);
@ -207,12 +256,15 @@ RETURN:
}
if (rc != TOXAV_ERR_NEW_OK) {
free(av);
av = nullptr;
if (av != nullptr) {
free(av);
av = nullptr;
}
}
return av;
}
void toxav_kill(ToxAV *av)
{
if (av == nullptr) {
@ -221,8 +273,16 @@ void toxav_kill(ToxAV *av)
pthread_mutex_lock(av->mutex);
// unregister callbacks
for (uint8_t i = PACKET_ID_RANGE_LOSSY_AV_START; i <= PACKET_ID_RANGE_LOSSY_AV_END; ++i) {
tox_callback_friend_lossy_packet_per_pktid(av->tox, nullptr, i);
}
rtp_stop_receiving(av->tox);
bwc_stop_receiving(av->tox);
/* To avoid possible deadlocks */
while (av->msi != nullptr && msi_kill(av->msi, av->m->log) != 0) {
while (av->msi != nullptr && msi_kill(av->log, av->tox, av->msi) != 0) {
pthread_mutex_unlock(av->mutex);
pthread_mutex_lock(av->mutex);
}
@ -243,13 +303,22 @@ void toxav_kill(ToxAV *av)
pthread_mutex_unlock(av->mutex);
pthread_mutex_destroy(av->mutex);
// set ToxAV object to NULL in toxcore, to signal ToxAV has been shutdown
tox_set_av_object(av->tox, nullptr);
free(av);
}
Tox *toxav_get_tox(const ToxAV *av)
{
return av->tox;
}
const Logger *toxav_get_logger(const ToxAV *av)
{
return av->log;
}
uint32_t toxav_audio_iteration_interval(const ToxAV *av)
{
return av->calls != nullptr ? av->audio_stats.interval : IDLE_ITERATION_INTERVAL_MS;
@ -276,10 +345,11 @@ uint32_t toxav_iteration_interval(const ToxAV *av)
static void calc_interval(ToxAV *av, DecodeTimeStats *stats, int32_t frame_time, uint64_t start_time)
{
stats->interval = frame_time < stats->average ? 0 : (frame_time - stats->average);
stats->total += current_time_monotonic(av->m->mono_time) - start_time;
stats->total += current_time_monotonic(av->toxav_mono_time) - start_time;
if (++stats->count == 3) {
stats->average = stats->total / 3 + 5; /* NOTE: Magic Offset for precision */
/* NOTE: Magic Offset for precision */
stats->average = stats->total / 3 + 5;
stats->count = 0;
stats->total = 0;
}
@ -300,7 +370,6 @@ static void iterate_common(ToxAV *av, bool audio)
}
const uint64_t start = current_time_monotonic(av->toxav_mono_time);
// time until the first audio or video frame is over
int32_t frame_time = IDLE_ITERATION_INTERVAL_MS;
for (ToxAVCall *i = av->calls[av->calls_head]; i != nullptr; i = i->next) {
@ -311,6 +380,15 @@ static void iterate_common(ToxAV *av, bool audio)
pthread_mutex_lock(i->toxav_call_mutex);
pthread_mutex_unlock(av->mutex);
const uint32_t fid = i->friend_number;
const bool is_offline = check_peer_offline_status(av->log, av->tox, i->msi_call->session, fid);
if (is_offline) {
pthread_mutex_unlock(i->toxav_call_mutex);
pthread_mutex_lock(av->mutex);
break;
}
if (audio) {
ac_iterate(i->audio);
@ -329,8 +407,6 @@ static void iterate_common(ToxAV *av, bool audio)
}
}
const uint32_t fid = i->friend_number;
pthread_mutex_unlock(i->toxav_call_mutex);
pthread_mutex_lock(av->mutex);
@ -342,8 +418,10 @@ static void iterate_common(ToxAV *av, bool audio)
DecodeTimeStats *stats = audio ? &av->audio_stats : &av->video_stats;
calc_interval(av, stats, frame_time, start);
pthread_mutex_unlock(av->mutex);
}
void toxav_audio_iterate(ToxAV *av)
{
iterate_common(av, true);
@ -388,7 +466,7 @@ bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint
call->previous_self_capabilities |= audio_bit_rate > 0 ? MSI_CAP_S_AUDIO : 0;
call->previous_self_capabilities |= video_bit_rate > 0 ? MSI_CAP_S_VIDEO : 0;
if (msi_invite(av->msi, &call->msi_call, friend_number, call->previous_self_capabilities) != 0) {
if (msi_invite(av->log, av->msi, &call->msi_call, friend_number, call->previous_self_capabilities) != 0) {
call_remove(call);
rc = TOXAV_ERR_CALL_SYNC;
goto RETURN;
@ -405,6 +483,7 @@ RETURN:
return rc == TOXAV_ERR_CALL_OK;
}
void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data)
{
pthread_mutex_lock(av->mutex);
@ -412,6 +491,7 @@ void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data)
av->ccb_user_data = user_data;
pthread_mutex_unlock(av->mutex);
}
bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate,
Toxav_Err_Answer *error)
{
@ -420,7 +500,7 @@ bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, ui
Toxav_Err_Answer rc = TOXAV_ERR_ANSWER_OK;
ToxAVCall *call;
if (!m_friend_exists(av->m, friend_number)) {
if (!tox_friend_exists(av->tox, friend_number)) {
rc = TOXAV_ERR_ANSWER_FRIEND_NOT_FOUND;
goto RETURN;
}
@ -452,7 +532,7 @@ bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, ui
call->previous_self_capabilities |= audio_bit_rate > 0 ? MSI_CAP_S_AUDIO : 0;
call->previous_self_capabilities |= video_bit_rate > 0 ? MSI_CAP_S_VIDEO : 0;
if (msi_answer(call->msi_call, call->previous_self_capabilities) != 0) {
if (msi_answer(av->log, call->msi_call, call->previous_self_capabilities) != 0) {
rc = TOXAV_ERR_ANSWER_SYNC;
}
@ -465,6 +545,7 @@ RETURN:
return rc == TOXAV_ERR_ANSWER_OK;
}
void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *user_data)
{
pthread_mutex_lock(av->mutex);
@ -472,6 +553,7 @@ void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *u
av->scb_user_data = user_data;
pthread_mutex_unlock(av->mutex);
}
static Toxav_Err_Call_Control call_control_handle_resume(const ToxAVCall *call)
{
/* Only act if paused and had media transfer active before */
@ -479,12 +561,13 @@ static Toxav_Err_Call_Control call_control_handle_resume(const ToxAVCall *call)
return TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION;
}
if (msi_change_capabilities(call->msi_call, call->previous_self_capabilities) == -1) {
if (msi_change_capabilities(call->av->log, call->msi_call,
call->previous_self_capabilities) == -1) {
return TOXAV_ERR_CALL_CONTROL_SYNC;
}
rtp_allow_receiving(call->audio_rtp);
rtp_allow_receiving(call->video_rtp);
rtp_allow_receiving_mark(call->audio_rtp);
rtp_allow_receiving_mark(call->video_rtp);
return TOXAV_ERR_CALL_CONTROL_OK;
}
@ -497,12 +580,12 @@ static Toxav_Err_Call_Control call_control_handle_pause(ToxAVCall *call)
call->previous_self_capabilities = call->msi_call->self_capabilities;
if (msi_change_capabilities(call->msi_call, 0) == -1) {
if (msi_change_capabilities(call->av->log, call->msi_call, 0) == -1) {
return TOXAV_ERR_CALL_CONTROL_SYNC;
}
rtp_stop_receiving(call->audio_rtp);
rtp_stop_receiving(call->video_rtp);
rtp_stop_receiving_mark(call->audio_rtp);
rtp_stop_receiving_mark(call->video_rtp);
return TOXAV_ERR_CALL_CONTROL_OK;
}
@ -511,7 +594,7 @@ static Toxav_Err_Call_Control call_control_handle_cancel(ToxAVCall *call)
/* Hang up */
pthread_mutex_lock(call->toxav_call_mutex);
if (msi_hangup(call->msi_call) != 0) {
if (msi_hangup(call->av->log, call->msi_call) != 0) {
pthread_mutex_unlock(call->toxav_call_mutex);
return TOXAV_ERR_CALL_CONTROL_SYNC;
}
@ -531,13 +614,13 @@ static Toxav_Err_Call_Control call_control_handle_mute_audio(const ToxAVCall *ca
return TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION;
}
if (msi_change_capabilities(call->msi_call, call->
if (msi_change_capabilities(call->av->log, call->msi_call, call->
msi_call->self_capabilities ^ MSI_CAP_R_AUDIO) == -1) {
return TOXAV_ERR_CALL_CONTROL_SYNC;
}
rtp_stop_receiving(call->audio_rtp);
rtp_stop_receiving_mark(call->audio_rtp);
return TOXAV_ERR_CALL_CONTROL_OK;
}
static Toxav_Err_Call_Control call_control_handle_unmute_audio(const ToxAVCall *call)
@ -546,12 +629,12 @@ static Toxav_Err_Call_Control call_control_handle_unmute_audio(const ToxAVCall *
return TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION;
}
if (msi_change_capabilities(call->msi_call, call->
if (msi_change_capabilities(call->av->log, call->msi_call, call->
msi_call->self_capabilities | MSI_CAP_R_AUDIO) == -1) {
return TOXAV_ERR_CALL_CONTROL_SYNC;
}
rtp_allow_receiving(call->audio_rtp);
rtp_allow_receiving_mark(call->audio_rtp);
return TOXAV_ERR_CALL_CONTROL_OK;
}
static Toxav_Err_Call_Control call_control_handle_hide_video(const ToxAVCall *call)
@ -560,12 +643,12 @@ static Toxav_Err_Call_Control call_control_handle_hide_video(const ToxAVCall *ca
return TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION;
}
if (msi_change_capabilities(call->msi_call, call->
if (msi_change_capabilities(call->av->log, call->msi_call, call->
msi_call->self_capabilities ^ MSI_CAP_R_VIDEO) == -1) {
return TOXAV_ERR_CALL_CONTROL_SYNC;
}
rtp_stop_receiving(call->video_rtp);
rtp_stop_receiving_mark(call->video_rtp);
return TOXAV_ERR_CALL_CONTROL_OK;
}
static Toxav_Err_Call_Control call_control_handle_show_video(const ToxAVCall *call)
@ -574,12 +657,12 @@ static Toxav_Err_Call_Control call_control_handle_show_video(const ToxAVCall *ca
return TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION;
}
if (msi_change_capabilities(call->msi_call, call->
if (msi_change_capabilities(call->av->log, call->msi_call, call->
msi_call->self_capabilities | MSI_CAP_R_VIDEO) == -1) {
return TOXAV_ERR_CALL_CONTROL_SYNC;
}
rtp_allow_receiving(call->video_rtp);
rtp_allow_receiving_mark(call->video_rtp);
return TOXAV_ERR_CALL_CONTROL_OK;
}
static Toxav_Err_Call_Control call_control_handle(ToxAVCall *call, Toxav_Call_Control control)
@ -611,7 +694,7 @@ static Toxav_Err_Call_Control call_control_handle(ToxAVCall *call, Toxav_Call_Co
}
static Toxav_Err_Call_Control call_control(ToxAV *av, uint32_t friend_number, Toxav_Call_Control control)
{
if (!m_friend_exists(av->m, friend_number)) {
if (!tox_friend_exists(av->tox, friend_number)) {
return TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_FOUND;
}
@ -637,13 +720,14 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, Toxav_Call_Control co
return rc == TOXAV_ERR_CALL_CONTROL_OK;
}
bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_rate,
Toxav_Err_Bit_Rate_Set *error)
{
Toxav_Err_Bit_Rate_Set rc = TOXAV_ERR_BIT_RATE_SET_OK;
ToxAVCall *call;
if (!m_friend_exists(av->m, friend_number)) {
if (!tox_friend_exists(av->tox, friend_number)) {
rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND;
goto RETURN;
}
@ -662,14 +746,14 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
goto RETURN;
}
LOGGER_DEBUG(av->m->log, "Setting new audio bitrate to: %d", bit_rate);
LOGGER_DEBUG(av->log, "Setting new audio bitrate to: %d", bit_rate);
if (call->audio_bit_rate == bit_rate) {
LOGGER_DEBUG(av->m->log, "Audio bitrate already set to: %d", bit_rate);
LOGGER_DEBUG(av->log, "Audio bitrate already set to: %d", bit_rate);
} else if (bit_rate == 0) {
LOGGER_DEBUG(av->m->log, "Turned off audio sending");
LOGGER_DEBUG(av->log, "Turned off audio sending");
if (msi_change_capabilities(call->msi_call, call->msi_call->
if (msi_change_capabilities(av->log, call->msi_call, call->msi_call->
self_capabilities ^ MSI_CAP_S_AUDIO) != 0) {
pthread_mutex_unlock(av->mutex);
rc = TOXAV_ERR_BIT_RATE_SET_SYNC;
@ -682,10 +766,10 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
pthread_mutex_lock(call->toxav_call_mutex);
if (call->audio_bit_rate == 0) {
LOGGER_DEBUG(av->m->log, "Turned on audio sending");
LOGGER_DEBUG(av->log, "Turned on audio sending");
/* The audio has been turned off before this */
if (msi_change_capabilities(call->msi_call, call->
if (msi_change_capabilities(av->log, call->msi_call, call->
msi_call->self_capabilities | MSI_CAP_S_AUDIO) != 0) {
pthread_mutex_unlock(call->toxav_call_mutex);
pthread_mutex_unlock(av->mutex);
@ -693,7 +777,7 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
goto RETURN;
}
} else {
LOGGER_DEBUG(av->m->log, "Set new audio bit rate %d", bit_rate);
LOGGER_DEBUG(av->log, "Set new audio bit rate %d", bit_rate);
}
call->audio_bit_rate = bit_rate;
@ -709,13 +793,14 @@ RETURN:
return rc == TOXAV_ERR_BIT_RATE_SET_OK;
}
bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_rate,
Toxav_Err_Bit_Rate_Set *error)
{
Toxav_Err_Bit_Rate_Set rc = TOXAV_ERR_BIT_RATE_SET_OK;
ToxAVCall *call;
if (!m_friend_exists(av->m, friend_number)) {
if (!tox_friend_exists(av->tox, friend_number)) {
rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND;
goto RETURN;
}
@ -734,15 +819,15 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
goto RETURN;
}
LOGGER_DEBUG(av->m->log, "Setting new video bitrate to: %d", bit_rate);
LOGGER_DEBUG(av->log, "Setting new video bitrate to: %d", bit_rate);
if (call->video_bit_rate == bit_rate) {
LOGGER_DEBUG(av->m->log, "Video bitrate already set to: %d", bit_rate);
LOGGER_DEBUG(av->log, "Video bitrate already set to: %d", bit_rate);
} else if (bit_rate == 0) {
LOGGER_DEBUG(av->m->log, "Turned off video sending");
LOGGER_DEBUG(av->log, "Turned off video sending");
/* Video sending is turned off; notify peer */
if (msi_change_capabilities(call->msi_call, call->msi_call->
if (msi_change_capabilities(av->log, call->msi_call, call->msi_call->
self_capabilities ^ MSI_CAP_S_VIDEO) != 0) {
pthread_mutex_unlock(av->mutex);
rc = TOXAV_ERR_BIT_RATE_SET_SYNC;
@ -754,10 +839,10 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
pthread_mutex_lock(call->toxav_call_mutex);
if (call->video_bit_rate == 0) {
LOGGER_DEBUG(av->m->log, "Turned on video sending");
LOGGER_DEBUG(av->log, "Turned on video sending");
/* The video has been turned off before this */
if (msi_change_capabilities(call->msi_call, call->
if (msi_change_capabilities(av->log, call->msi_call, call->
msi_call->self_capabilities | MSI_CAP_S_VIDEO) != 0) {
pthread_mutex_unlock(call->toxav_call_mutex);
pthread_mutex_unlock(av->mutex);
@ -765,7 +850,7 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
goto RETURN;
}
} else {
LOGGER_DEBUG(av->m->log, "Set new video bit rate %d", bit_rate);
LOGGER_DEBUG(av->log, "Set new video bit rate %d", bit_rate);
}
call->video_bit_rate = bit_rate;
@ -781,6 +866,7 @@ RETURN:
return rc == TOXAV_ERR_BIT_RATE_SET_OK;
}
void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback, void *user_data)
{
pthread_mutex_lock(av->mutex);
@ -788,6 +874,7 @@ void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback,
av->abcb_user_data = user_data;
pthread_mutex_unlock(av->mutex);
}
void toxav_callback_video_bit_rate(ToxAV *av, toxav_video_bit_rate_cb *callback, void *user_data)
{
pthread_mutex_lock(av->mutex);
@ -795,13 +882,14 @@ void toxav_callback_video_bit_rate(ToxAV *av, toxav_video_bit_rate_cb *callback,
av->vbcb_user_data = user_data;
pthread_mutex_unlock(av->mutex);
}
bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pcm, size_t sample_count,
uint8_t channels, uint32_t sampling_rate, Toxav_Err_Send_Frame *error)
{
Toxav_Err_Send_Frame rc = TOXAV_ERR_SEND_FRAME_OK;
ToxAVCall *call;
if (!m_friend_exists(av->m, friend_number)) {
if (!tox_friend_exists(av->tox, friend_number)) {
rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND;
goto RETURN;
}
@ -859,14 +947,14 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc
dest + sizeof(sampling_rate), dest_size - sizeof(sampling_rate));
if (vrc < 0) {
LOGGER_WARNING(av->m->log, "Failed to encode frame %s", opus_strerror(vrc));
LOGGER_WARNING(av->log, "Failed to encode frame %s", opus_strerror(vrc));
pthread_mutex_unlock(call->mutex_audio);
rc = TOXAV_ERR_SEND_FRAME_INVALID;
goto RETURN;
}
if (rtp_send_data(call->audio_rtp, dest, vrc + sizeof(sampling_rate), false, av->m->log) != 0) {
LOGGER_WARNING(av->m->log, "Failed to send audio packet");
if (rtp_send_data(av->log, call->audio_rtp, dest, vrc + sizeof(sampling_rate), false) != 0) {
LOGGER_WARNING(av->log, "Failed to send audio packet");
rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED;
}
}
@ -882,7 +970,7 @@ RETURN:
return rc == TOXAV_ERR_SEND_FRAME_OK;
}
static Toxav_Err_Send_Frame send_frames(const Logger *log, ToxAVCall *call)
static Toxav_Err_Send_Frame send_frames(const ToxAV *av, ToxAVCall *call)
{
vpx_codec_iter_t iter = nullptr;
@ -900,20 +988,15 @@ static Toxav_Err_Send_Frame send_frames(const Logger *log, ToxAVCall *call)
const uint32_t frame_length_in_bytes = pkt->data.frame.sz;
const int res = rtp_send_data(
av->log,
call->video_rtp,
(const uint8_t *)pkt->data.frame.buf,
frame_length_in_bytes,
is_keyframe,
log);
LOGGER_DEBUG(log, "+ _sending_FRAME_TYPE_==%s bytes=%d frame_len=%d", is_keyframe ? "K" : ".",
(int)pkt->data.frame.sz, (int)frame_length_in_bytes);
const uint8_t *const buf = (const uint8_t *)pkt->data.frame.buf;
LOGGER_DEBUG(log, "+ _sending_FRAME_ b0=%d b1=%d", buf[0], buf[1]);
is_keyframe);
if (res < 0) {
char *netstrerror = net_new_strerror(net_error());
LOGGER_WARNING(log, "Could not send video frame: %s", netstrerror);
LOGGER_WARNING(av->log, "Could not send video frame: %s", netstrerror);
net_kill_strerror(netstrerror);
return TOXAV_ERR_SEND_FRAME_RTP_FAILED;
}
@ -930,7 +1013,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u
int vpx_encode_flags = 0;
if (!m_friend_exists(av->m, friend_number)) {
if (!tox_friend_exists(av->tox, friend_number)) {
rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND;
goto RETURN;
}
@ -965,7 +1048,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u
goto RETURN;
}
if (vc_reconfigure_encoder(call->video, call->video_bit_rate * 1000, width, height, -1) != 0) {
if (vc_reconfigure_encoder(call->video, call->video_bit_rate, width, height, -1) != 0) {
pthread_mutex_unlock(call->mutex_video);
rc = TOXAV_ERR_SEND_FRAME_INVALID;
goto RETURN;
@ -974,13 +1057,13 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u
if (call->video_rtp->ssrc < VIDEO_SEND_X_KEYFRAMES_FIRST) {
// Key frame flag for first frames
vpx_encode_flags = VPX_EFLAG_FORCE_KF;
LOGGER_DEBUG(av->m->log, "I_FRAME_FLAG:%d only-i-frame mode", call->video_rtp->ssrc);
LOGGER_DEBUG(av->log, "I_FRAME_FLAG:%d only-i-frame mode", call->video_rtp->ssrc);
++call->video_rtp->ssrc;
} else if (call->video_rtp->ssrc == VIDEO_SEND_X_KEYFRAMES_FIRST) {
// normal keyframe placement
vpx_encode_flags = 0;
LOGGER_DEBUG(av->m->log, "I_FRAME_FLAG:%d normal mode", call->video_rtp->ssrc);
LOGGER_DEBUG(av->log, "I_FRAME_FLAG:%d normal mode", call->video_rtp->ssrc);
++call->video_rtp->ssrc;
}
@ -1009,7 +1092,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u
if (vrc != VPX_CODEC_OK) {
pthread_mutex_unlock(call->mutex_video);
LOGGER_ERROR(av->m->log, "Could not encode video frame: %s", vpx_codec_err_to_string(vrc));
LOGGER_ERROR(av->log, "Could not encode video frame: %s", vpx_codec_err_to_string(vrc));
rc = TOXAV_ERR_SEND_FRAME_INVALID;
goto RETURN;
}
@ -1017,7 +1100,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u
++call->video->frame_counter;
rc = send_frames(av->m->log, call);
rc = send_frames(av, call);
pthread_mutex_unlock(call->mutex_video);
@ -1063,7 +1146,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss,
ToxAVCall *call = (ToxAVCall *)user_data;
assert(call != nullptr);
LOGGER_DEBUG(call->av->m->log, "Reported loss of %f%%", (double)loss * 100);
LOGGER_DEBUG(call->av->log, "Reported loss of %f%%", (double)loss * 100);
/* if less than 10% data loss we do nothing! */
if (loss < 0.1F) {
@ -1075,7 +1158,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss,
if (call->video_bit_rate != 0) {
if (call->av->vbcb == nullptr) {
pthread_mutex_unlock(call->av->mutex);
LOGGER_WARNING(call->av->m->log, "No callback to report loss on");
LOGGER_WARNING(call->av->log, "No callback to report loss on");
return;
}
@ -1085,7 +1168,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss,
} else if (call->audio_bit_rate != 0) {
if (call->av->abcb == nullptr) {
pthread_mutex_unlock(call->av->mutex);
LOGGER_WARNING(call->av->m->log, "No callback to report loss on");
LOGGER_WARNING(call->av->log, "No callback to report loss on");
return;
}
@ -1096,6 +1179,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss,
pthread_mutex_unlock(call->av->mutex);
}
static int callback_invite(void *object, MSICall *call)
{
ToxAV *toxav = (ToxAV *)object;
@ -1104,7 +1188,7 @@ static int callback_invite(void *object, MSICall *call)
ToxAVCall *av_call = call_new(toxav, call->friend_number, nullptr);
if (av_call == nullptr) {
LOGGER_WARNING(toxav->m->log, "Failed to initialize call...");
LOGGER_WARNING(toxav->log, "Failed to initialize call...");
pthread_mutex_unlock(toxav->mutex);
return -1;
}
@ -1124,6 +1208,7 @@ static int callback_invite(void *object, MSICall *call)
pthread_mutex_unlock(toxav->mutex);
return 0;
}
static int callback_start(void *object, MSICall *call)
{
ToxAV *toxav = (ToxAV *)object;
@ -1152,6 +1237,7 @@ static int callback_start(void *object, MSICall *call)
pthread_mutex_unlock(toxav->mutex);
return 0;
}
static int callback_end(void *object, MSICall *call)
{
ToxAV *toxav = (ToxAV *)object;
@ -1167,6 +1253,7 @@ static int callback_end(void *object, MSICall *call)
pthread_mutex_unlock(toxav->mutex);
return 0;
}
static int callback_error(void *object, MSICall *call)
{
ToxAV *toxav = (ToxAV *)object;
@ -1182,21 +1269,22 @@ static int callback_error(void *object, MSICall *call)
pthread_mutex_unlock(toxav->mutex);
return 0;
}
static int callback_capabilites(void *object, MSICall *call)
{
ToxAV *toxav = (ToxAV *)object;
pthread_mutex_lock(toxav->mutex);
if ((call->peer_capabilities & MSI_CAP_S_AUDIO) != 0) {
rtp_allow_receiving(call->av_call->audio_rtp);
rtp_allow_receiving_mark(call->av_call->audio_rtp);
} else {
rtp_stop_receiving(call->av_call->audio_rtp);
rtp_stop_receiving_mark(call->av_call->audio_rtp);
}
if ((call->peer_capabilities & MSI_CAP_S_VIDEO) != 0) {
rtp_allow_receiving(call->av_call->video_rtp);
rtp_allow_receiving_mark(call->av_call->video_rtp);
} else {
rtp_stop_receiving(call->av_call->video_rtp);
rtp_stop_receiving_mark(call->av_call->video_rtp);
}
invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities);
@ -1204,6 +1292,7 @@ static int callback_capabilites(void *object, MSICall *call)
pthread_mutex_unlock(toxav->mutex);
return 0;
}
static bool audio_bit_rate_invalid(uint32_t bit_rate)
{
/* Opus RFC 6716 section-2.1.1 dictates the following:
@ -1211,6 +1300,7 @@ static bool audio_bit_rate_invalid(uint32_t bit_rate)
*/
return bit_rate < 6 || bit_rate > 510;
}
static bool video_bit_rate_invalid(uint32_t bit_rate)
{
/* https://www.webmproject.org/docs/webm-sdk/structvpx__codec__enc__cfg.html shows the following:
@ -1222,6 +1312,7 @@ static bool video_bit_rate_invalid(uint32_t bit_rate)
*/
return bit_rate > UINT32_MAX;
}
static bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state)
{
if (av->scb != nullptr) {
@ -1239,12 +1330,17 @@ static ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, Toxav_Err_Call *er
Toxav_Err_Call rc = TOXAV_ERR_CALL_OK;
ToxAVCall *call = nullptr;
if (!m_friend_exists(av->m, friend_number)) {
Tox_Err_Friend_Query f_con_query_error;
Tox_Connection f_con_status = TOX_CONNECTION_NONE;
if (!tox_friend_exists(av->tox, friend_number)) {
rc = TOXAV_ERR_CALL_FRIEND_NOT_FOUND;
goto RETURN;
}
if (m_get_friend_connectionstatus(av->m, friend_number) < 1) {
f_con_status = tox_friend_get_connection_status(av->tox, friend_number, &f_con_query_error);
if (f_con_status == TOX_CONNECTION_NONE) {
rc = TOXAV_ERR_CALL_FRIEND_NOT_CONNECTED;
goto RETURN;
}
@ -1323,16 +1419,6 @@ RETURN:
return call;
}
static ToxAVCall *call_get(ToxAV *av, uint32_t friend_number)
{
/* Assumes mutex locked */
if (av->calls == nullptr || av->calls_tail < friend_number) {
return nullptr;
}
return av->calls[friend_number];
}
static ToxAVCall *call_remove(ToxAVCall *call)
{
if (call == nullptr) {
@ -1399,7 +1485,7 @@ static bool call_prepare_transmission(ToxAVCall *call)
}
if (call->active) {
LOGGER_WARNING(av->m->log, "Call already active!");
LOGGER_WARNING(av->log, "Call already active!");
return true;
}
@ -1412,43 +1498,37 @@ static bool call_prepare_transmission(ToxAVCall *call)
}
/* Prepare bwc */
call->bwc = bwc_new(av->m, av->tox, call->friend_number, callback_bwc, call, av->toxav_mono_time);
call->bwc = bwc_new(av->log, av->tox, call->friend_number, callback_bwc, call, av->toxav_mono_time);
if (call->bwc == nullptr) {
LOGGER_ERROR(av->m->log, "Failed to create new bwc");
goto FAILURE;
}
{ /* Prepare audio */
call->audio = ac_new(av->toxav_mono_time, av->m->log, av, call->friend_number, av->acb, av->acb_user_data);
{ /* Prepare audio */
call->audio = ac_new(av->toxav_mono_time, av->log, av, call->friend_number, av->acb, av->acb_user_data);
if (call->audio == nullptr) {
LOGGER_ERROR(av->m->log, "Failed to create audio codec session");
LOGGER_ERROR(av->log, "Failed to create audio codec session");
goto FAILURE;
}
call->audio_rtp = rtp_new(RTP_TYPE_AUDIO, av->m, av->tox, call->friend_number, call->bwc,
call->audio_rtp = rtp_new(av->log, RTP_TYPE_AUDIO, av->tox, av, call->friend_number, call->bwc,
call->audio, ac_queue_message);
if (call->audio_rtp == nullptr) {
LOGGER_ERROR(av->m->log, "Failed to create audio rtp session");
LOGGER_ERROR(av->log, "Failed to create audio rtp session");
goto FAILURE;
}
}
{ /* Prepare video */
call->video = vc_new(av->toxav_mono_time, av->m->log, av, call->friend_number, av->vcb, av->vcb_user_data);
{ /* Prepare video */
call->video = vc_new(av->log, av->toxav_mono_time, av, call->friend_number, av->vcb, av->vcb_user_data);
if (call->video == nullptr) {
LOGGER_ERROR(av->m->log, "Failed to create video codec session");
LOGGER_ERROR(av->log, "Failed to create video codec session");
goto FAILURE;
}
call->video_rtp = rtp_new(RTP_TYPE_VIDEO, av->m, av->tox, call->friend_number, call->bwc,
call->video_rtp = rtp_new(av->log, RTP_TYPE_VIDEO, av->tox, av, call->friend_number, call->bwc,
call->video, vc_queue_message);
if (call->video_rtp == nullptr) {
LOGGER_ERROR(av->m->log, "Failed to create video rtp session");
LOGGER_ERROR(av->log, "Failed to create video rtp session");
goto FAILURE;
}
}
@ -1458,11 +1538,11 @@ static bool call_prepare_transmission(ToxAVCall *call)
FAILURE:
bwc_kill(call->bwc);
rtp_kill(call->audio_rtp);
rtp_kill(av->log, call->audio_rtp);
ac_kill(call->audio);
call->audio_rtp = nullptr;
call->audio = nullptr;
rtp_kill(call->video_rtp);
rtp_kill(av->log, call->video_rtp);
vc_kill(call->video);
call->video_rtp = nullptr;
call->video = nullptr;
@ -1489,12 +1569,14 @@ static void call_kill_transmission(ToxAVCall *call)
bwc_kill(call->bwc);
rtp_kill(call->audio_rtp);
const ToxAV *av = call->av;
rtp_kill(av->log, call->audio_rtp);
ac_kill(call->audio);
call->audio_rtp = nullptr;
call->audio = nullptr;
rtp_kill(call->video_rtp);
rtp_kill(av->log, call->video_rtp);
vc_kill(call->video);
call->video_rtp = nullptr;
call->video = nullptr;
@ -1502,3 +1584,12 @@ static void call_kill_transmission(ToxAVCall *call)
pthread_mutex_destroy(call->mutex_audio);
pthread_mutex_destroy(call->mutex_video);
}
Mono_Time *toxav_get_av_mono_time(const ToxAV *av)
{
if (av == nullptr) {
return nullptr;
}
return av->toxav_mono_time;
}

View File

@ -73,6 +73,8 @@ typedef struct Tox Tox;
#endif /* !TOX_DEFINED */
#endif /* !APIGEN_IGNORE */
#ifndef TOXAV_DEFINED
#define TOXAV_DEFINED
/**
* @brief The ToxAV instance type.
*
@ -83,6 +85,7 @@ typedef struct Tox Tox;
* notifying peers.
*/
typedef struct ToxAV ToxAV;
#endif /* TOXAV_DEFINED */
/** @{
* @brief Creation and destruction
@ -246,9 +249,9 @@ typedef enum Toxav_Err_Call {
* receiving are both enabled by default.
*
* @param friend_number The friend number of the friend that should be called.
* @param audio_bit_rate Audio bit rate in Kb/sec. Set this to 0 to disable
* @param audio_bit_rate Audio bit rate in kbit/sec. Set this to 0 to disable
* audio sending.
* @param video_bit_rate Video bit rate in Kb/sec. Set this to 0 to disable
* @param video_bit_rate Video bit rate in kbit/sec. Set this to 0 to disable
* video sending.
*/
bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate,
@ -315,9 +318,9 @@ typedef enum Toxav_Err_Answer {
* enabled by default.
*
* @param friend_number The friend number of the friend that is calling.
* @param audio_bit_rate Audio bit rate in Kb/sec. Set this to 0 to disable
* @param audio_bit_rate Audio bit rate in kbit/sec. Set this to 0 to disable
* audio sending.
* @param video_bit_rate Video bit rate in Kb/sec. Set this to 0 to disable
* @param video_bit_rate Video bit rate in kbit/sec. Set this to 0 to disable
* video sending.
*/
bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate,
@ -597,11 +600,11 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t pcm
uint8_t channels, uint32_t sampling_rate, Toxav_Err_Send_Frame *error);
/**
* Set the bit rate to be used in subsequent video frames.
* Set the bit rate to be used in subsequent audio frames.
*
* @param friend_number The friend number of the friend for which to set the
* bit rate.
* @param bit_rate The new audio bit rate in Kb/sec. Set to 0 to disable.
* @param bit_rate The new audio bit rate in kbit/sec. Set to 0 to disable.
*
* @return true on success.
*/
@ -614,7 +617,7 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
*
* @param friend_number The friend number of the friend for which to set the
* bit rate.
* @param audio_bit_rate Suggested maximum audio bit rate in Kb/sec.
* @param audio_bit_rate Suggested maximum audio bit rate in kbit/sec.
*/
typedef void toxav_audio_bit_rate_cb(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, void *user_data);
@ -627,9 +630,10 @@ void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback,
/**
* Send a video frame to a friend.
*
* Y - plane should be of size: `height * width`
* U - plane should be of size: `(height/2) * (width/2)`
* V - plane should be of size: `(height/2) * (width/2)`
* The video frame needs to be planar YUV420.
* Y - plane should be of size: `width * height`
* U - plane should be of size: `(width/2) * (height/2)`
* V - plane should be of size: `(width/2) * (height/2)`
*
* @param friend_number The friend number of the friend to which to send a video
* frame.
@ -641,9 +645,9 @@ void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback,
*/
bool toxav_video_send_frame(
ToxAV *av, uint32_t friend_number, uint16_t width, uint16_t height,
const uint8_t y[/*! height * width */],
const uint8_t u[/*! height/2 * width/2 */],
const uint8_t v[/*! height/2 * width/2 */],
const uint8_t y[/*! width * height */],
const uint8_t u[/*! width/2 * height/2 */],
const uint8_t v[/*! width/2 * height/2 */],
Toxav_Err_Send_Frame *error);
/**
@ -651,7 +655,7 @@ bool toxav_video_send_frame(
*
* @param friend_number The friend number of the friend for which to set the
* bit rate.
* @param bit_rate The new video bit rate in Kb/sec. Set to 0 to disable.
* @param bit_rate The new video bit rate in kbit/sec. Set to 0 to disable.
*
* @return true on success.
*/
@ -664,7 +668,7 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
*
* @param friend_number The friend number of the friend for which to set the
* bit rate.
* @param video_bit_rate Suggested maximum video bit rate in Kb/sec.
* @param video_bit_rate Suggested maximum video bit rate in kbit/sec.
*/
typedef void toxav_video_bit_rate_cb(ToxAV *av, uint32_t friend_number, uint32_t video_bit_rate, void *user_data);

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 */
}
VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t friend_number,
VCSession *vc_new(const Logger *log, Mono_Time *mono_time, ToxAV *av, uint32_t friend_number,
toxav_video_receive_frame_cb *cb, void *cb_data)
{
VCSession *vc = (VCSession *)calloc(1, sizeof(VCSession));
@ -216,7 +216,7 @@ VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t f
/* Set encoder to some initial values
*/
vpx_codec_enc_cfg_t cfg;
vpx_codec_enc_cfg_t cfg;
vc_init_encoder_cfg(log, &cfg, 1);
LOGGER_DEBUG(log, "Using VP8 codec for encoder (0.1)");
@ -250,6 +250,7 @@ VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t f
}
#endif /* 0 */
vc->linfts = current_time_monotonic(mono_time);
vc->lcfd = 60;
vc->vcb = cb;
@ -258,12 +259,14 @@ VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t f
vc->av = av;
vc->log = log;
return vc;
BASE_CLEANUP_1:
vpx_codec_destroy(vc->decoder);
BASE_CLEANUP:
pthread_mutex_destroy(vc->queue_mutex);
rb_kill(vc->vbuf_raw);
free(vc);
return nullptr;
}

View File

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

View File

@ -1,4 +1,4 @@
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
load("@rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test")
exports_files(
@ -6,7 +6,7 @@ exports_files(
"tox.h",
"tox_private.h",
],
visibility = ["//c-toxcore:__pkg__"],
visibility = ["//c-toxcore:__subpackages__"],
)
cc_library(
@ -100,14 +100,58 @@ cc_test(
size = "small",
srcs = ["util_test.cc"],
deps = [
":crypto_core",
":crypto_core_test_util",
":util",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "sort",
srcs = ["sort.c"],
hdrs = ["sort.h"],
deps = [
":attributes",
":ccompat",
":util",
],
)
cc_library(
name = "sort_test_util",
testonly = True,
srcs = ["sort_test_util.cc"],
hdrs = ["sort_test_util.hh"],
deps = [
":sort",
":util",
],
)
cc_test(
name = "sort_test",
size = "small",
srcs = ["sort_test.cc"],
deps = [
":sort",
":sort_test_util",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
cc_binary(
name = "sort_bench",
testonly = True,
srcs = ["sort_bench.cc"],
deps = [
":mem",
":sort",
":sort_test_util",
"@benchmark",
],
)
cc_library(
name = "logger",
srcs = ["logger.c"],
@ -121,6 +165,7 @@ cc_library(
deps = [
":attributes",
":ccompat",
":mem",
],
)
@ -170,6 +215,7 @@ cc_library(
deps = [
":attributes",
":ccompat",
":mem",
":util",
"@libsodium",
],
@ -208,6 +254,7 @@ cc_test(
deps = [
":crypto_core",
":crypto_core_test_util",
":mem_test_util",
":util",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
@ -332,6 +379,7 @@ cc_library(
hdrs = ["network_test_util.hh"],
deps = [
":crypto_core",
":mem",
":network",
":test_util",
],
@ -435,6 +483,7 @@ cc_library(
":network",
":ping_array",
":shared_key_cache",
":sort",
":state",
":util",
],
@ -478,10 +527,12 @@ cc_test(
cc_fuzz_test(
name = "DHT_fuzz_test",
size = "small",
testonly = True,
srcs = ["DHT_fuzz_test.cc"],
corpus = ["//tools/toktok-fuzzer/corpus:DHT_fuzz_test"],
deps = [
":DHT",
":mem_test_util",
"//c-toxcore/testing/fuzzing:fuzz_support",
],
)
@ -490,7 +541,11 @@ cc_library(
name = "onion",
srcs = ["onion.c"],
hdrs = ["onion.h"],
visibility = ["//c-toxcore/auto_tests:__pkg__"],
visibility = [
"//c-toxcore/auto_tests:__pkg__",
"//c-toxcore/other:__pkg__",
"//c-toxcore/other/bootstrap_daemon:__pkg__",
],
deps = [
":DHT",
":attributes",
@ -509,7 +564,11 @@ cc_library(
name = "forwarding",
srcs = ["forwarding.c"],
hdrs = ["forwarding.h"],
visibility = ["//c-toxcore/auto_tests:__pkg__"],
visibility = [
"//c-toxcore/auto_tests:__pkg__",
"//c-toxcore/other:__pkg__",
"//c-toxcore/other/bootstrap_daemon:__pkg__",
],
deps = [
":DHT",
":attributes",
@ -661,7 +720,10 @@ cc_library(
name = "net_crypto",
srcs = ["net_crypto.c"],
hdrs = ["net_crypto.h"],
visibility = ["//c-toxcore/auto_tests:__pkg__"],
visibility = [
"//c-toxcore/auto_tests:__pkg__",
"//c-toxcore/toxav:__pkg__",
],
deps = [
":DHT",
":LAN_discovery",
@ -701,6 +763,7 @@ cc_library(
":network",
":onion",
":shared_key_cache",
":sort",
":timed_auth",
":util",
],
@ -774,6 +837,7 @@ cc_library(
":crypto_core",
":group_announce",
":logger",
":mem",
":mono_time",
":network",
":onion_announce",
@ -803,6 +867,7 @@ cc_library(
":onion",
":onion_announce",
":ping_array",
":sort",
":timed_auth",
":util",
],
@ -968,9 +1033,11 @@ cc_library(
":crypto_core",
":friend_connection",
":logger",
":mem",
":mono_time",
":net_crypto",
":network",
":sort",
":state",
":util",
],

View File

@ -9,7 +9,6 @@
#include "DHT.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "LAN_discovery.h"
@ -24,7 +23,9 @@
#include "ping.h"
#include "ping_array.h"
#include "shared_key_cache.h"
#include "sort.h"
#include "state.h"
#include "util.h"
/** The timeout after which a node is discarded completely. */
#define KILL_NODE_TIMEOUT (BAD_NODE_TIMEOUT + PING_INTERVAL)
@ -279,7 +280,7 @@ const uint8_t *dht_get_shared_key_sent(DHT *dht, const uint8_t *public_key)
#define CRYPTO_SIZE (1 + CRYPTO_PUBLIC_KEY_SIZE * 2 + CRYPTO_NONCE_SIZE)
int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
int create_request(const Memory *mem, const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
uint8_t *packet, const uint8_t *recv_public_key,
const uint8_t *data, uint32_t data_length, uint8_t request_id)
{
@ -296,7 +297,7 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint
uint8_t temp[MAX_CRYPTO_REQUEST_SIZE] = {0};
temp[0] = request_id;
memcpy(temp + 1, data, data_length);
const int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, data_length + 1,
const int len = encrypt_data(mem, recv_public_key, send_secret_key, nonce, temp, data_length + 1,
packet + CRYPTO_SIZE);
if (len == -1) {
@ -312,7 +313,7 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint
return len + CRYPTO_SIZE;
}
int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
int handle_request(const Memory *mem, const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
uint8_t *request_id, const uint8_t *packet, uint16_t packet_length)
{
if (self_public_key == nullptr || public_key == nullptr || data == nullptr || request_id == nullptr
@ -331,7 +332,7 @@ int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_ke
memcpy(public_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE);
const uint8_t *const nonce = packet + 1 + CRYPTO_PUBLIC_KEY_SIZE * 2;
uint8_t temp[MAX_CRYPTO_REQUEST_SIZE];
int32_t len1 = decrypt_data(public_key, self_secret_key, nonce,
int32_t len1 = decrypt_data(mem, public_key, self_secret_key, nonce,
packet + CRYPTO_SIZE, packet_length - CRYPTO_SIZE, temp);
if (len1 == -1 || len1 == 0) {
@ -378,14 +379,14 @@ int dht_create_packet(const Memory *mem, const Random *rng,
random_nonce(rng, nonce);
const int encrypted_length = encrypt_data_symmetric(shared_key, nonce, plain, plain_length, encrypted);
const int encrypted_length = encrypt_data_symmetric(mem, shared_key, nonce, plain, plain_length, encrypted);
if (encrypted_length == -1) {
if (encrypted_length < 0) {
mem_delete(mem, encrypted);
return -1;
}
if (length < 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length) {
if (length < 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + (size_t)encrypted_length) {
mem_delete(mem, encrypted);
return -1;
}
@ -755,49 +756,6 @@ int get_close_nodes(
is_lan, want_announce);
}
typedef struct DHT_Cmp_Data {
uint64_t cur_time;
const uint8_t *base_public_key;
Client_data entry;
} DHT_Cmp_Data;
non_null()
static int dht_cmp_entry(const void *a, const void *b)
{
const DHT_Cmp_Data *cmp1 = (const DHT_Cmp_Data *)a;
const DHT_Cmp_Data *cmp2 = (const DHT_Cmp_Data *)b;
const Client_data entry1 = cmp1->entry;
const Client_data entry2 = cmp2->entry;
const uint8_t *cmp_public_key = cmp1->base_public_key;
const bool t1 = assoc_timeout(cmp1->cur_time, &entry1.assoc4) && assoc_timeout(cmp1->cur_time, &entry1.assoc6);
const bool t2 = assoc_timeout(cmp2->cur_time, &entry2.assoc4) && assoc_timeout(cmp2->cur_time, &entry2.assoc6);
if (t1 && t2) {
return 0;
}
if (t1) {
return -1;
}
if (t2) {
return 1;
}
const int closest = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
if (closest == 1) {
return 1;
}
if (closest == 2) {
return -1;
}
return 0;
}
#ifdef CHECK_ANNOUNCE_NODE
non_null()
static void set_announce_node_in_list(Client_data *list, uint32_t list_len, const uint8_t *public_key)
@ -870,7 +828,7 @@ static int handle_data_search_response(void *object, const IP_Port *source,
const uint8_t *public_key = packet + 1;
const uint8_t *shared_key = dht_get_shared_key_recv(dht, public_key);
if (decrypt_data_symmetric(shared_key,
if (decrypt_data_symmetric(dht->mem, shared_key,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
plain_len + CRYPTO_MAC_SIZE,
@ -914,31 +872,117 @@ static bool store_node_ok(const Client_data *client, uint64_t cur_time, const ui
|| id_closest(comp_public_key, client->public_key, public_key) == 2;
}
typedef struct Client_data_Cmp {
const Memory *mem;
uint64_t cur_time;
const uint8_t *comp_public_key;
} Client_data_Cmp;
non_null()
static int client_data_cmp(const Client_data_Cmp *cmp, const Client_data *entry1, const Client_data *entry2)
{
const bool t1 = assoc_timeout(cmp->cur_time, &entry1->assoc4) && assoc_timeout(cmp->cur_time, &entry1->assoc6);
const bool t2 = assoc_timeout(cmp->cur_time, &entry2->assoc4) && assoc_timeout(cmp->cur_time, &entry2->assoc6);
if (t1 && t2) {
return 0;
}
if (t1) {
return -1;
}
if (t2) {
return 1;
}
const int closest = id_closest(cmp->comp_public_key, entry1->public_key, entry2->public_key);
if (closest == 1) {
return 1;
}
if (closest == 2) {
return -1;
}
return 0;
}
non_null()
static bool client_data_less_handler(const void *object, const void *a, const void *b)
{
const Client_data_Cmp *cmp = (const Client_data_Cmp *)object;
const Client_data *entry1 = (const Client_data *)a;
const Client_data *entry2 = (const Client_data *)b;
return client_data_cmp(cmp, entry1, entry2) < 0;
}
non_null()
static const void *client_data_get_handler(const void *arr, uint32_t index)
{
const Client_data *entries = (const Client_data *)arr;
return &entries[index];
}
non_null()
static void client_data_set_handler(void *arr, uint32_t index, const void *val)
{
Client_data *entries = (Client_data *)arr;
const Client_data *entry = (const Client_data *)val;
entries[index] = *entry;
}
non_null()
static void *client_data_subarr_handler(void *arr, uint32_t index, uint32_t size)
{
Client_data *entries = (Client_data *)arr;
return &entries[index];
}
non_null()
static void *client_data_alloc_handler(const void *object, uint32_t size)
{
const Client_data_Cmp *cmp = (const Client_data_Cmp *)object;
Client_data *tmp = (Client_data *)mem_valloc(cmp->mem, size, sizeof(Client_data));
if (tmp == nullptr) {
return nullptr;
}
return tmp;
}
non_null()
static void client_data_delete_handler(const void *object, void *arr, uint32_t size)
{
const Client_data_Cmp *cmp = (const Client_data_Cmp *)object;
mem_delete(cmp->mem, arr);
}
static const Sort_Funcs client_data_cmp_funcs = {
client_data_less_handler,
client_data_get_handler,
client_data_set_handler,
client_data_subarr_handler,
client_data_alloc_handler,
client_data_delete_handler,
};
non_null()
static void sort_client_list(const Memory *mem, Client_data *list, uint64_t cur_time, unsigned int length,
const uint8_t *comp_public_key)
{
// Pass comp_public_key to qsort with each Client_data entry, so the
// Pass comp_public_key to merge_sort with each Client_data entry, so the
// comparison function can use it as the base of comparison.
DHT_Cmp_Data *cmp_list = (DHT_Cmp_Data *)mem_valloc(mem, length, sizeof(DHT_Cmp_Data));
const Client_data_Cmp cmp = {
mem,
cur_time,
comp_public_key,
};
if (cmp_list == nullptr) {
return;
}
for (uint32_t i = 0; i < length; ++i) {
cmp_list[i].cur_time = cur_time;
cmp_list[i].base_public_key = comp_public_key;
cmp_list[i].entry = list[i];
}
qsort(cmp_list, length, sizeof(DHT_Cmp_Data), dht_cmp_entry);
for (uint32_t i = 0; i < length; ++i) {
list[i] = cmp_list[i].entry;
}
mem_delete(mem, cmp_list);
merge_sort(list, length, &cmp, &client_data_cmp_funcs);
}
non_null()
@ -1347,15 +1391,15 @@ static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t
plain[0] = num_nodes;
memcpy(plain + 1 + nodes_length, sendback_data, length);
const uint32_t crypto_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE;
const uint32_t data_size = 1 + nodes_length + length + crypto_size;
const uint16_t crypto_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE;
const uint16_t data_size = 1 + nodes_length + length + crypto_size;
VLA(uint8_t, data, data_size);
const int len = dht_create_packet(dht->mem, dht->rng,
dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6,
plain, 1 + nodes_length + length, data, data_size);
if (len != data_size) {
if (len < 0 || (uint32_t)len != data_size) {
return -1;
}
@ -1381,6 +1425,7 @@ static int handle_getnodes(void *object, const IP_Port *source, const uint8_t *p
uint8_t plain[CRYPTO_NODE_SIZE];
const uint8_t *shared_key = dht_get_shared_key_recv(dht, packet + 1);
const int len = decrypt_data_symmetric(
dht->mem,
shared_key,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
@ -1442,6 +1487,7 @@ static bool handle_sendnodes_core(void *object, const IP_Port *source, const uin
VLA(uint8_t, plain, plain_size);
const uint8_t *shared_key = dht_get_shared_key_sent(dht, packet + 1);
const int len = decrypt_data_symmetric(
dht->mem,
shared_key,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
@ -1840,7 +1886,7 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key)
return dht_getnodes(dht, ip_port, public_key, dht->self_public_key);
}
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled,
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dns_enabled,
uint16_t port, const uint8_t *public_key)
{
IP_Port ip_port_v64;
@ -1855,7 +1901,7 @@ bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled,
ip_extra = &ip_port_v4.ip;
}
if (addr_resolve_or_parse_ip(dht->ns, address, &ip_port_v64.ip, ip_extra)) {
if (addr_resolve_or_parse_ip(dht->ns, dht->mem, address, &ip_port_v64.ip, ip_extra, dns_enabled)) {
ip_port_v64.port = port;
dht_bootstrap(dht, &ip_port_v64, public_key);
@ -2123,7 +2169,7 @@ static int send_nat_ping(const DHT *dht, const uint8_t *public_key, uint64_t pin
memcpy(data + 1, &ping_id, sizeof(uint64_t));
/* 254 is NAT ping request packet id */
const int len = create_request(
dht->rng, dht->self_public_key, dht->self_secret_key, packet_data, public_key,
dht->mem, dht->rng, dht->self_public_key, dht->self_secret_key, packet_data, public_key,
data, sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING);
if (len == -1) {
@ -2458,7 +2504,7 @@ static int cryptopacket_handle(void *object, const IP_Port *source, const uint8_
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t data[MAX_CRYPTO_REQUEST_SIZE];
uint8_t number;
const int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key,
const int len = handle_request(dht->mem, dht->self_public_key, dht->self_secret_key, public_key,
data, &number, packet, length);
if (len == -1 || len == 0) {

View File

@ -99,7 +99,7 @@ extern "C" {
* @return the length of the created packet on success.
*/
non_null()
int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
int create_request(const Memory *mem, const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
uint8_t *packet, const uint8_t *recv_public_key,
const uint8_t *data, uint32_t data_length, uint8_t request_id);
@ -127,7 +127,7 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint
*/
non_null()
int handle_request(
const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
const Memory *mem, const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
uint8_t *request_id, const uint8_t *packet, uint16_t packet_length);
typedef struct IPPTs {
@ -404,12 +404,13 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key);
* @param address can be a hostname or an IP address (IPv4 or IPv6).
* @param ipv6enabled if false, the resolving sticks STRICTLY to IPv4 addresses.
* Otherwise, the resolving looks for IPv6 addresses first, then IPv4 addresses.
* @param dns_enabled if false, the resolving does not use DNS, only IP addresses are supported.
*
* @retval true if the address could be converted into an IP address
* @retval false otherwise
*/
non_null()
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled,
bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dns_enabled,
uint16_t port, const uint8_t *public_key);
/** @brief Start sending packets after DHT loaded_friends_list and loaded_clients_list are set.

View File

@ -6,19 +6,22 @@
#include <vector>
#include "../testing/fuzzing/fuzz_support.hh"
#include "mem_test_util.hh"
namespace {
void TestHandleRequest(Fuzz_Data &input)
{
const Test_Memory mem;
CONSUME_OR_RETURN(const uint8_t *self_public_key, input, CRYPTO_PUBLIC_KEY_SIZE);
CONSUME_OR_RETURN(const uint8_t *self_secret_key, input, CRYPTO_SECRET_KEY_SIZE);
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t request[MAX_CRYPTO_REQUEST_SIZE];
uint8_t request_id;
handle_request(self_public_key, self_secret_key, public_key, request, &request_id, input.data(),
input.size());
handle_request(mem, self_public_key, self_secret_key, public_key, request, &request_id,
input.data(), input.size());
}
void TestUnpackNodes(Fuzz_Data &input)
@ -31,7 +34,8 @@ void TestUnpackNodes(Fuzz_Data &input)
const int packed_count = unpack_nodes(
nodes, node_count, &processed_data_len, input.data(), input.size(), tcp_enabled);
if (packed_count > 0) {
Logger *logger = logger_new();
const Memory *mem = os_memory();
Logger *logger = logger_new(mem);
std::vector<uint8_t> packed(packed_count * PACKED_NODE_SIZE_IP6);
const int packed_size
= pack_nodes(logger, packed.data(), packed.size(), nodes, packed_count);

View File

@ -274,6 +274,7 @@ TEST(AddToList, KeepsKeysInOrder)
TEST(Request, CreateAndParse)
{
Test_Memory mem;
Test_Random rng;
// Peers.
@ -293,32 +294,32 @@ TEST(Request, CreateAndParse)
std::vector<uint8_t> outgoing(919);
random_bytes(rng, outgoing.data(), outgoing.size());
EXPECT_LT(create_request(rng, sender.pk.data(), sender.sk.data(), packet.data(),
EXPECT_LT(create_request(mem, rng, sender.pk.data(), sender.sk.data(), packet.data(),
receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id),
0);
// Pop one element so the payload is 918 bytes. Packing should now succeed.
outgoing.pop_back();
const int max_sent_length = create_request(rng, sender.pk.data(), sender.sk.data(),
const int max_sent_length = create_request(mem, rng, sender.pk.data(), sender.sk.data(),
packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id);
ASSERT_GT(max_sent_length, 0); // success.
// Check that handle_request rejects packets larger than the maximum created packet size.
EXPECT_LT(handle_request(receiver.pk.data(), receiver.sk.data(), pk.data(), incoming.data(),
&recvd_pkt_id, packet.data(), max_sent_length + 1),
EXPECT_LT(handle_request(mem, receiver.pk.data(), receiver.sk.data(), pk.data(),
incoming.data(), &recvd_pkt_id, packet.data(), max_sent_length + 1),
0);
// Now try all possible packet sizes from max (918) to 0.
while (!outgoing.empty()) {
// Pack:
const int sent_length = create_request(rng, sender.pk.data(), sender.sk.data(),
const int sent_length = create_request(mem, rng, sender.pk.data(), sender.sk.data(),
packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id);
ASSERT_GT(sent_length, 0);
// Unpack:
const int recvd_length = handle_request(receiver.pk.data(), receiver.sk.data(), pk.data(),
incoming.data(), &recvd_pkt_id, packet.data(), sent_length);
const int recvd_length = handle_request(mem, receiver.pk.data(), receiver.sk.data(),
pk.data(), incoming.data(), &recvd_pkt_id, packet.data(), sent_length);
ASSERT_GE(recvd_length, 0);
EXPECT_EQ(
@ -334,7 +335,7 @@ TEST(AnnounceNodes, SetAndTest)
Test_Memory mem;
Test_Network ns;
Logger *log = logger_new();
Logger *log = logger_new(mem);
ASSERT_NE(log, nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
ASSERT_NE(mono_time, nullptr);

View File

@ -86,6 +86,8 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
../toxcore/ping.c \
../toxcore/shared_key_cache.h \
../toxcore/shared_key_cache.c \
../toxcore/sort.h \
../toxcore/sort.c \
../toxcore/state.h \
../toxcore/state.c \
../toxcore/tox.h \

View File

@ -472,10 +472,6 @@ int m_delfriend(Messenger *m, int32_t friendnumber)
return -1;
}
if (m->friend_connectionstatuschange_internal != nullptr) {
m->friend_connectionstatuschange_internal(m, friendnumber, false, m->friend_connectionstatuschange_internal_userdata);
}
clear_receipts(m, friendnumber);
remove_request_received(m->fr, m->friendlist[friendnumber].real_pk);
friend_connection_callbacks(m->fr_c, m->friendlist[friendnumber].friendcon_id, MESSENGER_CALLBACK_INDEX, nullptr,
@ -1027,13 +1023,6 @@ void m_callback_core_connection(Messenger *m, m_self_connection_status_cb *funct
m->core_connection_change = function;
}
void m_callback_connectionstatus_internal_av(Messenger *m, m_friend_connectionstatuschange_internal_cb *function,
void *userdata)
{
m->friend_connectionstatuschange_internal = function;
m->friend_connectionstatuschange_internal_userdata = userdata;
}
non_null(1) nullable(3)
static void check_friend_tcp_udp(Messenger *m, int32_t friendnumber, void *userdata)
{
@ -1081,11 +1070,6 @@ static void check_friend_connectionstatus(Messenger *m, int32_t friendnumber, ui
m->friendlist[friendnumber].status = status;
check_friend_tcp_udp(m, friendnumber, userdata);
if (m->friend_connectionstatuschange_internal != nullptr) {
m->friend_connectionstatuschange_internal(m, friendnumber, is_online,
m->friend_connectionstatuschange_internal_userdata);
}
}
}
@ -1855,23 +1839,6 @@ static int handle_filecontrol(Messenger *m, int32_t friendnumber, bool outbound,
}
}
/** @brief Set the callback for msi packets. */
void m_callback_msi_packet(Messenger *m, m_msi_packet_cb *function, void *userdata)
{
m->msi_packet = function;
m->msi_packet_userdata = userdata;
}
/** @brief Send an msi packet.
*
* @retval true on success
* @retval false on failure
*/
bool m_msi_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length)
{
return write_cryptpacket_id(m, friendnumber, PACKET_ID_MSI, data, length, false);
}
static int m_handle_lossy_packet(void *object, int friendcon_id, const uint8_t *data, uint16_t length,
void *userdata)
{
@ -1881,17 +1848,6 @@ static int m_handle_lossy_packet(void *object, int friendcon_id, const uint8_t *
return 1;
}
if (data[0] <= PACKET_ID_RANGE_LOSSY_AV_END) {
const RTP_Packet_Handler *const ph =
&m->friendlist[friendcon_id].lossy_rtp_packethandlers[data[0] % PACKET_ID_RANGE_LOSSY_AV_SIZE];
if (ph->function != nullptr) {
return ph->function(m, friendcon_id, data, length, ph->object);
}
return 1;
}
if (m->lossy_packethandler != nullptr) {
m->lossy_packethandler(m, friendcon_id, data[0], data, length, userdata);
}
@ -1904,38 +1860,6 @@ void custom_lossy_packet_registerhandler(Messenger *m, m_friend_lossy_packet_cb
m->lossy_packethandler = lossy_packethandler;
}
int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte, m_lossy_rtp_packet_cb *function,
void *object)
{
if (!m_friend_exists(m, friendnumber)) {
return -1;
}
if (byte < PACKET_ID_RANGE_LOSSY_AV_START || byte > PACKET_ID_RANGE_LOSSY_AV_END) {
return -1;
}
m->friendlist[friendnumber].lossy_rtp_packethandlers[byte % PACKET_ID_RANGE_LOSSY_AV_SIZE].function = function;
m->friendlist[friendnumber].lossy_rtp_packethandlers[byte % PACKET_ID_RANGE_LOSSY_AV_SIZE].object = object;
return 0;
}
/** @brief High level function to send custom lossy packets.
*
* TODO(oxij): this name is confusing, because this function sends both av and custom lossy packets.
* Meanwhile, m_handle_lossy_packet routes custom packets to custom_lossy_packet_registerhandler
* as you would expect from its name.
*
* I.e. custom_lossy_packet_registerhandler's "custom lossy packet" and this "custom lossy packet"
* are not the same set of packets.
*
* @retval -1 if friend invalid.
* @retval -2 if length wrong.
* @retval -3 if first byte invalid.
* @retval -4 if friend offline.
* @retval -5 if packet failed to send because of other error.
* @retval 0 on success.
*/
int m_send_custom_lossy_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint32_t length)
{
if (!m_friend_exists(m, friendnumber)) {
@ -1946,7 +1870,6 @@ int m_send_custom_lossy_packet(const Messenger *m, int32_t friendnumber, const u
return -2;
}
// TODO(oxij): send_lossy_cryptpacket makes this check already, similarly for other similar places
if (data[0] < PACKET_ID_RANGE_LOSSY_START || data[0] > PACKET_ID_RANGE_LOSSY_END) {
return -3;
}
@ -1974,7 +1897,10 @@ static int handle_custom_lossless_packet(void *object, int friend_num, const uin
}
if (packet[0] < PACKET_ID_RANGE_LOSSLESS_CUSTOM_START || packet[0] > PACKET_ID_RANGE_LOSSLESS_CUSTOM_END) {
return -1;
// allow PACKET_ID_MSI packets to be handled by custom packet handler
if (packet[0] != PACKET_ID_MSI) {
return -1;
}
}
if (m->lossless_packethandler != nullptr) {
@ -2356,20 +2282,6 @@ static int m_handle_packet_file_data(Messenger *m, const int friendcon_id, const
return 0;
}
non_null(1, 3) nullable(5)
static int m_handle_packet_msi(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata)
{
if (data_length == 0) {
return 0;
}
if (m->msi_packet != nullptr) {
m->msi_packet(m, friendcon_id, data, data_length, m->msi_packet_userdata);
}
return 0;
}
non_null(1, 3) nullable(5)
static int m_handle_packet_invite_groupchat(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata)
{
@ -2443,7 +2355,7 @@ static int m_handle_packet(void *object, int friendcon_id, const uint8_t *data,
case PACKET_ID_FILE_DATA:
return m_handle_packet_file_data(m, friendcon_id, payload, payload_length, userdata);
case PACKET_ID_MSI:
return m_handle_packet_msi(m, friendcon_id, payload, payload_length, userdata);
return handle_custom_lossless_packet(object, friendcon_id, data, length, userdata);
case PACKET_ID_INVITE_GROUPCHAT:
return m_handle_packet_invite_groupchat(m, friendcon_id, payload, payload_length, userdata);
}
@ -3570,7 +3482,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
return nullptr;
}
m->log = logger_new();
m->log = logger_new(mem);
if (m->log == nullptr) {
friendreq_kill(m->fr);

View File

@ -86,6 +86,8 @@ typedef struct Messenger_Options {
Messenger_State_Plugin *state_plugins;
uint8_t state_plugins_length;
bool dns_enabled;
} Messenger_Options;
struct Receipts {
@ -200,20 +202,10 @@ typedef void m_friend_lossy_packet_cb(Messenger *m, uint32_t friend_number, uint
size_t length, void *user_data);
typedef void m_friend_lossless_packet_cb(Messenger *m, uint32_t friend_number, uint8_t packet_id, const uint8_t *data,
size_t length, void *user_data);
typedef void m_friend_connectionstatuschange_internal_cb(Messenger *m, uint32_t friend_number,
bool is_online, void *user_data);
typedef void m_conference_invite_cb(Messenger *m, uint32_t friend_number, const uint8_t *cookie, uint16_t length,
void *user_data);
typedef void m_group_invite_cb(const Messenger *m, uint32_t friend_number, const uint8_t *invite_data, size_t length,
const uint8_t *group_name, size_t group_name_length, void *user_data);
typedef void m_msi_packet_cb(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length,
void *user_data);
typedef int m_lossy_rtp_packet_cb(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object);
typedef struct RTP_Packet_Handler {
m_lossy_rtp_packet_cb *function;
void *object;
} RTP_Packet_Handler;
typedef struct Friend {
uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE];
@ -243,8 +235,6 @@ typedef struct Friend {
uint32_t num_sending_files;
struct File_Transfers file_receiving[MAX_CONCURRENT_FILE_PIPES];
RTP_Packet_Handler lossy_rtp_packethandlers[PACKET_ID_RANGE_LOSSY_AV_SIZE];
struct Receipts *receipts_start;
struct Receipts *receipts_end;
} Friend;
@ -301,8 +291,6 @@ struct Messenger {
m_friend_typing_cb *friend_typingchange;
m_friend_read_receipt_cb *read_receipt;
m_friend_connection_status_cb *friend_connectionstatuschange;
m_friend_connectionstatuschange_internal_cb *friend_connectionstatuschange_internal;
void *friend_connectionstatuschange_internal_userdata;
struct Group_Chats *conferences_object;
m_conference_invite_cb *conference_invite;
@ -314,9 +302,6 @@ struct Messenger {
m_file_recv_chunk_cb *file_filedata;
m_file_chunk_request_cb *file_reqchunk;
m_msi_packet_cb *msi_packet;
void *msi_packet_userdata;
m_friend_lossy_packet_cb *lossy_packethandler;
m_friend_lossless_packet_cb *lossless_packethandler;
@ -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);
/** Same as previous but for internal A/V core usage only */
non_null() void m_callback_connectionstatus_internal_av(
Messenger *m, m_friend_connectionstatuschange_internal_cb *function, void *userdata);
/** @brief Set the callback for typing changes. */
non_null() void m_callback_core_connection(Messenger *m, m_self_connection_status_cb *function);
@ -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,
const uint8_t *data, uint16_t length);
/*** A/V related */
/** @brief Set the callback for msi packets. */
non_null(1) nullable(2, 3)
void m_callback_msi_packet(Messenger *m, m_msi_packet_cb *function, void *userdata);
/** @brief Send an msi packet.
*
* @retval true on success
* @retval false on failure
*/
non_null()
bool m_msi_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length);
/** @brief Set handlers for lossy rtp packets.
*
* @retval -1 on failure.
* @retval 0 on success.
*/
non_null(1) nullable(4, 5)
int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte,
m_lossy_rtp_packet_cb *function, void *object);
/*** CUSTOM PACKETS */
/** @brief Set handlers for custom lossy packets. */
non_null() void custom_lossy_packet_registerhandler(Messenger *m, m_friend_lossy_packet_cb *lossy_packethandler);
/** @brief High level function to send custom lossy packets.
*
* TODO(oxij): this name is confusing, because this function sends both av and custom lossy packets.
* Meanwhile, m_handle_lossy_packet routes custom packets to custom_lossy_packet_registerhandler
* as you would expect from its name.
*
* I.e. custom_lossy_packet_registerhandler's "custom lossy packet" and this "custom lossy packet"
* are not the same set of packets.
*
* @retval -1 if friend invalid.
* @retval -2 if length wrong.

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