summaryrefslogtreecommitdiff
path: root/protocols/Tox/libtox
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Tox/libtox')
-rw-r--r--protocols/Tox/libtox/docs/CHANGELOG.md474
-rw-r--r--protocols/Tox/libtox/docs/LICENSE9
-rw-r--r--protocols/Tox/libtox/docs/README.md80
-rw-r--r--protocols/Tox/libtox/libtox.vcxproj16
-rw-r--r--protocols/Tox/libtox/libtox.vcxproj.filters24
-rw-r--r--protocols/Tox/libtox/src/third_party/cmp/cmp.c4
-rw-r--r--protocols/Tox/libtox/src/toxcore/DHT.c294
-rw-r--r--protocols/Tox/libtox/src/toxcore/DHT.h25
-rw-r--r--protocols/Tox/libtox/src/toxcore/LAN_discovery.c86
-rw-r--r--protocols/Tox/libtox/src/toxcore/LAN_discovery.h5
-rw-r--r--protocols/Tox/libtox/src/toxcore/Makefile.inc179
-rw-r--r--protocols/Tox/libtox/src/toxcore/Messenger.c165
-rw-r--r--protocols/Tox/libtox/src/toxcore/Messenger.h57
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_client.c46
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_client.h7
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_common.c20
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_common.h7
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_connection.c17
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_connection.h5
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_server.c46
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_server.h10
-rw-r--r--protocols/Tox/libtox/src/toxcore/announce.c21
-rw-r--r--protocols/Tox/libtox/src/toxcore/announce.h2
-rw-r--r--protocols/Tox/libtox/src/toxcore/attributes.h2
-rw-r--r--protocols/Tox/libtox/src/toxcore/bin_pack.c2
-rw-r--r--protocols/Tox/libtox/src/toxcore/bin_pack.h2
-rw-r--r--protocols/Tox/libtox/src/toxcore/bin_unpack.c21
-rw-r--r--protocols/Tox/libtox/src/toxcore/bin_unpack.h5
-rw-r--r--protocols/Tox/libtox/src/toxcore/ccompat.c2
-rw-r--r--protocols/Tox/libtox/src/toxcore/ccompat.h2
-rw-r--r--protocols/Tox/libtox/src/toxcore/crypto_core.c63
-rw-r--r--protocols/Tox/libtox/src/toxcore/crypto_core.h15
-rw-r--r--protocols/Tox/libtox/src/toxcore/crypto_core_pack.c2
-rw-r--r--protocols/Tox/libtox/src/toxcore/crypto_core_pack.h2
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/conference_connected.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/conference_invite.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/conference_message.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/conference_peer_list_changed.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/conference_peer_name.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/conference_title.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/dht_get_nodes_response.c223
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/dht_nodes_response.c222
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/events_alloc.c2
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/events_alloc.h7
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/file_chunk_request.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/file_recv.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/file_recv_chunk.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/file_recv_control.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/friend_connection_status.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/friend_lossless_packet.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/friend_lossy_packet.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/friend_message.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/friend_name.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/friend_read_receipt.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/friend_request.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/friend_status.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/friend_status_message.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/friend_typing.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_custom_packet.c12
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_custom_private_packet.c12
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_invite.c12
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_join_fail.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_message.c30
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_moderation.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_password.c12
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_peer_exit.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_peer_join.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_peer_limit.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_peer_name.c12
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_peer_status.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_privacy_state.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_private_message.c55
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_self_join.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_topic.c12
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_topic_lock.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/group_voice_state.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/events/self_connection_status.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/forwarding.c12
-rw-r--r--protocols/Tox/libtox/src/toxcore/forwarding.h5
-rw-r--r--protocols/Tox/libtox/src/toxcore/friend_connection.c27
-rw-r--r--protocols/Tox/libtox/src/toxcore/friend_connection.h6
-rw-r--r--protocols/Tox/libtox/src/toxcore/friend_requests.c28
-rw-r--r--protocols/Tox/libtox/src/toxcore/friend_requests.h9
-rw-r--r--protocols/Tox/libtox/src/toxcore/group.c124
-rw-r--r--protocols/Tox/libtox/src/toxcore/group.h5
-rw-r--r--protocols/Tox/libtox/src/toxcore/group_announce.c27
-rw-r--r--protocols/Tox/libtox/src/toxcore/group_announce.h8
-rw-r--r--protocols/Tox/libtox/src/toxcore/group_chats.c515
-rw-r--r--protocols/Tox/libtox/src/toxcore/group_chats.h21
-rw-r--r--protocols/Tox/libtox/src/toxcore/group_common.h9
-rw-r--r--protocols/Tox/libtox/src/toxcore/group_connection.c118
-rw-r--r--protocols/Tox/libtox/src/toxcore/group_connection.h17
-rw-r--r--protocols/Tox/libtox/src/toxcore/group_moderation.c52
-rw-r--r--protocols/Tox/libtox/src/toxcore/group_onion_announce.c13
-rw-r--r--protocols/Tox/libtox/src/toxcore/group_onion_announce.h9
-rw-r--r--protocols/Tox/libtox/src/toxcore/group_pack.c47
-rw-r--r--protocols/Tox/libtox/src/toxcore/group_pack.h4
-rw-r--r--protocols/Tox/libtox/src/toxcore/list.c16
-rw-r--r--protocols/Tox/libtox/src/toxcore/list.h7
-rw-r--r--protocols/Tox/libtox/src/toxcore/logger.c72
-rw-r--r--protocols/Tox/libtox/src/toxcore/logger.h10
-rw-r--r--protocols/Tox/libtox/src/toxcore/mem.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/mem.h10
-rw-r--r--protocols/Tox/libtox/src/toxcore/mono_time.c4
-rw-r--r--protocols/Tox/libtox/src/toxcore/mono_time.h2
-rw-r--r--protocols/Tox/libtox/src/toxcore/net_crypto.c237
-rw-r--r--protocols/Tox/libtox/src/toxcore/net_crypto.h31
-rw-r--r--protocols/Tox/libtox/src/toxcore/net_profile.c157
-rw-r--r--protocols/Tox/libtox/src/toxcore/net_profile.h81
-rw-r--r--protocols/Tox/libtox/src/toxcore/network.c383
-rw-r--r--protocols/Tox/libtox/src/toxcore/network.h116
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion.c34
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion.h6
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion_announce.c154
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion_announce.h12
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion_client.c166
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion_client.h4
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping.c12
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping.h2
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping_array.c2
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping_array.h2
-rw-r--r--protocols/Tox/libtox/src/toxcore/shared_key_cache.c2
-rw-r--r--protocols/Tox/libtox/src/toxcore/shared_key_cache.h2
-rw-r--r--protocols/Tox/libtox/src/toxcore/sort.c182
-rw-r--r--protocols/Tox/libtox/src/toxcore/sort.h116
-rw-r--r--protocols/Tox/libtox/src/toxcore/timed_auth.c2
-rw-r--r--protocols/Tox/libtox/src/toxcore/timed_auth.h2
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox.c318
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox.h1644
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_api.c592
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_dispatch.c18
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_dispatch.h17
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_event.c110
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_event.h12
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_events.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_events.h39
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_log_level.c27
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_log_level.h58
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_options.c285
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_options.h455
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_pack.c2
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_pack.h2
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_private.c229
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_private.h385
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_struct.h9
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_unpack.c112
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_unpack.h2
-rw-r--r--protocols/Tox/libtox/src/toxcore/util.c7
-rw-r--r--protocols/Tox/libtox/src/toxcore/util.h11
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/defines.h2
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c97
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h40
152 files changed, 6416 insertions, 3531 deletions
diff --git a/protocols/Tox/libtox/docs/CHANGELOG.md b/protocols/Tox/libtox/docs/CHANGELOG.md
index 85da062d93..36bfb39b2c 100644
--- a/protocols/Tox/libtox/docs/CHANGELOG.md
+++ b/protocols/Tox/libtox/docs/CHANGELOG.md
@@ -1,9 +1,483 @@
+## 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:
+
+- [#2744](https://github.com/TokTok/c-toxcore/pull/2744) docs: Document that group topic lock is default on.
+- [#2743](https://github.com/TokTok/c-toxcore/pull/2743) docs: Add missing param docs for callbacks.
+- [#2742](https://github.com/TokTok/c-toxcore/pull/2742) chore: Add cmake flag to disable unit tests.
+- [#2741](https://github.com/TokTok/c-toxcore/pull/2741) refactor: Don't expose Tox_System in the public API
+- [#2736](https://github.com/TokTok/c-toxcore/pull/2736) cleanup: A more descriptive error for group invite accept function
+- [#2735](https://github.com/TokTok/c-toxcore/pull/2735) chore: Small API doc fixes
+- [#2732](https://github.com/TokTok/c-toxcore/pull/2732) cleanup: event length naming inconsistencies
+- [#2731](https://github.com/TokTok/c-toxcore/pull/2731) cleanup: align group send err enum order
+- [#2729](https://github.com/TokTok/c-toxcore/pull/2729) cleanup: use typedef for private message ID's in callback
+- [#2728](https://github.com/TokTok/c-toxcore/pull/2728) refactor: Observers/ignored peers can now send and receive custom packets
+- [#2727](https://github.com/TokTok/c-toxcore/pull/2727) feat: add message IDs to private group messages
+- [#2726](https://github.com/TokTok/c-toxcore/pull/2726) refactor: Rename `out` parameters to `out_$something`.
+- [#2718](https://github.com/TokTok/c-toxcore/pull/2718) chore: Use a specific non-broken slimcc version.
+- [#2713](https://github.com/TokTok/c-toxcore/pull/2713) feat: Update and improve the Windows cross-compilation
+- [#2712](https://github.com/TokTok/c-toxcore/pull/2712) chore: Update github actions.
+- [#2710](https://github.com/TokTok/c-toxcore/pull/2710) docs: Update the list of CMake options
+- [#2709](https://github.com/TokTok/c-toxcore/pull/2709) refactor: Remove "mod" and "founder" from group API naming scheme
+- [#2708](https://github.com/TokTok/c-toxcore/pull/2708) docs: add the experimental api build option to INSTALL.md
+- [#2705](https://github.com/TokTok/c-toxcore/pull/2705) refactor: Rename Queries to Query to align with other enums.
+- [#2704](https://github.com/TokTok/c-toxcore/pull/2704) fix: Correct type for conference offline peer numbers.
+- [#2700](https://github.com/TokTok/c-toxcore/pull/2700) test: Add FreeBSD VM action on GitHub.
+- [#2699](https://github.com/TokTok/c-toxcore/pull/2699) test: Add pkgsrc build.
+- [#2698](https://github.com/TokTok/c-toxcore/pull/2698) chore: Only install tox_private.h on request.
+- [#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
+- [#2684](https://github.com/TokTok/c-toxcore/pull/2684) cleanup: Don't use `memcpy` to cast arbitrary `struct`s to `uint8_t[]`.
+- [#2683](https://github.com/TokTok/c-toxcore/pull/2683) fix: Pass array, not array pointer, to `memcmp`.
+- [#2682](https://github.com/TokTok/c-toxcore/pull/2682) cleanup: Never pass `void*` directly to `memcpy`.
+- [#2678](https://github.com/TokTok/c-toxcore/pull/2678) chore: Disable NGC saving by default, enable through Tox_Options.
+- [#2675](https://github.com/TokTok/c-toxcore/pull/2675) cleanup: Replace pointer arithmetic with explicit `&arr[i]`.
+- [#2672](https://github.com/TokTok/c-toxcore/pull/2672) refactor: Use `structs` for extended public/secret keys.
+- [#2671](https://github.com/TokTok/c-toxcore/pull/2671) refactor: Use tox rng to seed the keypair generation.
+- [#2666](https://github.com/TokTok/c-toxcore/pull/2666) cleanup: Small improvements found by PVS Studio.
+- [#2664](https://github.com/TokTok/c-toxcore/pull/2664) docs: Run prettier-markdown on markdown files.
+- [#2662](https://github.com/TokTok/c-toxcore/pull/2662) fix: Correct a few potential null derefs in bootstrap daemon.
+- [#2661](https://github.com/TokTok/c-toxcore/pull/2661) fix: Zero out stack-allocated secret key before return.
+- [#2660](https://github.com/TokTok/c-toxcore/pull/2660) fix: Add missing memunlock of local variable when it goes out of scope.
+- [#2659](https://github.com/TokTok/c-toxcore/pull/2659) cleanup: Simplify custom packet length check in NGC.
+- [#2658](https://github.com/TokTok/c-toxcore/pull/2658) refactor: Make prune_gc_sanctions_list more obviously correct.
+- [#2657](https://github.com/TokTok/c-toxcore/pull/2657) fix: Fix some false positive from PVS Studio.
+- [#2656](https://github.com/TokTok/c-toxcore/pull/2656) docs: Add static analysis tool list to README.
+- [#2655](https://github.com/TokTok/c-toxcore/pull/2655) cleanup: Check that WINXP macro exists before comparing it.
+- [#2652](https://github.com/TokTok/c-toxcore/pull/2652) refactor: Make tox mutex non-recursive.
+- [#2648](https://github.com/TokTok/c-toxcore/pull/2648) docs: Add more documentation to crypto_core.
+- [#2647](https://github.com/TokTok/c-toxcore/pull/2647) docs: Fix up doxyfile.
+- [#2645](https://github.com/TokTok/c-toxcore/pull/2645) refactor: Remove `Tox *` from `tox_dispatch`.
+- [#2644](https://github.com/TokTok/c-toxcore/pull/2644) refactor: Don't rely on tox_dispatch passing tox in tests.
+- [#2643](https://github.com/TokTok/c-toxcore/pull/2643) refactor: Use strong typedef for NGC peer id.
+- [#2642](https://github.com/TokTok/c-toxcore/pull/2642) chore: Use C++ mode for clang-tidy.
+- [#2640](https://github.com/TokTok/c-toxcore/pull/2640) refactor: Use strong `typedef` instead of `struct` for `Socket`.
+- [#2637](https://github.com/TokTok/c-toxcore/pull/2637) chore: Check that both gtest and gmock exist for tests.
+- [#2634](https://github.com/TokTok/c-toxcore/pull/2634) chore: Add some comments to the astyle config.
+- [#2629](https://github.com/TokTok/c-toxcore/pull/2629) chore: Reformat sources with astyle.
+- [#2626](https://github.com/TokTok/c-toxcore/pull/2626) chore: Rename C++ headers to .hh suffixes.
+- [#2624](https://github.com/TokTok/c-toxcore/pull/2624) test: Add slimcc compiler compatibility test.
+- [#2622](https://github.com/TokTok/c-toxcore/pull/2622) cleanup: Add more `const` where possible.
+- [#2621](https://github.com/TokTok/c-toxcore/pull/2621) cleanup: Remove implicit bool conversions.
+- [#2620](https://github.com/TokTok/c-toxcore/pull/2620) chore: Only check the bootstrap daemon checksum on release.
+- [#2617](https://github.com/TokTok/c-toxcore/pull/2617) cleanup: Further `#include` cleanups.
+- [#2614](https://github.com/TokTok/c-toxcore/pull/2614) cleanup: Use Bazel modules to enforce proper `#include` hygiene.
+- [#2612](https://github.com/TokTok/c-toxcore/pull/2612) refactor: Move pack/unpack `IP_Port` from DHT into network module.
+- [#2611](https://github.com/TokTok/c-toxcore/pull/2611) chore: Really fix coverage docker image build.
+- [#2610](https://github.com/TokTok/c-toxcore/pull/2610) chore: Fix post-submit coverage image.
+- [#2609](https://github.com/TokTok/c-toxcore/pull/2609) fix: partially fix a bug that prevented group part messages from sending
+- [#2605](https://github.com/TokTok/c-toxcore/pull/2605) fix: Don't use `memcmp` to compare `IP_Port`s.
+- [#2604](https://github.com/TokTok/c-toxcore/pull/2604) chore: Fix rpm build; add a CI check for it.
+- [#2603](https://github.com/TokTok/c-toxcore/pull/2603) chore: Speed up docker builds a bit by reducing layer count.
+- [#2602](https://github.com/TokTok/c-toxcore/pull/2602) cleanup: Add `const` where possible in auto tests.
+- [#2601](https://github.com/TokTok/c-toxcore/pull/2601) fix: a few off by one errors in group autotests
+- [#2598](https://github.com/TokTok/c-toxcore/pull/2598) refactor: Rename `system_{memory,...}` to `os_{memory,...}`.
+- [#2597](https://github.com/TokTok/c-toxcore/pull/2597) test: Add goblint static analyser.
+- [#2594](https://github.com/TokTok/c-toxcore/pull/2594) cleanup: Use `memzero(x, s)` instead of `memset(x, 0, s)`.
+- [#2593](https://github.com/TokTok/c-toxcore/pull/2593) cleanup: Use explicit 0 instead of `PACKET_ID_PADDING`.
+- [#2592](https://github.com/TokTok/c-toxcore/pull/2592) cleanup: Remove all uses of `SIZEOF_VLA`.
+- [#2591](https://github.com/TokTok/c-toxcore/pull/2591) cleanup: Expand the `Tox_Options` accessor macros.
+- [#2590](https://github.com/TokTok/c-toxcore/pull/2590) test: Add a simple new/delete test for Tox.
+- [#2588](https://github.com/TokTok/c-toxcore/pull/2588) cleanup: Remove plan9 support.
+- [#2587](https://github.com/TokTok/c-toxcore/pull/2587) cleanup: Add comment after every `#endif`.
+- [#2583](https://github.com/TokTok/c-toxcore/pull/2583) test: Fix comment I broke in the events test PR.
+- [#2582](https://github.com/TokTok/c-toxcore/pull/2582) cleanup: Rename group to conference in groupav documentation.
+- [#2581](https://github.com/TokTok/c-toxcore/pull/2581) cleanup: Ensure handler params are named after callback params.
+- [#2580](https://github.com/TokTok/c-toxcore/pull/2580) cleanup: Minor cleanup of event unpack code.
+- [#2578](https://github.com/TokTok/c-toxcore/pull/2578) refactor: Allow NULL pointers for byte arrays in events.
+- [#2577](https://github.com/TokTok/c-toxcore/pull/2577) refactor: Add common msgpack array packer with callback.
+- [#2576](https://github.com/TokTok/c-toxcore/pull/2576) cleanup: make some improvements to group moderation test
+- [#2575](https://github.com/TokTok/c-toxcore/pull/2575) refactor: Pass `this` pointer as first param to s11n callbacks.
+- [#2573](https://github.com/TokTok/c-toxcore/pull/2573) cleanup: skip a do_gc iteration before removing peers marked for deletion
+- [#2572](https://github.com/TokTok/c-toxcore/pull/2572) cleanup: Remove `bin_pack_{new,free}`.
+- [#2568](https://github.com/TokTok/c-toxcore/pull/2568) feat: Add dht_get_nodes_response event to the events system.
+- [#2567](https://github.com/TokTok/c-toxcore/pull/2567) refactor: Use enum-specific pack functions for enum values.
+- [#2566](https://github.com/TokTok/c-toxcore/pull/2566) cleanup: Remove empty test doing nothing.
+- [#2565](https://github.com/TokTok/c-toxcore/pull/2565) refactor: Factor out union pack switch from event packer.
+- [#2564](https://github.com/TokTok/c-toxcore/pull/2564) cleanup: Move the 2-element array pack out of individual events.
+- [#2563](https://github.com/TokTok/c-toxcore/pull/2563) test: Add printf log statement to group_moderation_test.
+- [#2562](https://github.com/TokTok/c-toxcore/pull/2562) chore: add clangd files to .gitignore
+- [#2561](https://github.com/TokTok/c-toxcore/pull/2561) refactor: Move file streaming test to its own file.
+- [#2560](https://github.com/TokTok/c-toxcore/pull/2560) fix(ci): window builds now build in parallel
+- [#2559](https://github.com/TokTok/c-toxcore/pull/2559) refactor: Migrate auto_tests to new events API.
+- [#2557](https://github.com/TokTok/c-toxcore/pull/2557) test: Add C++ classes wrapping system interfaces.
+- [#2555](https://github.com/TokTok/c-toxcore/pull/2555) fix: Remove fatal error for non-erroneous case
+- [#2554](https://github.com/TokTok/c-toxcore/pull/2554) fix: Make all the fuzzers work again, and add a test for protodump.
+- [#2552](https://github.com/TokTok/c-toxcore/pull/2552) fix: Make sure there's enough space for CONSUME1 in fuzzers.
+- [#2551](https://github.com/TokTok/c-toxcore/pull/2551) chore: Move from gcov to llvm source-based coverage.
+- [#2549](https://github.com/TokTok/c-toxcore/pull/2549) fix: issues with packet broadcast error reporting
+- [#2547](https://github.com/TokTok/c-toxcore/pull/2547) test: Add fuzz tests to the coverage run.
+- [#2545](https://github.com/TokTok/c-toxcore/pull/2545) refactor: Use `operator==` for equality tests of `Node_format`.
+- [#2543](https://github.com/TokTok/c-toxcore/pull/2543) refactor(test): Slightly nicer C++ interface to tox Random.
+- [#2542](https://github.com/TokTok/c-toxcore/pull/2542) refactor: packet broadcast functions now return errors
+- [#2541](https://github.com/TokTok/c-toxcore/pull/2541) fix: don't pass garbage data buffer to packet send functions
+- [#2540](https://github.com/TokTok/c-toxcore/pull/2540) cleanup: Make group packet entry creation less error-prone
+- [#2539](https://github.com/TokTok/c-toxcore/pull/2539) refactor: Minor refactoring of get_close_nodes functions.
+- [#2538](https://github.com/TokTok/c-toxcore/pull/2538) refactor: Factor out malloc+memcpy into memdup.
+- [#2536](https://github.com/TokTok/c-toxcore/pull/2536) cleanup: Some more test cleanups, removing overly smart code.
+- [#2531](https://github.com/TokTok/c-toxcore/pull/2531) test: Add more unit tests for `add_to_list`.
+- [#2530](https://github.com/TokTok/c-toxcore/pull/2530) refactor: Assign malloc return to a local variable first.
+- [#2529](https://github.com/TokTok/c-toxcore/pull/2529) test: Add "infer" CI check to github, remove from circle.
+- [#2527](https://github.com/TokTok/c-toxcore/pull/2527) cleanup: Add Toxav alias for ToxAV.
+- [#2526](https://github.com/TokTok/c-toxcore/pull/2526) cleanup: Make Tox_Options a typedef.
+- [#2525](https://github.com/TokTok/c-toxcore/pull/2525) cleanup: Add dynamically derived array sizes to the API.
+- [#2524](https://github.com/TokTok/c-toxcore/pull/2524) cleanup: Add explicit array sizes to toxencryptsave.
+- [#2523](https://github.com/TokTok/c-toxcore/pull/2523) cleanup: Move `tox_get_system` out of the public API.
+- [#2522](https://github.com/TokTok/c-toxcore/pull/2522) cleanup: Make setters take non-const `Tox *`.
+- [#2521](https://github.com/TokTok/c-toxcore/pull/2521) cleanup: Make array params in toxav `[]` instead of `*`.
+- [#2520](https://github.com/TokTok/c-toxcore/pull/2520) cleanup: Mark arrays in the tox API as `[]` instead of `*`.
+- [#2519](https://github.com/TokTok/c-toxcore/pull/2519) refactor: Align group message sending with other send functions.
+- [#2518](https://github.com/TokTok/c-toxcore/pull/2518) cleanup: Add typedefs for public API int identifiers.
+- [#2517](https://github.com/TokTok/c-toxcore/pull/2517) chore: Spellcheck tox-bootstrapd
+- [#2516](https://github.com/TokTok/c-toxcore/pull/2516) chore: Remove settings.yml in favour of hs-github-tools.
+- [#2515](https://github.com/TokTok/c-toxcore/pull/2515) chore: Use GPL license with https.
+- [#2513](https://github.com/TokTok/c-toxcore/pull/2513) chore: Add fetch-sha256 script to update bootstrap node hash.
+- [#2512](https://github.com/TokTok/c-toxcore/pull/2512) cleanup: Move all vptr-to-ptr casts to the beginning of a function.
+- [#2510](https://github.com/TokTok/c-toxcore/pull/2510) cleanup: Use github actions matrix to simplify CI.
+- [#2509](https://github.com/TokTok/c-toxcore/pull/2509) fix: Use QueryPerformanceCounter on windows for monotonic time.
+- [#2508](https://github.com/TokTok/c-toxcore/pull/2508) chore: Add `net_(new|kill)_strerror` to cppcheck's allocators.
+- [#2507](https://github.com/TokTok/c-toxcore/pull/2507) cleanup: Run clang-tidy on headers, as well.
+- [#2506](https://github.com/TokTok/c-toxcore/pull/2506) cleanup: Make TCP connection failures a warning instead of error.
+- [#2505](https://github.com/TokTok/c-toxcore/pull/2505) cleanup: Make all .c files include the headers they need.
+- [#2504](https://github.com/TokTok/c-toxcore/pull/2504) cleanup: Upgrade cppcheck, fix some warnings.
+- [#2503](https://github.com/TokTok/c-toxcore/pull/2503) cleanup: Upgrade to clang-tidy-17 and fix some warnings.
+- [#2502](https://github.com/TokTok/c-toxcore/pull/2502) chore: Use `pkg_search_module` directly in cmake.
+- [#2501](https://github.com/TokTok/c-toxcore/pull/2501) chore: Add `IMPORTED_TARGET` to pkg-config packages.
+- [#2499](https://github.com/TokTok/c-toxcore/pull/2499) cleanup: Use target_link_libraries directly in cmake.
+- [#2498](https://github.com/TokTok/c-toxcore/pull/2498) chore: Simplify msvc build using vcpkg.
+- [#2497](https://github.com/TokTok/c-toxcore/pull/2497) cleanup: Remove NaCl support.
+- [#2494](https://github.com/TokTok/c-toxcore/pull/2494) fix: unpack enum function names in event impl generator
+- [#2493](https://github.com/TokTok/c-toxcore/pull/2493) chore: Disable targets for cross-compilation.
+- [#2491](https://github.com/TokTok/c-toxcore/pull/2491) chore: Build a docker image with coverage info in it.
+- [#2490](https://github.com/TokTok/c-toxcore/pull/2490) cleanup: Some portability/warning fixes for Windows builds.
+- [#2488](https://github.com/TokTok/c-toxcore/pull/2488) fix: Correct a use-after-free and fix some memory leaks.
+- [#2487](https://github.com/TokTok/c-toxcore/pull/2487) refactor: Change all enum-like `#define` sequences into enums.
+- [#2486](https://github.com/TokTok/c-toxcore/pull/2486) refactor: Change the `TCP_PACKET_*` defines into an enum.
+- [#2485](https://github.com/TokTok/c-toxcore/pull/2485) refactor: event generation tool for reorder pr
+- [#2484](https://github.com/TokTok/c-toxcore/pull/2484) chore: Fix make_single_file to support core-only.
+- [#2481](https://github.com/TokTok/c-toxcore/pull/2481) chore: Update github actions `uses`.
+- [#2480](https://github.com/TokTok/c-toxcore/pull/2480) feat: add ngc related unpack functions
+- [#2479](https://github.com/TokTok/c-toxcore/pull/2479) feat: Add `to_string` functions for all public enums.
+- [#2477](https://github.com/TokTok/c-toxcore/pull/2477) test: add real timeout test
+- [#2476](https://github.com/TokTok/c-toxcore/pull/2476) chore: Move s390x build to post-merge.
+- [#2475](https://github.com/TokTok/c-toxcore/pull/2475) refactor: Give `enum-from-int` functions the ability to report errors.
+- [#2474](https://github.com/TokTok/c-toxcore/pull/2474) cleanup: Remove test net support.
+- [#2472](https://github.com/TokTok/c-toxcore/pull/2472) feat: Enable ubsan on bootstrap nodes.
+- [#2470](https://github.com/TokTok/c-toxcore/pull/2470) test: Add check-c run to bazel build.
+- [#2468](https://github.com/TokTok/c-toxcore/pull/2468) fix(test): tests use ipv6 by default, even with USE_IPV6 set to 0
+- [#2466](https://github.com/TokTok/c-toxcore/pull/2466) cleanup: Make group saving/loading more forgiving with data errors
+- [#2465](https://github.com/TokTok/c-toxcore/pull/2465) refactor: replace memset with a loop
+- [#2459](https://github.com/TokTok/c-toxcore/pull/2459) fix: Enable debug flag for ubsan.
+- [#2458](https://github.com/TokTok/c-toxcore/pull/2458) fix: also Install header for private/experimental API functions with autotools
+- [#2456](https://github.com/TokTok/c-toxcore/pull/2456) docs: Remove defunct IRC channel from README.md
+- [#2454](https://github.com/TokTok/c-toxcore/pull/2454) fix: memory leaks
+- [#2453](https://github.com/TokTok/c-toxcore/pull/2453) refactor: Install header for private/experimental API functions
+- [#2452](https://github.com/TokTok/c-toxcore/pull/2452) refactor: replace DEFAULT_TCP_RELAY_PORTS_COUNT with a compile-time calculation
+- [#2451](https://github.com/TokTok/c-toxcore/pull/2451) cleanup: clarify disabling of static assert checks
+- [#2449](https://github.com/TokTok/c-toxcore/pull/2449) cleanup: replace tabs with spaces
+- [#2448](https://github.com/TokTok/c-toxcore/pull/2448) feat: group connection queries now return our own connection type
+- [#2447](https://github.com/TokTok/c-toxcore/pull/2447) fix: Docker tox-bootstrapd hash update failing when using BuildKit
+- [#2446](https://github.com/TokTok/c-toxcore/pull/2446) feat: Add groupchat API function that returns an IP address string for a peer
+- [#2442](https://github.com/TokTok/c-toxcore/pull/2442) perf: Slightly reduce bandwidth usage when there are few nodes.
+- [#2439](https://github.com/TokTok/c-toxcore/pull/2439) test: Make esp32 build actually try to instantiate tox.
+- [#2438](https://github.com/TokTok/c-toxcore/pull/2438) cleanup: Remove explicit layering_check feature.
+- [#2437](https://github.com/TokTok/c-toxcore/pull/2437) chore: Upgrade sonar-scan jvm to java 17.
+- [#2436](https://github.com/TokTok/c-toxcore/pull/2436) fix: Add missing `htons` call when adding configured TCP relay.
+- [#2434](https://github.com/TokTok/c-toxcore/pull/2434) chore: Cancel old PR builds on docker and sonar-scan workflows.
+- [#2432](https://github.com/TokTok/c-toxcore/pull/2432) chore: Use C99 on MSVC instead of C11.
+- [#2430](https://github.com/TokTok/c-toxcore/pull/2430) chore: Retry freebsd tests 2 times.
+- [#2429](https://github.com/TokTok/c-toxcore/pull/2429) test: Add an s390x build (on alpine) for CI.
+- [#2428](https://github.com/TokTok/c-toxcore/pull/2428) chore: Add a compcert docker run script.
+- [#2427](https://github.com/TokTok/c-toxcore/pull/2427) cleanup: Use tcc docker image for CI.
+- [#2424](https://github.com/TokTok/c-toxcore/pull/2424) fix: Fix memory leak in the error path of loading savedata.
+- [#2420](https://github.com/TokTok/c-toxcore/pull/2420) refactor: Use Bin_Pack for packing Node_format.
+- [#2416](https://github.com/TokTok/c-toxcore/pull/2416) chore: Add more logging to loading conferences from savedata.
+- [#2415](https://github.com/TokTok/c-toxcore/pull/2415) refactor: Add a `bin_unpack_bin_max` for max-length arrays.
+- [#2414](https://github.com/TokTok/c-toxcore/pull/2414) fix: inversed return values
+- [#2413](https://github.com/TokTok/c-toxcore/pull/2413) cleanup: Fix GCC compatibility.
+- [#2408](https://github.com/TokTok/c-toxcore/pull/2408) fix: Ensure we have allocators available for the error paths.
+- [#2407](https://github.com/TokTok/c-toxcore/pull/2407) cleanup: Remove redundant `-DSODIUM_EXPORT` from definitions.
+- [#2406](https://github.com/TokTok/c-toxcore/pull/2406) cleanup: Fix a few more clang-tidy warnings.
+- [#2405](https://github.com/TokTok/c-toxcore/pull/2405) cleanup: Fix a few more clang-tidy warnings.
+- [#2404](https://github.com/TokTok/c-toxcore/pull/2404) cleanup: Enforce stricter identifier naming using clang-tidy.
+- [#2396](https://github.com/TokTok/c-toxcore/pull/2396) chore: Add devcontainer setup for codespaces.
+- [#2393](https://github.com/TokTok/c-toxcore/pull/2393) refactor: Add `mem` module to allow tests to override allocators.
+- [#2392](https://github.com/TokTok/c-toxcore/pull/2392) refactor: Make event dispatch ordered by receive time.
+- [#2391](https://github.com/TokTok/c-toxcore/pull/2391) docs: Fix doxygen config and remove some redundant comments.
+- [#2390](https://github.com/TokTok/c-toxcore/pull/2390) chore: Fix the Android CI job
+- [#2389](https://github.com/TokTok/c-toxcore/pull/2389) fix: Add missing `#include <array>`.
+- [#2388](https://github.com/TokTok/c-toxcore/pull/2388) chore: Add missing module dependencies.
+- [#2384](https://github.com/TokTok/c-toxcore/pull/2384) feat: increase NGC lossy custom packet size
+- [#2383](https://github.com/TokTok/c-toxcore/pull/2383) fix: add missing ngc constants getter declarations and definitions
+- [#2381](https://github.com/TokTok/c-toxcore/pull/2381) fix: incorrect documentation
+- [#2380](https://github.com/TokTok/c-toxcore/pull/2380) feat: allow for larger incoming NGC packets
+- [#2371](https://github.com/TokTok/c-toxcore/pull/2371) docs: fix group_peer_exit_cb
+- [#2370](https://github.com/TokTok/c-toxcore/pull/2370) fix: behaviour of group api function
+- [#2369](https://github.com/TokTok/c-toxcore/pull/2369) fix: flaky tcp test
+- [#2367](https://github.com/TokTok/c-toxcore/pull/2367) fix: fuzz support for TCP server
+- [#2364](https://github.com/TokTok/c-toxcore/pull/2364) fix: potential endless loop under extremely high load
+- [#2362](https://github.com/TokTok/c-toxcore/pull/2362) test: enable tcp relay for bootstrap fuzzing
+- [#2361](https://github.com/TokTok/c-toxcore/pull/2361) fix: resolve_bootstrap_node() not checking net_getipport() returned count correctly
+- [#2357](https://github.com/TokTok/c-toxcore/pull/2357) feat: get the number of close dht nodes with announce/store support
+- [#2355](https://github.com/TokTok/c-toxcore/pull/2355) fix: group custom packet size limits
+- [#2354](https://github.com/TokTok/c-toxcore/pull/2354) fix: DHTBootstrap should always respond to version packets with toxcore version
+- [#2351](https://github.com/TokTok/c-toxcore/pull/2351) fix: Increase max group message length by four bytes
+- [#2348](https://github.com/TokTok/c-toxcore/pull/2348) refactor: Make some improvements to how often/when we announce a group
+- [#2341](https://github.com/TokTok/c-toxcore/pull/2341) fix: #1144 by forcing misc_tools to be a static lib
+- [#2340](https://github.com/TokTok/c-toxcore/pull/2340) fix: missing net to host conversion of port in logging in group_chat.c
+- [#2339](https://github.com/TokTok/c-toxcore/pull/2339) fix: missing net to host conversion of port in logging
+- [#2338](https://github.com/TokTok/c-toxcore/pull/2338) fix: bug causing friend group invites to sometimes fail & improve logging
+- [#2333](https://github.com/TokTok/c-toxcore/pull/2333) docs: Update README for bootstrap node docker
+- [#2329](https://github.com/TokTok/c-toxcore/pull/2329) refactor: extract each case in handle packet in messenger
+- [#2327](https://github.com/TokTok/c-toxcore/pull/2327) fix: unlock correct dht_friend
+- [#2325](https://github.com/TokTok/c-toxcore/pull/2325) fix: Remove cmake cache files after copying to container build directory
+- [#2323](https://github.com/TokTok/c-toxcore/pull/2323) docs: Update README.md to include cmp submodule info
+- [#2318](https://github.com/TokTok/c-toxcore/pull/2318) chore: disable warning about pre C99 code
+- [#2317](https://github.com/TokTok/c-toxcore/pull/2317) Refactor: Extract shared key cache into separate file
+- [#2311](https://github.com/TokTok/c-toxcore/pull/2311) cleanup: make it more clear that assert and uint32_t increment both only exist if NDEBUG is not defined
+- [#2291](https://github.com/TokTok/c-toxcore/pull/2291) test: Add a protocol dump test to generate initial fuzzer input.
+- [#2271](https://github.com/TokTok/c-toxcore/pull/2271) chore: Migrate from Appveyor to Azure Pipelines
+- [#2269](https://github.com/TokTok/c-toxcore/pull/2269) feat: Merge the remainder of the new groupchats implementation
+- [#2203](https://github.com/TokTok/c-toxcore/pull/2203) refactor: Store time in Mono_Time in milliseconds.
+- [#1944](https://github.com/TokTok/c-toxcore/pull/1944) chore: tox_new() should return null when savedata loading fails
+
+### Closed issues:
+
+- [#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
+- [#2303](https://github.com/TokTok/c-toxcore/issues/2303) Add new group chats events to tox_events and tox_dispatch modules.
+- [#2302](https://github.com/TokTok/c-toxcore/issues/2302) Run strong fuzz tests against NGC
+- [#2301](https://github.com/TokTok/c-toxcore/issues/2301) Implement NGC save/load in hs-toxcore and run round-trip tests against c-toxcore
+- [#2192](https://github.com/TokTok/c-toxcore/issues/2192) Provide official signed release tarballs
+- [#2118](https://github.com/TokTok/c-toxcore/issues/2118) Add a private "get mono_time" API to `tox_private.h` and use it in auto_tests.
+- [#2029](https://github.com/TokTok/c-toxcore/issues/2029) Migrate all auto tests to the events API.
+- [#2014](https://github.com/TokTok/c-toxcore/issues/2014) Add sodium autotools CI build
+- [#1144](https://github.com/TokTok/c-toxcore/issues/1144) DHT_bootstrap should not link against misc_tools
+
+## v0.2.18
+
+### Merged PRs:
+
+- [#2300](https://github.com/TokTok/c-toxcore/pull/2300) chore: Release 0.2.18
+- [#2299](https://github.com/TokTok/c-toxcore/pull/2299) fix: remove the assert because buffer can be larger than UINT16_MAX.
+- [#2297](https://github.com/TokTok/c-toxcore/pull/2297) cleanup: remove unused field last_seen from Onion_Friend
+- [#2289](https://github.com/TokTok/c-toxcore/pull/2289) test: Add a Null_System used in toxsave_harness.
+- [#2288](https://github.com/TokTok/c-toxcore/pull/2288) test: enable additional sanitizers for fuzzing
+- [#2287](https://github.com/TokTok/c-toxcore/pull/2287) fix: Don't allow onion paths to be built from real friends.
+- [#2285](https://github.com/TokTok/c-toxcore/pull/2285) test: Don't abort fuzz test when tox_new fails.
+- [#2284](https://github.com/TokTok/c-toxcore/pull/2284) refactor: Move crypto utilities from util to crypto_core.
+- [#2283](https://github.com/TokTok/c-toxcore/pull/2283) fix: Allow onion paths to be built from more random nodes.
+- [#2282](https://github.com/TokTok/c-toxcore/pull/2282) fix: Fix potential array out-of-bounds in DHT onion path building.
+- [#2281](https://github.com/TokTok/c-toxcore/pull/2281) cleanup: Avoid goto in msi.c.
+- [#2280](https://github.com/TokTok/c-toxcore/pull/2280) test: Improve test hermeticity by using local TCP relay.
+- [#2279](https://github.com/TokTok/c-toxcore/pull/2279) test: Enable fuzzing for TCP.
+- [#2277](https://github.com/TokTok/c-toxcore/pull/2277) refactor: Avoid `static_cast` in `Fuzz_System` functions.
+- [#2275](https://github.com/TokTok/c-toxcore/pull/2275) chore: Downgrade C++ version to 17
+- [#2273](https://github.com/TokTok/c-toxcore/pull/2273) fix: Really fix overrun added in e49a477a
+- [#2272](https://github.com/TokTok/c-toxcore/pull/2272) fix: Add missing return on error
+- [#2270](https://github.com/TokTok/c-toxcore/pull/2270) test: Improve error messages in toxav_basic_test.
+- [#2266](https://github.com/TokTok/c-toxcore/pull/2266) fix: Fixed leak and overrun added in e49a477a
+- [#2263](https://github.com/TokTok/c-toxcore/pull/2263) chore: Upgrade to C++20 in CMake build.
+- [#2261](https://github.com/TokTok/c-toxcore/pull/2261) refactor: Protect array unpacking against invalid lengths.
+- [#2258](https://github.com/TokTok/c-toxcore/pull/2258) refactor: Rename announce functions into their own namespace.
+- [#2257](https://github.com/TokTok/c-toxcore/pull/2257) fix: Format IP as string again in error log.
+- [#2255](https://github.com/TokTok/c-toxcore/pull/2255) fix: Fix a stack overflow triggered by small DHT packets.
+- [#2251](https://github.com/TokTok/c-toxcore/pull/2251) chore: Add MISRA-2012 check using cppcheck's misra addon.
+- [#2250](https://github.com/TokTok/c-toxcore/pull/2250) cleanup: remove populate_path_nodes_tcp
+- [#2249](https://github.com/TokTok/c-toxcore/pull/2249) test: Improve stability of forwarding_test.
+- [#2248](https://github.com/TokTok/c-toxcore/pull/2248) refactor: Use a struct for the `ip_ntoa` buffer.
+- [#2246](https://github.com/TokTok/c-toxcore/pull/2246) fix: Don't crash if RNG init failed.
+- [#2244](https://github.com/TokTok/c-toxcore/pull/2244) refactor: Allow NULL logger; make it no-op in NDEBUG.
+- [#2243](https://github.com/TokTok/c-toxcore/pull/2243) chore: Add initial ESP32 docker build.
+- [#2242](https://github.com/TokTok/c-toxcore/pull/2242) cleanup: Use `static_assert` instead of `assert` where possible.
+- [#2240](https://github.com/TokTok/c-toxcore/pull/2240) chore(deps): Use upstream cmp directly instead of our fork.
+- [#2238](https://github.com/TokTok/c-toxcore/pull/2238) cleanup: Make `*_free` and `kill_*` functions nullable.
+- [#2236](https://github.com/TokTok/c-toxcore/pull/2236) chore: Add dependabot config.
+- [#2234](https://github.com/TokTok/c-toxcore/pull/2234) test: Add more functionality to the bootstrap fuzz harness.
+- [#2233](https://github.com/TokTok/c-toxcore/pull/2233) cleanup: Replace a series of `if` statements with a `switch`.
+- [#2232](https://github.com/TokTok/c-toxcore/pull/2232) test: Add fuzzer support functions for internal toxcore objects.
+- [#2230](https://github.com/TokTok/c-toxcore/pull/2230) feat: Merge group announce portion of new groupchats implementation
+- [#2229](https://github.com/TokTok/c-toxcore/pull/2229) cleanup: Remove layers in the cmake build.
+- [#2228](https://github.com/TokTok/c-toxcore/pull/2228) chore: Fix path to fuzzer binaries in clusterfuzz build.
+- [#2227](https://github.com/TokTok/c-toxcore/pull/2227) cleanup: Disallow stack frames of over 9000 bytes.
+- [#2225](https://github.com/TokTok/c-toxcore/pull/2225) fix: fix typo in git command in INSTALL.md
+- [#2224](https://github.com/TokTok/c-toxcore/pull/2224) cleanup: Add include for assert.h for the fuzzing build.
+- [#2223](https://github.com/TokTok/c-toxcore/pull/2223) chore: Add `uint8_t` version of `bin_pack` for numbers.
+- [#2219](https://github.com/TokTok/c-toxcore/pull/2219) refactor: Rename bin_pack/unpack functions the same as cmp funcs.
+- [#2217](https://github.com/TokTok/c-toxcore/pull/2217) cleanup: Add Network object parameter for addr_resolve.
+- [#2214](https://github.com/TokTok/c-toxcore/pull/2214) cleanup: Remove all uses of `TOX_*_MAX_SIZE` macros.
+- [#2213](https://github.com/TokTok/c-toxcore/pull/2213) cleanup: Remove unused random_testing program.
+- [#2212](https://github.com/TokTok/c-toxcore/pull/2212) cleanup: Expand `CONST_FUNCTION` and remove the macro.
+- [#2211](https://github.com/TokTok/c-toxcore/pull/2211) cleanup: Move definitions of tox_private.h functions to tox_private.c.
+- [#2210](https://github.com/TokTok/c-toxcore/pull/2210) chore: Clone submodules in clusterfuzzlite Dockerfile.
+- [#2208](https://github.com/TokTok/c-toxcore/pull/2208) chore: Remove valgrind build.
+- [#2206](https://github.com/TokTok/c-toxcore/pull/2206) feat: Allow overriding mono_time in tox_new.
+- [#2204](https://github.com/TokTok/c-toxcore/pull/2204) chore: Support producing shared libraries on Windows
+- [#2202](https://github.com/TokTok/c-toxcore/pull/2202) cleanup: Avoid name clash between struct field and function.
+- [#2201](https://github.com/TokTok/c-toxcore/pull/2201) docs: Add information regarding git submodules, cmp to INSTALL.md
+- [#2200](https://github.com/TokTok/c-toxcore/pull/2200) cleanup: Add more null checks in `tox_new`.
+- [#2199](https://github.com/TokTok/c-toxcore/pull/2199) cleanup: Mark Mono_Time const where possible.
+- [#2196](https://github.com/TokTok/c-toxcore/pull/2196) test: Remove save_load_test from autotools build.
+- [#2195](https://github.com/TokTok/c-toxcore/pull/2195) fix: Correct calculation of packet sent time
+- [#2193](https://github.com/TokTok/c-toxcore/pull/2193) perf: Make time move a lot faster in fuzzing runs.
+- [#2190](https://github.com/TokTok/c-toxcore/pull/2190) feat: Add support for custom random number generator.
+- [#2189](https://github.com/TokTok/c-toxcore/pull/2189) chore: Add third_party to toxcore-sources docker image.
+- [#2188](https://github.com/TokTok/c-toxcore/pull/2188) cleanup: Make addr_resolve a private function.
+- [#2187](https://github.com/TokTok/c-toxcore/pull/2187) test: Add DHT and tox_events fuzz tests to the cmake build.
+- [#2186](https://github.com/TokTok/c-toxcore/pull/2186) cleanup: Use `_Static_assert` in gcc/clang.
+- [#2184](https://github.com/TokTok/c-toxcore/pull/2184) test: Add some support functions to make writing fuzzers easier.
+- [#2183](https://github.com/TokTok/c-toxcore/pull/2183) test: Enable more tests for msan.
+- [#2182](https://github.com/TokTok/c-toxcore/pull/2182) test: Improve stability of tox_many_tcp_test.
+- [#2177](https://github.com/TokTok/c-toxcore/pull/2177) feat: Add support for overriding network functions.
+- [#2176](https://github.com/TokTok/c-toxcore/pull/2176) test: try to save the fuzzed save file again
+- [#2175](https://github.com/TokTok/c-toxcore/pull/2175) refactor: Use cmp instead of msgpack-c for events packing.
+- [#2173](https://github.com/TokTok/c-toxcore/pull/2173) chore: Use "master" as the branch in toktok-fuzzer.
+- [#2170](https://github.com/TokTok/c-toxcore/pull/2170) test: Add fuzzer tests to the bazel build.
+- [#2169](https://github.com/TokTok/c-toxcore/pull/2169) feat: Merge moderation portion of new groupchats codebase
+- [#2167](https://github.com/TokTok/c-toxcore/pull/2167) cleanup: Reduce scope of array-typed variables where possible.
+- [#2166](https://github.com/TokTok/c-toxcore/pull/2166) cleanup: Reduce scope of variables as requested by cimple.
+- [#2164](https://github.com/TokTok/c-toxcore/pull/2164) feat: Merge onion_announce changes from new groupchats fork
+- [#2163](https://github.com/TokTok/c-toxcore/pull/2163) chore: Enable memory sanitizer build.
+- [#2160](https://github.com/TokTok/c-toxcore/pull/2160) test: Improve the stability of the save_load test
+- [#2159](https://github.com/TokTok/c-toxcore/pull/2159) chore: Update the Appveyor build to VS2019 to work around conan issues
+- [#2158](https://github.com/TokTok/c-toxcore/pull/2158) cleanup: Expose `struct Tox` to internal code.
+- [#2157](https://github.com/TokTok/c-toxcore/pull/2157) cleanup: Split the huge TCP client packet handler.
+- [#2156](https://github.com/TokTok/c-toxcore/pull/2156) cleanup: Sync doc comments between .h and .c files.
+- [#2155](https://github.com/TokTok/c-toxcore/pull/2155) fix: Eliminate memory leak in toxav.
+- [#2154](https://github.com/TokTok/c-toxcore/pull/2154) test: Speed up toxav_many_test by using fake mono_time.
+- [#2153](https://github.com/TokTok/c-toxcore/pull/2153) docs: Put all the tox public api into a fake "tox" namespace.
+- [#2150](https://github.com/TokTok/c-toxcore/pull/2150) cleanup: Move all the group.h structs into group.c.
+- [#2149](https://github.com/TokTok/c-toxcore/pull/2149) cleanup: Avoid `memset` on structs.
+- [#2147](https://github.com/TokTok/c-toxcore/pull/2147) feat: Store announcements
+- [#2146](https://github.com/TokTok/c-toxcore/pull/2146) chore: Add testing/Dockerfile to the CI build.
+- [#2145](https://github.com/TokTok/c-toxcore/pull/2145) chore: Be even more explicit about integer range bounds.
+- [#2144](https://github.com/TokTok/c-toxcore/pull/2144) cleanup: Minor cleanups in TCP_connection.c.
+- [#2143](https://github.com/TokTok/c-toxcore/pull/2143) fix: Allow port range in DHT_bootstrap.c.
+- [#2142](https://github.com/TokTok/c-toxcore/pull/2142) cleanup: Count re-adding an existing bootstrap node as success.
+- [#2141](https://github.com/TokTok/c-toxcore/pull/2141) cleanup: Disable LAN discovery in TCP-only mode.
+- [#2140](https://github.com/TokTok/c-toxcore/pull/2140) cleanup: Add assertion for decrypted data length.
+- [#2101](https://github.com/TokTok/c-toxcore/pull/2101) cleanup: improve CMakeLists.txt structure
+- [#2100](https://github.com/TokTok/c-toxcore/pull/2100) chore: remove cpufeatures.c
+- [#2098](https://github.com/TokTok/c-toxcore/pull/2098) chore: remove DHT_test.c since it's unused
+
+### Closed issues:
+
+- [#2298](https://github.com/TokTok/c-toxcore/issues/2298) assert makes incorrect assumption
+- [#2256](https://github.com/TokTok/c-toxcore/issues/2256) New Defects reported by Coverity Scan for TokTok/c-toxcore
+- [#2109](https://github.com/TokTok/c-toxcore/issues/2109) Assimilate `messenger_test.c`: replace with public API test
+- [#2012](https://github.com/TokTok/c-toxcore/issues/2012) Support building a DLL on Windows
+- [#907](https://github.com/TokTok/c-toxcore/issues/907) use dll abnormal System.AccessViolationException win7 x32 but x64 no problem
+
+## v0.2.17
+
+### Merged PRs:
+
+- [#2138](https://github.com/TokTok/c-toxcore/pull/2138) chore: Release 0.2.17
+- [#2136](https://github.com/TokTok/c-toxcore/pull/2136) docs: Clean up doxygen comments to be more doxygen-like.
+- [#2135](https://github.com/TokTok/c-toxcore/pull/2135) cleanup: Move test-only functions into tests.
+- [#2134](https://github.com/TokTok/c-toxcore/pull/2134) cleanup: Add explicit callback setters for MSI callbacks.
+- [#2133](https://github.com/TokTok/c-toxcore/pull/2133) cleanup: Remove redundant Messenger and DHT tests.
+- [#2132](https://github.com/TokTok/c-toxcore/pull/2132) cleanup: Remove dependency from LAN_discovery onto DHT.
+- [#2131](https://github.com/TokTok/c-toxcore/pull/2131) cleanup: Split util.c out of the network library.
+- [#2130](https://github.com/TokTok/c-toxcore/pull/2130) cleanup: Remove redundant `()` around `return` expression.
+- [#2128](https://github.com/TokTok/c-toxcore/pull/2128) test: Add unit test for create/handle request packets.
+- [#2127](https://github.com/TokTok/c-toxcore/pull/2127) cleanup: Remove `EAGAIN` from the list of ignored errors.
+- [#2126](https://github.com/TokTok/c-toxcore/pull/2126) cleanup: Remove port from `Broadcast_Info`.
+- [#2125](https://github.com/TokTok/c-toxcore/pull/2125) cleanup: Don't reference local variables in macro bodies.
+- [#2123](https://github.com/TokTok/c-toxcore/pull/2123) cleanup: Remove some more implicit bool conversions.
+- [#2122](https://github.com/TokTok/c-toxcore/pull/2122) chore: Enable a bunch more warnings in GCC builds.
+- [#2120](https://github.com/TokTok/c-toxcore/pull/2120) cleanup: Remove all boolean-int conversions.
+- [#2117](https://github.com/TokTok/c-toxcore/pull/2117) cleanup: Comply with strict include ordering.
+- [#2116](https://github.com/TokTok/c-toxcore/pull/2116) cleanup: Remove more boolean conversions (and a bugfix).
+- [#2115](https://github.com/TokTok/c-toxcore/pull/2115) cleanup: Log at ERROR level when `connect()` fails.
+- [#2114](https://github.com/TokTok/c-toxcore/pull/2114) cleanup: Avoid creating invalid enum values.
+- [#2113](https://github.com/TokTok/c-toxcore/pull/2113) cleanup: Remove superfluous parentheses on the rhs of assignments.
+- [#2108](https://github.com/TokTok/c-toxcore/pull/2108) test: Add mallocfail and proxy test to our coverage runs.
+- [#2106](https://github.com/TokTok/c-toxcore/pull/2106) test: Add test coverage docker build for local tests.
+- [#2105](https://github.com/TokTok/c-toxcore/pull/2105) cleanup: Change valid status of onion friend to bool.
+- [#2104](https://github.com/TokTok/c-toxcore/pull/2104) fix: Report failure to DHT bootstrap back to the client.
+- [#2103](https://github.com/TokTok/c-toxcore/pull/2103) cleanup: Remove more implicit bool conversions.
+- [#2102](https://github.com/TokTok/c-toxcore/pull/2102) cleanup: Mark all local non-pointers as const where possible.
+- [#2099](https://github.com/TokTok/c-toxcore/pull/2099) cleanup: Reduce name shadowing; remove ptr-to-bool conversions.
+- [#2097](https://github.com/TokTok/c-toxcore/pull/2097) cleanup: Remove implicit conversions from `uint32_t` to `bool`.
+- [#2096](https://github.com/TokTok/c-toxcore/pull/2096) cleanup: Return boolean constants, not ints from bool functions.
+- [#2094](https://github.com/TokTok/c-toxcore/pull/2094) fix: Null function pointer dereference.
+- [#2093](https://github.com/TokTok/c-toxcore/pull/2093) cleanup: Remove any disallowed casts.
+- [#2092](https://github.com/TokTok/c-toxcore/pull/2092) perf: fix issue with friend finding taking too long after disconnects.
+- [#2091](https://github.com/TokTok/c-toxcore/pull/2091) cleanup: Avoid casting function pointers.
+- [#2090](https://github.com/TokTok/c-toxcore/pull/2090) refactor: Move `tox_new_log` to `auto_test_support`.
+- [#2088](https://github.com/TokTok/c-toxcore/pull/2088) cleanup: Remove all implicit bool conversions in if-conditions.
+- [#2086](https://github.com/TokTok/c-toxcore/pull/2086) cleanup: Enable most cppcheck warnings as errors.
+- [#2084](https://github.com/TokTok/c-toxcore/pull/2084) fix: out-of-memory condition by corrupted save file
+- [#2079](https://github.com/TokTok/c-toxcore/pull/2079) cleanup: Remove unused execution trace library.
+- [#2078](https://github.com/TokTok/c-toxcore/pull/2078) perf: Refactor onion_client.c do_friends() to reduce network traffic
+- [#2075](https://github.com/TokTok/c-toxcore/pull/2075) chore: Add a .clang-format that mostly agrees with astyle.
+- [#2074](https://github.com/TokTok/c-toxcore/pull/2074) chore: Make coverity scan a nightly job.
+- [#2073](https://github.com/TokTok/c-toxcore/pull/2073) chore: Fix build-args in win32/win64 docker build.
+- [#2072](https://github.com/TokTok/c-toxcore/pull/2072) chore: Simplify and speed up windows builds using docker image.
+- [#2070](https://github.com/TokTok/c-toxcore/pull/2070) chore: Add docker image builds for windows cross compiler.
+- [#2064](https://github.com/TokTok/c-toxcore/pull/2064) fix: toxsave memory leak while loading groups
+
+### Closed issues:
+
+- [#2121](https://github.com/TokTok/c-toxcore/issues/2121) Improve speed and stability of LAN discovery test
+- [#2083](https://github.com/TokTok/c-toxcore/issues/2083) Tox save file format/loader doesn't limit or check the number of frozen peers
+- [#2080](https://github.com/TokTok/c-toxcore/issues/2080) speedup getting online after tox process has been suspended
+- [#2050](https://github.com/TokTok/c-toxcore/issues/2050) Excessive onion friend lookups
+- [#2034](https://github.com/TokTok/c-toxcore/issues/2034) Make coverity-scan workflow a nightly build instead of on master push
+- [#2000](https://github.com/TokTok/c-toxcore/issues/2000) Move win32 docker image build out to dockerfiles
+- [#1990](https://github.com/TokTok/c-toxcore/issues/1990) Add a .clang-format config that matches the astyle config as closely as possible.
+- [#1115](https://github.com/TokTok/c-toxcore/issues/1115) Add empty handler for LAN discovery packets when LAN discovery is disabled
+- [#647](https://github.com/TokTok/c-toxcore/issues/647) `tox_bootstrap` should return an error on unrecoverable `getnodes` failure
+- [#169](https://github.com/TokTok/c-toxcore/issues/169) Get rid of TOX_USER_STATUS_BUSY + 1
+
## v0.2.16
### Merged PRs:
+- [#2071](https://github.com/TokTok/c-toxcore/pull/2071) chore: Release 0.2.16
- [#2069](https://github.com/TokTok/c-toxcore/pull/2069) chore: Simplify and speed up nacl build using toxchat/nacl.
- [#2066](https://github.com/TokTok/c-toxcore/pull/2066) test: Add a profiling script and Dockerfile.
- [#2058](https://github.com/TokTok/c-toxcore/pull/2058) fix: properly deallocate frozen peers
diff --git a/protocols/Tox/libtox/docs/LICENSE b/protocols/Tox/libtox/docs/LICENSE
index 10926e87f1..f288702d2f 100644
--- a/protocols/Tox/libtox/docs/LICENSE
+++ b/protocols/Tox/libtox/docs/LICENSE
@@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
@@ -664,12 +664,11 @@ might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
+<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
-
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/protocols/Tox/libtox/docs/README.md b/protocols/Tox/libtox/docs/README.md
index 847ec7cd6f..e7a2b6ba60 100644
--- a/protocols/Tox/libtox/docs/README.md
+++ b/protocols/Tox/libtox/docs/README.md
@@ -1,44 +1,55 @@
# ![Project Tox](https://raw.github.com/TokTok/c-toxcore/master/other/tox.png "Project Tox")
-**Current Coverage:** [![coverage](https://codecov.io/gh/TokTok/c-toxcore/branch/master/graph/badge.svg?token=BRfCKo02De)](https://codecov.io/gh/TokTok/c-toxcore)
+**Current Coverage:**
+[![coverage](https://codecov.io/gh/TokTok/c-toxcore/branch/master/graph/badge.svg?token=BRfCKo02De)](https://codecov.io/gh/TokTok/c-toxcore)
-[**Website**](https://tox.chat) **|** [**Wiki**](https://wiki.tox.chat/) **|** [**Blog**](https://blog.tox.chat/) **|** [**FAQ**](https://wiki.tox.chat/doku.php?id=users:faq) **|** [**Binaries/Downloads**](https://tox.chat/download.html) **|** [**Clients**](https://wiki.tox.chat/doku.php?id=clients) **|** [**Compiling**](/INSTALL.md)
-
-**IRC Channels:** Users: [#tox@libera.chat](https://web.libera.chat/#tox), Developers: [#toktok@libera.chat](https://web.libera.chat/#toktok)
+[**Website**](https://tox.chat) **|** [**Wiki**](https://wiki.tox.chat/) **|**
+[**Blog**](https://blog.tox.chat/) **|**
+[**FAQ**](https://wiki.tox.chat/doku.php?id=users:faq) **|**
+[**Binaries/Downloads**](https://tox.chat/download.html) **|**
+[**Clients**](https://wiki.tox.chat/doku.php?id=clients) **|**
+[**Compiling**](/INSTALL.md)
## What is Tox
Tox is a peer to peer (serverless) instant messenger aimed at making security
and privacy easy to obtain for regular users. It uses
-[NaCl](https://nacl.cr.yp.to/) for its encryption and authentication.
+[libsodium](https://doc.libsodium.org/) (based on
+[NaCl](https://nacl.cr.yp.to/)) for its encryption and authentication.
## IMPORTANT!
### ![Danger: Experimental](other/tox-warning.png)
This is an **experimental** cryptographic network library. It has not been
-formally audited by an independent third party that specializes in
-cryptography or cryptanalysis. **Use this library at your own risk.**
+formally audited by an independent third party that specializes in cryptography
+or cryptanalysis. **Use this library at your own risk.**
-The underlying crypto library [NaCl](https://nacl.cr.yp.to/install.html)
-provides reliable encryption, but the security model has not yet been fully
-specified. See [issue 210](https://github.com/TokTok/c-toxcore/issues/210) for
-a discussion on developing a threat model. See other issues for known
-weaknesses (e.g. [issue 426](https://github.com/TokTok/c-toxcore/issues/426)
-describes what can happen if your secret key is stolen).
+The underlying crypto library [libsodium](https://doc.libsodium.org/) provides
+reliable encryption, but the security model has not yet been fully specified.
+See [issue 210](https://github.com/TokTok/c-toxcore/issues/210) for a discussion
+on developing a threat model. See other issues for known weaknesses (e.g.
+[issue 426](https://github.com/TokTok/c-toxcore/issues/426) describes what can
+happen if your secret key is stolen).
## Toxcore Development Roadmap
-The roadmap and changelog are generated from GitHub issues. You may view them
-on the website, where they are updated at least once every 24 hours:
+The roadmap and changelog are generated from GitHub issues. You may view them on
+the website, where they are updated at least once every 24 hours:
-- Changelog: https://toktok.ltd/changelog/c-toxcore
-- Roadmap: https://toktok.ltd/roadmap/c-toxcore
+- Changelog: https://toktok.ltd/changelog/c-toxcore
+- Roadmap: https://toktok.ltd/roadmap/c-toxcore
## Installing toxcore
Detailed installation instructions can be found in [INSTALL.md](INSTALL.md).
+Be advised that due to the addition of `cmp` as a submodule, you now also need
+to initialize the git submodules required by toxcore. This can be done by
+cloning the repo with the following command:
+`git clone --recurse-submodules https://github.com/Toktok/c-toxcore` or by
+running `git submodule update --init` in the root directory of the repo.
+
In a nutshell, if you have [libsodium](https://github.com/jedisct1/libsodium)
installed, run:
@@ -73,17 +84,17 @@ if (err_new != TOX_ERR_NEW_OK) {
}
```
-Here, we simply exit the program, but in a real client you will probably want
-to do some error handling and proper error reporting to the user. The `NULL`
+Here, we simply exit the program, but in a real client you will probably want to
+do some error handling and proper error reporting to the user. The `NULL`
argument given to the first parameter of `tox_new` is the `Tox_Options`. It
-contains various write-once network settings and allows you to load a
-previously serialised instance. See [toxcore/tox.h](tox.h) for details.
+contains various write-once network settings and allows you to load a previously
+serialised instance. See [toxcore/tox.h](tox.h) for details.
### Setting up callbacks
-Toxcore works with callbacks that you can register to listen for certain
-events. Examples of such events are "friend request received" or "friend sent
-a message". Search the API for `tox_callback_*` to find all of them.
+Toxcore works with callbacks that you can register to listen for certain events.
+Examples of such events are "friend request received" or "friend sent a
+message". Search the API for `tox_callback_*` to find all of them.
Here, we will set up callbacks for receiving friend requests and receiving
messages. We will always accept any friend request (because we're a bot), and
@@ -171,3 +182,24 @@ the API documentation in [toxcore/tox.h](toxcore/tox.h) for more information.
- [Another echo bot](https://wiki.tox.chat/developers/client_examples/echo_bot)
- [minitox](https://github.com/hqwrong/minitox) (A minimal tox client)
+
+## SAST Tools
+
+This project uses various tools supporting Static Application Security Testing:
+
+- [clang-tidy](https://clang.llvm.org/extra/clang-tidy/): A clang-based C++
+ "linter" tool.
+- [Coverity](https://scan.coverity.com/): A cloud-based static analyzer service
+ for Java, C/C++, C#, JavaScript, Ruby, or Python that is free for open source
+ projects.
+- [cppcheck](https://cppcheck.sourceforge.io/): A static analyzer for C/C++
+ code.
+- [cpplint](https://github.com/cpplint/cpplint): Static code checker for C++
+- [goblint](https://goblint.in.tum.de/): A static analyzer for multi-threaded C
+ programs, specializing in finding concurrency bugs.
+- [infer](https://github.com/facebook/infer): A static analyzer for Java, C,
+ C++, and Objective-C.
+- [PVS-Studio](https://pvs-studio.com/en/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source):
+ A static analyzer for C, C++, C#, and Java code.
+- [tokstyle](https://github.com/TokTok/hs-tokstyle): A style checker for TokTok
+ C projects.
diff --git a/protocols/Tox/libtox/libtox.vcxproj b/protocols/Tox/libtox/libtox.vcxproj
index 4c86a4fef8..4700e878cb 100644
--- a/protocols/Tox/libtox/libtox.vcxproj
+++ b/protocols/Tox/libtox/libtox.vcxproj
@@ -181,6 +181,9 @@
<ClCompile Include="src\toxcore\net_crypto.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
+ <ClCompile Include="src\toxcore\net_profile.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
<ClCompile Include="src\toxcore\onion.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
@@ -199,6 +202,9 @@
<ClCompile Include="src\toxcore\shared_key_cache.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
+ <ClCompile Include="src\toxcore\sort.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
<ClCompile Include="src\toxcore\state.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
@@ -229,6 +235,12 @@
<ClCompile Include="src\toxcore\tox_events.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
+ <ClCompile Include="src\toxcore\tox_log_level.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\toxcore\tox_options.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
<ClCompile Include="src\toxcore\tox_private.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
@@ -265,11 +277,13 @@
<ClInclude Include="src\toxcore\mono_time.h" />
<ClInclude Include="src\toxcore\network.h" />
<ClInclude Include="src\toxcore\net_crypto.h" />
+ <ClInclude Include="src\toxcore\net_profile.h" />
<ClInclude Include="src\toxcore\onion.h" />
<ClInclude Include="src\toxcore\onion_announce.h" />
<ClInclude Include="src\toxcore\onion_client.h" />
<ClInclude Include="src\toxcore\ping.h" />
<ClInclude Include="src\toxcore\ping_array.h" />
+ <ClInclude Include="src\toxcore\sort.h" />
<ClInclude Include="src\toxcore\state.h" />
<ClInclude Include="src\toxcore\TCP_client.h" />
<ClInclude Include="src\toxcore\TCP_common.h" />
@@ -279,6 +293,8 @@
<ClInclude Include="src\toxcore\tox.h" />
<ClInclude Include="src\toxcore\tox_dispatch.h" />
<ClInclude Include="src\toxcore\tox_events.h" />
+ <ClInclude Include="src\toxcore\tox_log_level.h" />
+ <ClInclude Include="src\toxcore\tox_options.h" />
<ClInclude Include="src\toxcore\tox_private.h" />
<ClInclude Include="src\toxcore\tox_struct.h" />
<ClInclude Include="src\toxcore\tox_unpack.h" />
diff --git a/protocols/Tox/libtox/libtox.vcxproj.filters b/protocols/Tox/libtox/libtox.vcxproj.filters
index fd34edfa20..ed210dca74 100644
--- a/protocols/Tox/libtox/libtox.vcxproj.filters
+++ b/protocols/Tox/libtox/libtox.vcxproj.filters
@@ -216,6 +216,18 @@
<ClCompile Include="src\toxcore\crypto_core_pack.c">
<Filter>Source Files\toxcore</Filter>
</ClCompile>
+ <ClCompile Include="src\toxcore\net_profile.c">
+ <Filter>Source Files\toxcore</Filter>
+ </ClCompile>
+ <ClCompile Include="src\toxcore\sort.c">
+ <Filter>Source Files\toxcore</Filter>
+ </ClCompile>
+ <ClCompile Include="src\toxcore\tox_log_level.c">
+ <Filter>Source Files\toxcore</Filter>
+ </ClCompile>
+ <ClCompile Include="src\toxcore\tox_options.c">
+ <Filter>Source Files\toxcore</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\toxcore\announce.h">
@@ -344,6 +356,18 @@
<ClInclude Include="src\toxcore\crypto_core_pack.h">
<Filter>Source Files\toxcore</Filter>
</ClInclude>
+ <ClInclude Include="src\toxcore\net_profile.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\toxcore\sort.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\toxcore\tox_log_level.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\toxcore\tox_options.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<Import Project="$(ProjectDir)..\..\..\build\vc.common\common.filters" />
</Project> \ No newline at end of file
diff --git a/protocols/Tox/libtox/src/third_party/cmp/cmp.c b/protocols/Tox/libtox/src/third_party/cmp/cmp.c
index c312efd6c7..c11d23a8a3 100644
--- a/protocols/Tox/libtox/src/third_party/cmp/cmp.c
+++ b/protocols/Tox/libtox/src/third_party/cmp/cmp.c
@@ -865,7 +865,7 @@ bool cmp_write_pfix(cmp_ctx_t *ctx, uint8_t c) {
}
bool cmp_write_nfix(cmp_ctx_t *ctx, int8_t c) {
- if (c >= -32 && c <= -1)
+ if (c >= -0x20 && c <= -1)
return write_fixed_value(ctx, (uint8_t)c);
ctx->error = CMP_ERROR_INPUT_VALUE_TOO_LARGE;
@@ -875,7 +875,7 @@ bool cmp_write_nfix(cmp_ctx_t *ctx, int8_t c) {
bool cmp_write_sfix(cmp_ctx_t *ctx, int8_t c) {
if (c >= 0)
return cmp_write_pfix(ctx, (uint8_t)c);
- if (c >= -32 && c <= -1)
+ if (c >= -0x20 && c <= -1)
return cmp_write_nfix(ctx, c);
ctx->error = CMP_ERROR_INPUT_VALUE_TOO_LARGE;
diff --git a/protocols/Tox/libtox/src/toxcore/DHT.c b/protocols/Tox/libtox/src/toxcore/DHT.c
index 2567d1b5a8..0dc49008e4 100644
--- a/protocols/Tox/libtox/src/toxcore/DHT.c
+++ b/protocols/Tox/libtox/src/toxcore/DHT.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -9,7 +9,6 @@
#include "DHT.h"
#include <assert.h>
-#include <stdlib.h>
#include <string.h>
#include "LAN_discovery.h"
@@ -24,13 +23,15 @@
#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)
-/** Ping interval in seconds for each random sending of a get nodes request. */
-#define GET_NODE_INTERVAL 20
+/** Ping interval in seconds for each random sending of a nodes request. */
+#define NODES_REQUEST_INTERVAL 20
#define MAX_PUNCHING_PORTS 48
@@ -45,7 +46,7 @@
#define NAT_PING_REQUEST 0
#define NAT_PING_RESPONSE 1
-/** Number of get node requests to send to quickly find close nodes. */
+/** Number of node requests to send to quickly find close nodes. */
#define MAX_BOOTSTRAP_TIMES 5
// TODO(sudden6): find out why we need multiple callbacks and if we really need 32
@@ -65,9 +66,9 @@ struct DHT_Friend {
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
Client_data client_list[MAX_FRIEND_CLIENTS];
- /* Time at which the last get_nodes request was sent. */
- uint64_t lastgetnode;
- /* number of times get_node packets were sent. */
+ /* Time at which the last nodes request was sent. */
+ uint64_t last_nodes_request;
+ /* number of times nodes request packets were sent. */
uint32_t bootstrap_times;
/* Symmetric NAT hole punching stuff. */
@@ -103,7 +104,7 @@ struct DHT {
bool lan_discovery_enabled;
Client_data close_clientlist[LCLIENT_LIST];
- uint64_t close_lastgetnodes;
+ uint64_t close_last_nodes_request;
uint32_t close_bootstrap_times;
/* DHT keypair */
@@ -129,7 +130,7 @@ struct DHT {
Node_format to_bootstrap[MAX_CLOSE_TO_BOOTSTRAP_NODES];
unsigned int num_to_bootstrap;
- dht_get_nodes_response_cb *get_nodes_response;
+ dht_nodes_response_cb *nodes_response_callback;
};
const uint8_t *dht_friend_public_key(const DHT_Friend *dht_friend)
@@ -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;
}
@@ -430,7 +431,7 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed
const int ipp_size = unpack_ip_port(&nodes[num].ip_port, data + len_processed, length - len_processed, tcp_enabled);
if (ipp_size == -1) {
- return -1;
+ break;
}
len_processed += ipp_size;
@@ -449,6 +450,10 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed
#endif /* NDEBUG */
}
+ if (num == 0 && max_num_nodes > 0 && length > 0) {
+ return -1;
+ }
+
if (processed_data_len != nullptr) {
*processed_data_len = len_processed;
}
@@ -707,7 +712,7 @@ static void get_close_nodes_inner(
}
/**
- * Find MAX_SENT_NODES nodes closest to the public_key for the send nodes request:
+ * Find MAX_SENT_NODES nodes closest to the public_key for the nodes request:
* put them in the nodes_list and return how many were found.
*
* want_announce: return only nodes which implement the dht announcements protocol.
@@ -755,49 +760,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 +832,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 +876,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 void sort_client_list(const Memory *mem, Client_data *list, uint64_t cur_time, unsigned int length,
- const uint8_t *comp_public_key)
+static int client_data_cmp(const Client_data_Cmp *cmp, const Client_data *entry1, const Client_data *entry2)
{
- // Pass comp_public_key to qsort 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 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 (cmp_list == nullptr) {
- return;
+ if (t1 && t2) {
+ return 0;
}
- 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];
+ if (t1) {
+ return -1;
+ }
+
+ if (t2) {
+ return 1;
}
- qsort(cmp_list, length, sizeof(DHT_Cmp_Data), dht_cmp_entry);
+ const int closest = id_closest(cmp->comp_public_key, entry1->public_key, entry2->public_key);
- for (uint32_t i = 0; i < length; ++i) {
- list[i] = cmp_list[i].entry;
+ if (closest == 1) {
+ return 1;
}
- mem_delete(mem, cmp_list);
+ 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 merge_sort with each Client_data entry, so the
+ // comparison function can use it as the base of comparison.
+ const Client_data_Cmp cmp = {
+ mem,
+ cur_time,
+ comp_public_key,
+ };
+
+ merge_sort(list, length, &cmp, &client_data_cmp_funcs);
}
non_null()
@@ -1087,7 +1135,7 @@ static bool is_pk_in_close_list(const DHT *dht, const uint8_t *public_key, const
ip_port);
}
-/** @brief Check if the node obtained with a get_nodes with public_key should be pinged.
+/** @brief Check if the node obtained from a nodes response with public_key should be pinged.
*
* NOTE: for best results call it after addto_lists.
*
@@ -1095,7 +1143,7 @@ static bool is_pk_in_close_list(const DHT *dht, const uint8_t *public_key, const
* return true if it should.
*/
non_null()
-static bool ping_node_from_getnodes_ok(DHT *dht, const uint8_t *public_key, const IP_Port *ip_port)
+static bool ping_node_from_nodes_response_ok(DHT *dht, const uint8_t *public_key, const IP_Port *ip_port)
{
bool ret = false;
@@ -1266,7 +1314,7 @@ static void returnedip_ports(DHT *dht, const IP_Port *ip_port, const uint8_t *pu
}
}
-bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id)
+bool dht_send_nodes_request(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id)
{
/* Check if packet is going to be sent to ourself. */
if (pk_equal(public_key, dht->self_public_key)) {
@@ -1301,21 +1349,21 @@ bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, c
const uint8_t *shared_key = dht_get_shared_key_sent(dht, public_key);
const int len = dht_create_packet(dht->mem, dht->rng,
- dht->self_public_key, shared_key, NET_PACKET_GET_NODES,
+ dht->self_public_key, shared_key, NET_PACKET_NODES_REQUEST,
plain, sizeof(plain), data, sizeof(data));
if (len != sizeof(data)) {
- LOGGER_ERROR(dht->log, "getnodes packet encryption failed");
+ LOGGER_ERROR(dht->log, "nodes request packet encryption failed");
return false;
}
return sendpacket(dht->net, ip_port, data, len) > 0;
}
-/** Send a send nodes response: message for IPv6 nodes */
+/** Send a nodes response */
non_null()
-static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id,
- const uint8_t *sendback_data, uint16_t length, const uint8_t *shared_encryption_key)
+static int send_nodes_response(const DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id,
+ const uint8_t *sendback_data, uint16_t length, const uint8_t *shared_encryption_key)
{
/* Check if packet is going to be sent to ourself. */
if (pk_equal(public_key, dht->self_public_key)) {
@@ -1347,15 +1395,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,
+ dht->self_public_key, shared_encryption_key, NET_PACKET_NODES_RESPONSE,
plain, 1 + nodes_length + length, data, data_size);
- if (len != data_size) {
+ if (len < 0 || (uint32_t)len != data_size) {
return -1;
}
@@ -1365,7 +1413,7 @@ static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t
#define CRYPTO_NODE_SIZE (CRYPTO_PUBLIC_KEY_SIZE + sizeof(uint64_t))
non_null()
-static int handle_getnodes(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
+static int handle_nodes_request(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
{
DHT *const dht = (DHT *)object;
@@ -1381,6 +1429,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,
@@ -1391,16 +1440,16 @@ static int handle_getnodes(void *object, const IP_Port *source, const uint8_t *p
return 1;
}
- sendnodes_ipv6(dht, source, packet + 1, plain, plain + CRYPTO_PUBLIC_KEY_SIZE, sizeof(uint64_t), shared_key);
+ send_nodes_response(dht, source, packet + 1, plain, plain + CRYPTO_PUBLIC_KEY_SIZE, sizeof(uint64_t), shared_key);
ping_add(dht->ping, packet + 1, source);
return 0;
}
-/** Return true if we sent a getnode packet to the peer associated with the supplied info. */
+/** Return true if we sent a nodes request packet to the peer associated with the supplied info. */
non_null()
-static bool sent_getnode_to_node(DHT *dht, const uint8_t *public_key, const IP_Port *node_ip_port, uint64_t ping_id)
+static bool sent_nodes_request_to_node(DHT *dht, const uint8_t *public_key, const IP_Port *node_ip_port, uint64_t ping_id)
{
uint8_t data[sizeof(Node_format) * 2];
@@ -1418,8 +1467,8 @@ static bool sent_getnode_to_node(DHT *dht, const uint8_t *public_key, const IP_P
}
non_null()
-static bool handle_sendnodes_core(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
- Node_format *plain_nodes, uint16_t size_plain_nodes, uint32_t *num_nodes_out)
+static bool handle_nodes_response_core(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
+ Node_format *plain_nodes, uint16_t size_plain_nodes, uint32_t *num_nodes_out)
{
DHT *const dht = (DHT *)object;
const uint32_t cid_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + 1 + sizeof(uint64_t) + CRYPTO_MAC_SIZE;
@@ -1442,6 +1491,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,
@@ -1459,7 +1509,7 @@ static bool handle_sendnodes_core(void *object, const IP_Port *source, const uin
uint64_t ping_id;
memcpy(&ping_id, plain + 1 + data_size, sizeof(ping_id));
- if (!sent_getnode_to_node(dht, packet + 1, source, ping_id)) {
+ if (!sent_nodes_request_to_node(dht, packet + 1, source, ping_id)) {
return false;
}
@@ -1487,14 +1537,14 @@ static bool handle_sendnodes_core(void *object, const IP_Port *source, const uin
}
non_null()
-static int handle_sendnodes_ipv6(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
+static int handle_nodes_response(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
void *userdata)
{
DHT *const dht = (DHT *)object;
Node_format plain_nodes[MAX_SENT_NODES];
uint32_t num_nodes;
- if (!handle_sendnodes_core(object, source, packet, length, plain_nodes, MAX_SENT_NODES, &num_nodes)) {
+ if (!handle_nodes_response_core(object, source, packet, length, plain_nodes, MAX_SENT_NODES, &num_nodes)) {
return 1;
}
@@ -1504,11 +1554,11 @@ static int handle_sendnodes_ipv6(void *object, const IP_Port *source, const uint
for (uint32_t i = 0; i < num_nodes; ++i) {
if (ipport_isset(&plain_nodes[i].ip_port)) {
- ping_node_from_getnodes_ok(dht, plain_nodes[i].public_key, &plain_nodes[i].ip_port);
+ ping_node_from_nodes_response_ok(dht, plain_nodes[i].public_key, &plain_nodes[i].ip_port);
returnedip_ports(dht, &plain_nodes[i].ip_port, plain_nodes[i].public_key, packet + 1);
- if (dht->get_nodes_response != nullptr) {
- dht->get_nodes_response(dht, &plain_nodes[i], userdata);
+ if (dht->nodes_response_callback != nullptr) {
+ dht->nodes_response_callback(dht, &plain_nodes[i], userdata);
}
}
}
@@ -1721,7 +1771,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
if (mono_time_is_timeout(dht->mono_time, assoc->last_pinged, PING_INTERVAL)) {
const IP_Port *target = &assoc->ip_port;
const uint8_t *target_key = client->public_key;
- dht_getnodes(dht, target, target_key, public_key);
+ dht_send_nodes_request(dht, target, target_key, public_key);
assoc->last_pinged = temp_time;
}
@@ -1746,7 +1796,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
sort_client_list(dht->mem, list, dht->cur_time, list_count, public_key);
}
- if (num_nodes > 0 && (mono_time_is_timeout(dht->mono_time, *lastgetnode, GET_NODE_INTERVAL)
+ if (num_nodes > 0 && (mono_time_is_timeout(dht->mono_time, *lastgetnode, NODES_REQUEST_INTERVAL)
|| *bootstrap_times < MAX_BOOTSTRAP_TIMES)) {
uint32_t rand_node = random_range_u32(dht->rng, num_nodes);
@@ -1756,7 +1806,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
const IP_Port *target = &assoc_list[rand_node]->ip_port;
const uint8_t *target_key = client_list[rand_node]->public_key;
- dht_getnodes(dht, target, target_key, public_key);
+ dht_send_nodes_request(dht, target, target_key, public_key);
*lastgetnode = temp_time;
++*bootstrap_times;
@@ -1769,7 +1819,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
/** @brief Ping each client in the "friends" list every PING_INTERVAL seconds.
*
- * Send a get nodes request every GET_NODE_INTERVAL seconds to a random good
+ * Send a nodes request every NODES_REQUEST_INTERVAL seconds to a random good
* node for each "friend" in our "friends" list.
*/
non_null()
@@ -1779,31 +1829,31 @@ static void do_dht_friends(DHT *dht)
DHT_Friend *const dht_friend = &dht->friends_list[i];
for (size_t j = 0; j < dht_friend->num_to_bootstrap; ++j) {
- dht_getnodes(dht, &dht_friend->to_bootstrap[j].ip_port, dht_friend->to_bootstrap[j].public_key, dht_friend->public_key);
+ dht_send_nodes_request(dht, &dht_friend->to_bootstrap[j].ip_port, dht_friend->to_bootstrap[j].public_key, dht_friend->public_key);
}
dht_friend->num_to_bootstrap = 0;
- do_ping_and_sendnode_requests(dht, &dht_friend->lastgetnode, dht_friend->public_key, dht_friend->client_list,
+ do_ping_and_sendnode_requests(dht, &dht_friend->last_nodes_request, dht_friend->public_key, dht_friend->client_list,
MAX_FRIEND_CLIENTS, &dht_friend->bootstrap_times, true);
}
}
/** @brief Ping each client in the close nodes list every PING_INTERVAL seconds.
*
- * Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list.
+ * Send a nodes request every NODES_REQUEST_INTERVAL seconds to a random good node in the list.
*/
non_null()
static void do_close(DHT *dht)
{
for (size_t i = 0; i < dht->num_to_bootstrap; ++i) {
- dht_getnodes(dht, &dht->to_bootstrap[i].ip_port, dht->to_bootstrap[i].public_key, dht->self_public_key);
+ dht_send_nodes_request(dht, &dht->to_bootstrap[i].ip_port, dht->to_bootstrap[i].public_key, dht->self_public_key);
}
dht->num_to_bootstrap = 0;
const uint8_t not_killed = do_ping_and_sendnode_requests(
- dht, &dht->close_lastgetnodes, dht->self_public_key, dht->close_clientlist, LCLIENT_LIST, &dht->close_bootstrap_times,
+ dht, &dht->close_last_nodes_request, dht->self_public_key, dht->close_clientlist, LCLIENT_LIST, &dht->close_bootstrap_times,
false);
if (not_killed != 0) {
@@ -1837,10 +1887,10 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key)
return true;
}
- return dht_getnodes(dht, ip_port, public_key, dht->self_public_key);
+ return dht_send_nodes_request(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 +1905,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 +2173,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 +2508,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) {
@@ -2484,9 +2534,9 @@ static int cryptopacket_handle(void *object, const IP_Port *source, const uint8_
return 1;
}
-void dht_callback_get_nodes_response(DHT *dht, dht_get_nodes_response_cb *function)
+void dht_callback_nodes_response(DHT *dht, dht_nodes_response_cb *function)
{
- dht->get_nodes_response = function;
+ dht->nodes_response_callback = function;
}
non_null(1, 2, 3) nullable(5)
@@ -2547,8 +2597,8 @@ DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Netw
return nullptr;
}
- networking_registerhandler(dht->net, NET_PACKET_GET_NODES, &handle_getnodes, dht);
- networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
+ networking_registerhandler(dht->net, NET_PACKET_NODES_REQUEST, &handle_nodes_request, dht);
+ networking_registerhandler(dht->net, NET_PACKET_NODES_RESPONSE, &handle_nodes_response, dht);
networking_registerhandler(dht->net, NET_PACKET_CRYPTO, &cryptopacket_handle, dht);
networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_lan_discovery, dht);
cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, &handle_nat_ping, dht);
@@ -2626,8 +2676,8 @@ void kill_dht(DHT *dht)
return;
}
- networking_registerhandler(dht->net, NET_PACKET_GET_NODES, nullptr, nullptr);
- networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, nullptr, nullptr);
+ networking_registerhandler(dht->net, NET_PACKET_NODES_REQUEST, nullptr, nullptr);
+ networking_registerhandler(dht->net, NET_PACKET_NODES_RESPONSE, nullptr, nullptr);
networking_registerhandler(dht->net, NET_PACKET_CRYPTO, nullptr, nullptr);
networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, nullptr, nullptr);
cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, nullptr, nullptr);
diff --git a/protocols/Tox/libtox/src/toxcore/DHT.h b/protocols/Tox/libtox/src/toxcore/DHT.h
index 19a9e1d937..16b293331c 100644
--- a/protocols/Tox/libtox/src/toxcore/DHT.h
+++ b/protocols/Tox/libtox/src/toxcore/DHT.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -36,7 +36,7 @@ extern "C" {
#define MAX_CLOSE_TO_BOOTSTRAP_NODES 8
-/** The max number of nodes to send with send nodes. */
+/** The max number of nodes to send with nodes response. */
#define MAX_SENT_NODES 4
/** Ping timeout in seconds */
@@ -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 {
@@ -259,21 +259,21 @@ non_null()
const uint8_t *dht_get_shared_key_sent(DHT *dht, const uint8_t *public_key);
/**
- * Sends a getnodes request to `ip_port` with the public key `public_key` for nodes
+ * Sends a nodes request to `ip_port` with the public key `public_key` for nodes
* that are close to `client_id`.
*
* @retval true on success.
*/
non_null()
-bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id);
+bool dht_send_nodes_request(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id);
typedef void dht_ip_cb(void *object, int32_t number, const IP_Port *ip_port);
-typedef void dht_get_nodes_response_cb(const DHT *dht, const Node_format *node, void *user_data);
+typedef void dht_nodes_response_cb(const DHT *dht, const Node_format *node, void *user_data);
-/** Sets the callback to be triggered on a getnodes response. */
+/** Sets the callback to be triggered on a nodes response. */
non_null(1) nullable(2)
-void dht_callback_get_nodes_response(DHT *dht, dht_get_nodes_response_cb *function);
+void dht_callback_nodes_response(DHT *dht, dht_nodes_response_cb *function);
/** @brief Add a new friend to the friends list.
* @param public_key must be CRYPTO_PUBLIC_KEY_SIZE bytes long.
@@ -390,7 +390,7 @@ void do_dht(DHT *dht);
* Use these two functions to bootstrap the client.
*/
/**
- * @brief Sends a "get nodes" request to the given node with ip, port and public_key
+ * @brief Sends a "nodes request" to the given node with ip, port and public_key
* to setup connections
*/
non_null()
@@ -398,18 +398,19 @@ bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key);
/** @brief Resolves address into an IP address.
*
- * If successful, sends a "get nodes" request to the given node with ip, port
+ * If successful, sends a "nodes request" to the given node with ip, port
* and public_key to setup connections
*
* @param address can be a hostname or an IP address (IPv4 or IPv6).
* @param ipv6enabled if false, the resolving sticks STRICTLY to IPv4 addresses.
* Otherwise, the resolving looks for IPv6 addresses first, then IPv4 addresses.
+ * @param dns_enabled if false, the resolving does not use DNS, only IP addresses are supported.
*
* @retval true if the address could be converted into an IP address
* @retval false otherwise
*/
non_null()
-bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled,
+bool dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, bool dns_enabled,
uint16_t port, const uint8_t *public_key);
/** @brief Start sending packets after DHT loaded_friends_list and loaded_clients_list are set.
diff --git a/protocols/Tox/libtox/src/toxcore/LAN_discovery.c b/protocols/Tox/libtox/src/toxcore/LAN_discovery.c
index aead975911..fcc3d4793f 100644
--- a/protocols/Tox/libtox/src/toxcore/LAN_discovery.c
+++ b/protocols/Tox/libtox/src/toxcore/LAN_discovery.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -8,8 +8,6 @@
*/
#include "LAN_discovery.h"
-#include <stdlib.h>
-
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
// The mingw32/64 Windows library warns about including winsock2.h after
// windows.h even though with the above it's a valid thing to do. So, to make
@@ -41,11 +39,14 @@
#include "attributes.h"
#include "ccompat.h"
#include "crypto_core.h"
+#include "mem.h"
#include "network.h"
#define MAX_INTERFACES 16
struct Broadcast_Info {
+ const Memory *mem;
+
uint32_t count;
IP ips[MAX_INTERFACES];
};
@@ -53,29 +54,31 @@ struct Broadcast_Info {
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
non_null()
-static Broadcast_Info *fetch_broadcast_info(const Network *ns)
+static Broadcast_Info *fetch_broadcast_info(const Memory *mem, const Network *ns)
{
- Broadcast_Info *broadcast = (Broadcast_Info *)calloc(1, sizeof(Broadcast_Info));
+ Broadcast_Info *broadcast = (Broadcast_Info *)mem_alloc(mem, sizeof(Broadcast_Info));
if (broadcast == nullptr) {
return nullptr;
}
- IP_ADAPTER_INFO *adapter_info = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
+ broadcast->mem = mem;
+
+ IP_ADAPTER_INFO *adapter_info = (IP_ADAPTER_INFO *)mem_balloc(mem, sizeof(IP_ADAPTER_INFO));
if (adapter_info == nullptr) {
- free(broadcast);
+ mem_delete(mem, broadcast);
return nullptr;
}
unsigned long out_buf_len = sizeof(IP_ADAPTER_INFO);
if (GetAdaptersInfo(adapter_info, &out_buf_len) == ERROR_BUFFER_OVERFLOW) {
- free(adapter_info);
- IP_ADAPTER_INFO *new_adapter_info = (IP_ADAPTER_INFO *)malloc(out_buf_len);
+ mem_delete(mem, adapter_info);
+ IP_ADAPTER_INFO *new_adapter_info = (IP_ADAPTER_INFO *)mem_balloc(mem, out_buf_len);
if (new_adapter_info == nullptr) {
- free(broadcast);
+ mem_delete(mem, broadcast);
return nullptr;
}
@@ -113,7 +116,7 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns)
}
if (adapter_info != nullptr) {
- free(adapter_info);
+ mem_delete(mem, adapter_info);
}
return broadcast;
@@ -122,14 +125,19 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns)
#elif !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && (defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__))
non_null()
-static Broadcast_Info *fetch_broadcast_info(const Network *ns)
+static bool ip4_is_local(const IP4 *ip4);
+
+non_null()
+static Broadcast_Info *fetch_broadcast_info(const Memory *mem, const Network *ns)
{
- Broadcast_Info *broadcast = (Broadcast_Info *)calloc(1, sizeof(Broadcast_Info));
+ Broadcast_Info *broadcast = (Broadcast_Info *)mem_alloc(mem, sizeof(Broadcast_Info));
if (broadcast == nullptr) {
return nullptr;
}
+ broadcast->mem = mem;
+
/* Not sure how many platforms this will run on,
* so it's wrapped in `__linux__` for now.
* Definitely won't work like this on Windows...
@@ -137,7 +145,7 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns)
const Socket sock = net_socket(ns, net_family_ipv4(), TOX_SOCK_STREAM, 0);
if (!sock_valid(sock)) {
- free(broadcast);
+ mem_delete(mem, broadcast);
return nullptr;
}
@@ -150,7 +158,7 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns)
if (ioctl(net_socket_to_native(sock), SIOCGIFCONF, &ifc) < 0) {
kill_sock(ns, sock);
- free(broadcast);
+ mem_delete(mem, broadcast);
return nullptr;
}
@@ -162,7 +170,8 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns)
const int n = ifc.ifc_len / sizeof(struct ifreq);
for (int i = 0; i < n; ++i) {
- /* there are interfaces with are incapable of broadcast */
+ /* there are interfaces with are incapable of broadcast
+ * on Linux, `lo` has no broadcast address, but this function returns `>=0` */
if (ioctl(net_socket_to_native(sock), SIOCGIFBRDADDR, &i_faces[i]) < 0) {
continue;
}
@@ -172,7 +181,7 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns)
continue;
}
- const struct sockaddr_in *sock4 = (const struct sockaddr_in *)(void *)&i_faces[i].ifr_broadaddr;
+ const struct sockaddr_in *broadaddr4 = (const struct sockaddr_in *)(void *)&i_faces[i].ifr_broadaddr;
if (broadcast->count >= MAX_INTERFACES) {
break;
@@ -180,10 +189,27 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns)
IP *ip = &broadcast->ips[broadcast->count];
ip->family = net_family_ipv4();
- ip->ip.v4.uint32 = sock4->sin_addr.s_addr;
+ ip->ip.v4.uint32 = broadaddr4->sin_addr.s_addr;
+ // if no broadcast address
if (ip->ip.v4.uint32 == 0) {
- continue;
+ if (ioctl(net_socket_to_native(sock), SIOCGIFADDR, &i_faces[i]) < 0) {
+ continue;
+ }
+
+ const struct sockaddr_in *addr4 = (const struct sockaddr_in *)(void *)&i_faces[i].ifr_addr;
+
+
+ IP4 ip4_staging;
+ ip4_staging.uint32 = addr4->sin_addr.s_addr;
+
+ if (ip4_is_local(&ip4_staging)) {
+ // this is 127.x.x.x
+ ip->ip.v4.uint32 = ip4_staging.uint32;
+ } else {
+ // give up.
+ continue;
+ }
}
++broadcast->count;
@@ -197,9 +223,17 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns)
#else // TODO(irungentoo): Other platforms?
non_null()
-static Broadcast_Info *fetch_broadcast_info(const Network *ns)
+static Broadcast_Info *fetch_broadcast_info(const Memory *mem, const Network *ns)
{
- return (Broadcast_Info *)calloc(1, sizeof(Broadcast_Info));
+ Broadcast_Info *broadcast = (Broadcast_Info *)mem_alloc(mem, sizeof(Broadcast_Info));
+
+ if (broadcast == nullptr) {
+ return nullptr;
+ }
+
+ broadcast->mem = mem;
+
+ return broadcast;
}
#endif /* platforms */
@@ -375,12 +409,16 @@ bool lan_discovery_send(const Networking_Core *net, const Broadcast_Info *broadc
return res;
}
-Broadcast_Info *lan_discovery_init(const Network *ns)
+Broadcast_Info *lan_discovery_init(const Memory *mem, const Network *ns)
{
- return fetch_broadcast_info(ns);
+ return fetch_broadcast_info(mem, ns);
}
void lan_discovery_kill(Broadcast_Info *broadcast)
{
- free(broadcast);
+ if (broadcast == nullptr) {
+ return;
+ }
+
+ mem_delete(broadcast->mem, broadcast);
}
diff --git a/protocols/Tox/libtox/src/toxcore/LAN_discovery.h b/protocols/Tox/libtox/src/toxcore/LAN_discovery.h
index 94e5d3581c..c18ce9e562 100644
--- a/protocols/Tox/libtox/src/toxcore/LAN_discovery.h
+++ b/protocols/Tox/libtox/src/toxcore/LAN_discovery.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -10,6 +10,7 @@
#define C_TOXCORE_TOXCORE_LAN_DISCOVERY_H
#include "attributes.h"
+#include "mem.h"
#include "network.h"
/**
@@ -32,7 +33,7 @@ bool lan_discovery_send(const Networking_Core *net, const Broadcast_Info *broadc
* Discovers broadcast devices and IP addresses.
*/
non_null()
-Broadcast_Info *lan_discovery_init(const Network *ns);
+Broadcast_Info *lan_discovery_init(const Memory *mem, const Network *ns);
/**
* Free all resources associated with the broadcast info.
diff --git a/protocols/Tox/libtox/src/toxcore/Makefile.inc b/protocols/Tox/libtox/src/toxcore/Makefile.inc
new file mode 100644
index 0000000000..de9227b6d0
--- /dev/null
+++ b/protocols/Tox/libtox/src/toxcore/Makefile.inc
@@ -0,0 +1,179 @@
+lib_LTLIBRARIES += libtoxcore.la
+
+libtoxcore_la_include_HEADERS = \
+ ../toxcore/tox.h \
+ ../toxcore/tox_options.h
+
+libtoxcore_la_includedir = $(includedir)/tox
+
+libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
+ ../third_party/cmp/cmp.h \
+ ../toxcore/events/conference_connected.c \
+ ../toxcore/events/conference_invite.c \
+ ../toxcore/events/conference_message.c \
+ ../toxcore/events/conference_peer_list_changed.c \
+ ../toxcore/events/conference_peer_name.c \
+ ../toxcore/events/conference_title.c \
+ ../toxcore/events/dht_nodes_response.c \
+ ../toxcore/events/events_alloc.c \
+ ../toxcore/events/events_alloc.h \
+ ../toxcore/events/file_chunk_request.c \
+ ../toxcore/events/file_recv.c \
+ ../toxcore/events/file_recv_chunk.c \
+ ../toxcore/events/file_recv_control.c \
+ ../toxcore/events/friend_connection_status.c \
+ ../toxcore/events/friend_lossless_packet.c \
+ ../toxcore/events/friend_lossy_packet.c \
+ ../toxcore/events/friend_message.c \
+ ../toxcore/events/friend_name.c \
+ ../toxcore/events/friend_read_receipt.c \
+ ../toxcore/events/friend_request.c \
+ ../toxcore/events/friend_status.c \
+ ../toxcore/events/friend_status_message.c \
+ ../toxcore/events/friend_typing.c \
+ ../toxcore/events/self_connection_status.c \
+ ../toxcore/events/group_custom_packet.c \
+ ../toxcore/events/group_custom_private_packet.c \
+ ../toxcore/events/group_invite.c \
+ ../toxcore/events/group_join_fail.c \
+ ../toxcore/events/group_message.c \
+ ../toxcore/events/group_moderation.c \
+ ../toxcore/events/group_password.c \
+ ../toxcore/events/group_peer_exit.c \
+ ../toxcore/events/group_peer_join.c \
+ ../toxcore/events/group_peer_limit.c \
+ ../toxcore/events/group_peer_name.c \
+ ../toxcore/events/group_peer_status.c \
+ ../toxcore/events/group_privacy_state.c \
+ ../toxcore/events/group_private_message.c \
+ ../toxcore/events/group_self_join.c \
+ ../toxcore/events/group_topic.c \
+ ../toxcore/events/group_topic_lock.c \
+ ../toxcore/events/group_voice_state.c \
+ ../toxcore/announce.c \
+ ../toxcore/announce.h \
+ ../toxcore/attributes.h \
+ ../toxcore/bin_pack.c \
+ ../toxcore/bin_pack.h \
+ ../toxcore/bin_unpack.c \
+ ../toxcore/bin_unpack.h \
+ ../toxcore/ccompat.c \
+ ../toxcore/ccompat.h \
+ ../toxcore/crypto_core_pack.c \
+ ../toxcore/crypto_core_pack.h \
+ ../toxcore/crypto_core.c \
+ ../toxcore/crypto_core.h \
+ ../toxcore/DHT.c \
+ ../toxcore/DHT.h \
+ ../toxcore/forwarding.c \
+ ../toxcore/forwarding.h \
+ ../toxcore/friend_connection.c \
+ ../toxcore/friend_connection.h \
+ ../toxcore/friend_requests.c \
+ ../toxcore/friend_requests.h \
+ ../toxcore/group_announce.c \
+ ../toxcore/group_announce.h \
+ ../toxcore/group_chats.c \
+ ../toxcore/group_chats.h \
+ ../toxcore/group_common.h \
+ ../toxcore/group_connection.c \
+ ../toxcore/group_connection.h \
+ ../toxcore/group_moderation.c \
+ ../toxcore/group_moderation.h \
+ ../toxcore/group_onion_announce.c \
+ ../toxcore/group_onion_announce.h \
+ ../toxcore/group_pack.c \
+ ../toxcore/group_pack.h \
+ ../toxcore/group.c \
+ ../toxcore/group.h \
+ ../toxcore/LAN_discovery.c \
+ ../toxcore/LAN_discovery.h \
+ ../toxcore/list.c \
+ ../toxcore/list.h \
+ ../toxcore/logger.c \
+ ../toxcore/logger.h \
+ ../toxcore/mem.c \
+ ../toxcore/mem.h \
+ ../toxcore/Messenger.c \
+ ../toxcore/Messenger.h \
+ ../toxcore/mono_time.c \
+ ../toxcore/mono_time.h \
+ ../toxcore/net_crypto.c \
+ ../toxcore/net_crypto.h \
+ ../toxcore/net_profile.c \
+ ../toxcore/net_profile.h \
+ ../toxcore/network.c \
+ ../toxcore/network.h \
+ ../toxcore/onion_announce.c \
+ ../toxcore/onion_announce.h \
+ ../toxcore/onion_client.c \
+ ../toxcore/onion_client.h \
+ ../toxcore/onion.c \
+ ../toxcore/onion.h \
+ ../toxcore/ping_array.c \
+ ../toxcore/ping_array.h \
+ ../toxcore/ping.c \
+ ../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 \
+ ../toxcore/TCP_client.h \
+ ../toxcore/TCP_common.c \
+ ../toxcore/TCP_common.h \
+ ../toxcore/TCP_connection.c \
+ ../toxcore/TCP_connection.h \
+ ../toxcore/TCP_server.c \
+ ../toxcore/TCP_server.h \
+ ../toxcore/timed_auth.c \
+ ../toxcore/timed_auth.h \
+ ../toxcore/tox_api.c \
+ ../toxcore/tox_dispatch.c \
+ ../toxcore/tox_dispatch.h \
+ ../toxcore/tox_event.c \
+ ../toxcore/tox_event.h \
+ ../toxcore/tox_events.c \
+ ../toxcore/tox_events.h \
+ ../toxcore/tox_log_level.c \
+ ../toxcore/tox_log_level.h \
+ ../toxcore/tox_options.c \
+ ../toxcore/tox_options.h \
+ ../toxcore/tox_pack.c \
+ ../toxcore/tox_pack.h \
+ ../toxcore/tox_private.c \
+ ../toxcore/tox_private.h \
+ ../toxcore/tox_struct.h \
+ ../toxcore/tox_unpack.c \
+ ../toxcore/tox_unpack.h \
+ ../toxcore/tox.c \
+ ../toxcore/tox.h \
+ ../toxcore/util.c \
+ ../toxcore/util.h
+
+libtoxcore_la_CFLAGS = -I$(top_srcdir) \
+ -I$(top_srcdir)/toxcore \
+ $(LIBSODIUM_CFLAGS) \
+ $(MSGPACK_CFLAGS) \
+ $(PTHREAD_CFLAGS) \
+ -DCMP_NO_FLOAT=1
+
+libtoxcore_la_LDFLAGS = $(LT_LDFLAGS) \
+ $(EXTRA_LT_LDFLAGS) \
+ $(LIBSODIUM_LDFLAGS) \
+ $(MSGPACK_LDFLAGS) \
+ $(MATH_LDFLAGS) \
+ $(RT_LIBS) \
+ $(WINSOCK2_LIBS)
+
+libtoxcore_la_LIBADD = $(LIBSODIUM_LIBS) \
+ $(MSGPACK_LIBS) \
+ $(PTHREAD_LIBS)
+
+if SET_SO_VERSION
+
+EXTRA_libtoxcore_la_DEPENDENCIES = ../so.version
+
+endif
diff --git a/protocols/Tox/libtox/src/toxcore/Messenger.c b/protocols/Tox/libtox/src/toxcore/Messenger.c
index 947edef7e1..2d25abda56 100644
--- a/protocols/Tox/libtox/src/toxcore/Messenger.c
+++ b/protocols/Tox/libtox/src/toxcore/Messenger.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -34,6 +34,7 @@
#include "mem.h"
#include "mono_time.h"
#include "net_crypto.h"
+#include "net_profile.h"
#include "network.h"
#include "onion.h"
#include "onion_announce.h"
@@ -137,7 +138,7 @@ void getaddress(const Messenger *m, uint8_t *address)
}
non_null()
-static bool send_online_packet(Messenger *m, int friendcon_id)
+static bool send_online_packet(const Messenger *m, int friendcon_id)
{
const uint8_t packet[1] = {PACKET_ID_ONLINE};
return write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, friendcon_id), packet,
@@ -145,7 +146,7 @@ static bool send_online_packet(Messenger *m, int friendcon_id)
}
non_null()
-static bool send_offline_packet(Messenger *m, int friendcon_id)
+static bool send_offline_packet(const Messenger *m, int friendcon_id)
{
const uint8_t packet[1] = {PACKET_ID_OFFLINE};
return write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, friendcon_id), packet,
@@ -472,10 +473,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,
@@ -775,31 +772,31 @@ int m_set_statusmessage(Messenger *m, const uint8_t *status, uint16_t length)
}
non_null()
-static bool userstatus_from_int(uint8_t status, Userstatus *out)
+static bool userstatus_from_int(uint8_t status, Userstatus *out_enum)
{
switch (status) {
case USERSTATUS_NONE: {
- *out = USERSTATUS_NONE;
+ *out_enum = USERSTATUS_NONE;
return true;
}
case USERSTATUS_AWAY: {
- *out = USERSTATUS_AWAY;
+ *out_enum = USERSTATUS_AWAY;
return true;
}
case USERSTATUS_BUSY: {
- *out = USERSTATUS_BUSY;
+ *out_enum = USERSTATUS_BUSY;
return true;
}
case USERSTATUS_INVALID: {
- *out = USERSTATUS_INVALID;
+ *out_enum = USERSTATUS_INVALID;
return true;
}
default: {
- *out = USERSTATUS_INVALID;
+ *out_enum = USERSTATUS_INVALID;
return false;
}
}
@@ -1027,13 +1024,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 +1071,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 +1840,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 +1849,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 +1861,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 +1871,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 +1898,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) {
@@ -2357,20 +2284,6 @@ static int m_handle_packet_file_data(Messenger *m, const int friendcon_id, const
}
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)
{
// first two bytes are messenger packet type and group invite type
@@ -2443,7 +2356,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);
}
@@ -2468,14 +2381,12 @@ static void do_friends(Messenger *m, void *userdata)
}
}
- if (m->friendlist[i].status == FRIEND_REQUESTED
- || m->friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online. */
- if (m->friendlist[i].status == FRIEND_REQUESTED) {
- /* If we didn't connect to friend after successfully sending him a friend request the request is deemed
- * unsuccessful so we set the status back to FRIEND_ADDED and try again.
- */
- check_friend_request_timed_out(m, i, temp_time, userdata);
- }
+ if (m->friendlist[i].status == FRIEND_REQUESTED) {
+ /* If we didn't connect to friend after successfully sending him a friend
+ * request the request is deemed unsuccessful so we set the status back to
+ * FRIEND_ADDED and try again.
+ */
+ check_friend_request_timed_out(m, i, temp_time, userdata);
}
if (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online. */
@@ -2605,7 +2516,7 @@ static bool self_announce_group(const Messenger *m, GC_Chat *chat, Onion_Friend
return false;
}
- if (gca_add_announce(m->mono_time, m->group_announce, &announce) == nullptr) {
+ if (gca_add_announce(m->mem, m->mono_time, m->group_announce, &announce) == nullptr) {
onion_friend_set_gc_data(onion_friend, nullptr, 0);
return false;
}
@@ -3261,7 +3172,7 @@ static bool handle_groups_load(void *obj, Bin_Unpack *bu)
non_null()
static State_Load_Status groups_load(Messenger *m, const uint8_t *data, uint32_t length)
{
- if (!bin_unpack_obj(handle_groups_load, m, data, length)) {
+ if (!bin_unpack_obj(m->mem, handle_groups_load, m, data, length)) {
LOGGER_ERROR(m->log, "msgpack failed to unpack groupchats array");
return STATE_LOAD_STATUS_ERROR;
}
@@ -3565,14 +3476,14 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
m->rng = rng;
m->ns = ns;
- m->fr = friendreq_new();
+ m->fr = friendreq_new(mem);
if (m->fr == nullptr) {
mem_delete(mem, m);
return nullptr;
}
- m->log = logger_new();
+ m->log = logger_new(mem);
if (m->log == nullptr) {
friendreq_kill(m->fr);
@@ -3621,11 +3532,24 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
return nullptr;
}
- m->net_crypto = new_net_crypto(m->log, m->mem, m->rng, m->ns, m->mono_time, m->dht, &options->proxy_info);
+ m->tcp_np = netprof_new(m->log, mem);
+
+ if (m->tcp_np == nullptr) {
+ LOGGER_WARNING(m->log, "TCP netprof initialisation failed");
+ kill_dht(m->dht);
+ kill_networking(m->net);
+ friendreq_kill(m->fr);
+ logger_kill(m->log);
+ mem_delete(mem, m);
+ return nullptr;
+ }
+
+ m->net_crypto = new_net_crypto(m->log, m->mem, m->rng, m->ns, m->mono_time, m->dht, &options->proxy_info, m->tcp_np);
if (m->net_crypto == nullptr) {
LOGGER_WARNING(m->log, "net_crypto initialisation failed");
+ netprof_kill(mem, m->tcp_np);
kill_dht(m->dht);
kill_networking(m->net);
friendreq_kill(m->fr);
@@ -3634,12 +3558,13 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
return nullptr;
}
- m->group_announce = new_gca_list();
+ m->group_announce = new_gca_list(m->mem);
if (m->group_announce == nullptr) {
LOGGER_WARNING(m->log, "DHT group chats initialisation failed");
kill_net_crypto(m->net_crypto);
+ netprof_kill(mem, m->tcp_np);
kill_dht(m->dht);
kill_networking(m->net);
friendreq_kill(m->fr);
@@ -3649,7 +3574,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
}
if (options->dht_announcements_enabled) {
- m->forwarding = new_forwarding(m->log, m->rng, m->mono_time, m->dht);
+ m->forwarding = new_forwarding(m->log, m->mem, m->rng, m->mono_time, m->dht);
if (m->forwarding != nullptr) {
m->announce = new_announcements(m->log, m->mem, m->rng, m->mono_time, m->forwarding);
} else {
@@ -3664,7 +3589,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
m->onion_a = new_onion_announce(m->log, m->mem, m->rng, m->mono_time, m->dht);
m->onion_c = new_onion_client(m->log, m->mem, m->rng, m->mono_time, m->net_crypto);
if (m->onion_c != nullptr) {
- m->fr_c = new_friend_connections(m->log, m->mono_time, m->ns, m->onion_c, options->local_discovery_enabled);
+ m->fr_c = new_friend_connections(m->log, m->mem, m->mono_time, m->ns, m->onion_c, options->local_discovery_enabled);
}
if ((options->dht_announcements_enabled && (m->forwarding == nullptr || m->announce == nullptr)) ||
@@ -3679,6 +3604,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
kill_announcements(m->announce);
kill_forwarding(m->forwarding);
kill_net_crypto(m->net_crypto);
+ netprof_kill(mem, m->tcp_np);
kill_dht(m->dht);
kill_networking(m->net);
friendreq_kill(m->fr);
@@ -3702,6 +3628,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
kill_announcements(m->announce);
kill_forwarding(m->forwarding);
kill_net_crypto(m->net_crypto);
+ netprof_kill(mem, m->tcp_np);
kill_dht(m->dht);
kill_networking(m->net);
friendreq_kill(m->fr);
@@ -3727,6 +3654,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
kill_announcements(m->announce);
kill_forwarding(m->forwarding);
kill_net_crypto(m->net_crypto);
+ netprof_kill(mem, m->tcp_np);
kill_dht(m->dht);
kill_networking(m->net);
friendreq_kill(m->fr);
@@ -3782,6 +3710,7 @@ void kill_messenger(Messenger *m)
kill_announcements(m->announce);
kill_forwarding(m->forwarding);
kill_net_crypto(m->net_crypto);
+ netprof_kill(m->mem, m->tcp_np);
kill_dht(m->dht);
kill_networking(m->net);
diff --git a/protocols/Tox/libtox/src/toxcore/Messenger.h b/protocols/Tox/libtox/src/toxcore/Messenger.h
index cace3340b2..1286ddf138 100644
--- a/protocols/Tox/libtox/src/toxcore/Messenger.h
+++ b/protocols/Tox/libtox/src/toxcore/Messenger.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -25,6 +25,7 @@
#include "mem.h"
#include "mono_time.h"
#include "net_crypto.h"
+#include "net_profile.h"
#include "network.h"
#include "onion.h"
#include "onion_announce.h"
@@ -86,6 +87,8 @@ typedef struct Messenger_Options {
Messenger_State_Plugin *state_plugins;
uint8_t state_plugins_length;
+
+ bool dns_enabled;
} Messenger_Options;
struct Receipts {
@@ -200,20 +203,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 +236,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;
@@ -258,6 +249,7 @@ struct Messenger {
Networking_Core *net;
Net_Crypto *net_crypto;
+ Net_Profile *tcp_np;
DHT *dht;
Forwarding *forwarding;
@@ -301,8 +293,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 +304,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 +601,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,29 +714,6 @@ 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. */
@@ -761,13 +721,6 @@ non_null() void custom_lossy_packet_registerhandler(Messenger *m, m_friend_lossy
/** @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.
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_client.c b/protocols/Tox/libtox/src/toxcore/TCP_client.c
index 2b8c6e448f..1982412cda 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_client.c
+++ b/protocols/Tox/libtox/src/toxcore/TCP_client.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2014 Tox project.
*/
@@ -20,6 +20,7 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
+#include "net_profile.h"
#include "network.h"
#include "util.h"
@@ -107,13 +108,25 @@ void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value)
* @retval false on failure
*/
non_null()
-static bool connect_sock_to(const Logger *logger, const Memory *mem, Socket sock, const IP_Port *ip_port, const TCP_Proxy_Info *proxy_info)
+static bool connect_sock_to(const Network *ns, const Logger *logger, const Memory *mem, Socket sock, const IP_Port *ip_port, const TCP_Proxy_Info *proxy_info)
{
+ Net_Err_Connect err;
if (proxy_info->proxy_type != TCP_PROXY_NONE) {
- return net_connect(mem, logger, sock, &proxy_info->ip_port);
+ net_connect(ns, mem, logger, sock, &proxy_info->ip_port, &err);
} else {
- return net_connect(mem, logger, sock, ip_port);
+ net_connect(ns, mem, logger, sock, ip_port, &err);
}
+ switch (err) {
+ case NET_ERR_CONNECT_OK:
+ case NET_ERR_CONNECT_FAILED: {
+ /* nonblocking socket, connect will never return success */
+ return true;
+ }
+ case NET_ERR_CONNECT_INVALID_FAMILY:
+ return false;
+ }
+ LOGGER_ERROR(logger, "unexpected error code %s from net_connect", net_err_connect_to_string(err));
+ return false;
}
/**
@@ -312,7 +325,7 @@ static int generate_handshake(TCP_Client_Connection *tcp_conn)
memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, tcp_conn->con.sent_nonce, CRYPTO_NONCE_SIZE);
memcpy(tcp_conn->con.last_packet, tcp_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE);
random_nonce(tcp_conn->con.rng, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE);
- const int len = encrypt_data_symmetric(tcp_conn->con.shared_key, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain,
+ const int len = encrypt_data_symmetric(tcp_conn->con.mem, tcp_conn->con.shared_key, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain,
sizeof(plain), tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
if (len != sizeof(plain) + CRYPTO_MAC_SIZE) {
@@ -334,7 +347,7 @@ non_null()
static int handle_handshake(TCP_Client_Connection *tcp_conn, const uint8_t *data)
{
uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE];
- const int len = decrypt_data_symmetric(tcp_conn->con.shared_key, data, data + CRYPTO_NONCE_SIZE,
+ const int len = decrypt_data_symmetric(tcp_conn->con.mem, tcp_conn->con.shared_key, data, data + CRYPTO_NONCE_SIZE,
TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain);
if (len != sizeof(plain)) {
@@ -582,7 +595,7 @@ void forwarding_handler(TCP_Client_Connection *con, forwarded_response_cb *forwa
TCP_Client_Connection *new_tcp_connection(
const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns,
const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key,
- const TCP_Proxy_Info *proxy_info)
+ const TCP_Proxy_Info *proxy_info, Net_Profile *net_profile)
{
assert(logger != nullptr);
assert(mem != nullptr);
@@ -591,6 +604,7 @@ TCP_Client_Connection *new_tcp_connection(
assert(ns != nullptr);
if (!net_family_is_ipv4(ip_port->ip.family) && !net_family_is_ipv6(ip_port->ip.family)) {
+ LOGGER_ERROR(logger, "Invalid IP family: %d", ip_port->ip.family.value);
return nullptr;
}
@@ -609,15 +623,26 @@ TCP_Client_Connection *new_tcp_connection(
const Socket sock = net_socket(ns, family, TOX_SOCK_STREAM, TOX_PROTO_TCP);
if (!sock_valid(sock)) {
+ LOGGER_ERROR(logger, "Failed to create TCP socket with family %d", family.value);
return nullptr;
}
if (!set_socket_nosigpipe(ns, sock)) {
+ LOGGER_ERROR(logger, "Failed to set TCP socket to ignore SIGPIPE");
kill_sock(ns, sock);
return nullptr;
}
- if (!(set_socket_nonblock(ns, sock) && connect_sock_to(logger, mem, sock, ip_port, proxy_info))) {
+ if (!set_socket_nonblock(ns, sock)) {
+ LOGGER_ERROR(logger, "Failed to set TCP socket to non-blocking");
+ kill_sock(ns, sock);
+ return nullptr;
+ }
+
+ if (!connect_sock_to(ns, logger, mem, sock, ip_port, proxy_info)) {
+ Ip_Ntoa ip_ntoa;
+ LOGGER_WARNING(logger, "Failed to connect TCP socket to %s:%u",
+ net_ip_ntoa(&ip_port->ip, &ip_ntoa), net_ntohs(ip_port->port));
kill_sock(ns, sock);
return nullptr;
}
@@ -625,6 +650,7 @@ TCP_Client_Connection *new_tcp_connection(
TCP_Client_Connection *temp = (TCP_Client_Connection *)mem_alloc(mem, sizeof(TCP_Client_Connection));
if (temp == nullptr) {
+ LOGGER_ERROR(logger, "Failed to allocate memory for TCP_Client_Connection");
kill_sock(ns, sock);
return nullptr;
}
@@ -634,6 +660,7 @@ TCP_Client_Connection *new_tcp_connection(
temp->con.rng = rng;
temp->con.sock = sock;
temp->con.ip_port = *ip_port;
+ temp->con.net_profile = net_profile;
memcpy(temp->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(temp->self_public_key, self_public_key, CRYPTO_PUBLIC_KEY_SIZE);
encrypt_precompute(temp->public_key, self_secret_key, temp->con.shared_key);
@@ -657,6 +684,7 @@ TCP_Client_Connection *new_tcp_connection(
temp->status = TCP_CLIENT_CONNECTING;
if (generate_handshake(temp) == -1) {
+ LOGGER_ERROR(logger, "Failed to generate handshake");
kill_sock(ns, sock);
mem_delete(mem, temp);
return nullptr;
@@ -819,6 +847,8 @@ static int handle_tcp_client_packet(const Logger *logger, TCP_Client_Connection
return -1;
}
+ netprof_record_packet(conn->con.net_profile, data[0], length, PACKET_DIRECTION_RECV);
+
switch (data[0]) {
case TCP_PACKET_ROUTING_RESPONSE:
return handle_tcp_client_routing_response(conn, data, length);
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_client.h b/protocols/Tox/libtox/src/toxcore/TCP_client.h
index ea2654b953..3ed6e8c683 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_client.h
+++ b/protocols/Tox/libtox/src/toxcore/TCP_client.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2014 Tox project.
*/
@@ -15,6 +15,7 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
+#include "net_profile.h"
#include "network.h"
#define TCP_CONNECTION_TIMEOUT 10
@@ -60,11 +61,11 @@ non_null()
void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value);
/** Create new TCP connection to ip_port/public_key */
-non_null(1, 2, 3, 4, 5, 6, 7, 8, 9) nullable(10)
+non_null(1, 2, 3, 4, 5, 6, 7, 8, 9) nullable(10, 11)
TCP_Client_Connection *new_tcp_connection(
const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns,
const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key,
- const TCP_Proxy_Info *proxy_info);
+ const TCP_Proxy_Info *proxy_info, Net_Profile *net_profile);
/** Run the TCP connection */
non_null(1, 2, 3) nullable(4)
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_common.c b/protocols/Tox/libtox/src/toxcore/TCP_common.c
index bd3b7ca4c7..1a8a5d9731 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_common.c
+++ b/protocols/Tox/libtox/src/toxcore/TCP_common.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2014 Tox project.
*/
@@ -35,7 +35,8 @@ int send_pending_data_nonpriority(const Logger *logger, TCP_Connection *con)
}
const uint16_t left = con->last_packet_length - con->last_packet_sent;
- const int len = net_send(con->ns, logger, con->sock, con->last_packet + con->last_packet_sent, left, &con->ip_port);
+ const int len = net_send(con->ns, logger, con->sock, con->last_packet + con->last_packet_sent, left, &con->ip_port,
+ con->net_profile);
if (len <= 0) {
return -1;
@@ -66,7 +67,7 @@ int send_pending_data(const Logger *logger, TCP_Connection *con)
while (p != nullptr) {
const uint16_t left = p->size - p->sent;
- const int len = net_send(con->ns, logger, con->sock, p->data + p->sent, left, &con->ip_port);
+ const int len = net_send(con->ns, logger, con->sock, p->data + p->sent, left, &con->ip_port, con->net_profile);
if (len != left) {
if (len > 0) {
@@ -157,14 +158,15 @@ int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con
uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE);
memcpy(packet, &c_length, sizeof(uint16_t));
- int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
+ int len = encrypt_data_symmetric(con->mem, con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
if ((unsigned int)len != (packet_size - sizeof(uint16_t))) {
return -1;
}
if (priority) {
- len = sendpriority ? net_send(con->ns, logger, con->sock, packet, packet_size, &con->ip_port) : 0;
+ len = sendpriority ? net_send(con->ns, logger, con->sock, packet, packet_size, &con->ip_port,
+ con->net_profile) : 0;
if (len <= 0) {
len = 0;
@@ -179,7 +181,7 @@ int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con
return add_priority(con, packet, packet_size, len) ? 1 : 0;
}
- len = net_send(con->ns, logger, con->sock, packet, packet_size, &con->ip_port);
+ len = net_send(con->ns, logger, con->sock, packet, packet_size, &con->ip_port, con->net_profile);
if (len <= 0) {
return 0;
@@ -234,7 +236,7 @@ int read_tcp_packet(
* return -1 on failure.
*/
non_null()
-static uint16_t read_tcp_length(const Logger *logger, const Memory *mem, const Network *ns, Socket sock, const IP_Port *ip_port)
+static uint16_t read_tcp_length(const Logger *logger, const Network *ns, Socket sock, const IP_Port *ip_port)
{
const uint16_t count = net_socket_data_recv_buffer(ns, sock);
@@ -273,7 +275,7 @@ int read_packet_tcp_secure_connection(
uint16_t max_len, const IP_Port *ip_port)
{
if (*next_packet_length == 0) {
- const uint16_t len = read_tcp_length(logger, mem, ns, sock, ip_port);
+ const uint16_t len = read_tcp_length(logger, ns, sock, ip_port);
if (len == (uint16_t) -1) {
return -1;
@@ -305,7 +307,7 @@ int read_packet_tcp_secure_connection(
*next_packet_length = 0;
- const int len = decrypt_data_symmetric(shared_key, recv_nonce, data_encrypted, len_packet, data);
+ const int len = decrypt_data_symmetric(mem, shared_key, recv_nonce, data_encrypted, len_packet, data);
if (len + CRYPTO_MAC_SIZE != len_packet) {
LOGGER_ERROR(logger, "decrypted length %d does not match expected length %d", len + CRYPTO_MAC_SIZE, len_packet);
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_common.h b/protocols/Tox/libtox/src/toxcore/TCP_common.h
index 9fa136609c..dd07fd1ec5 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_common.h
+++ b/protocols/Tox/libtox/src/toxcore/TCP_common.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2014 Tox project.
*/
@@ -10,6 +10,7 @@
#include "crypto_core.h"
#include "logger.h"
#include "mem.h"
+#include "net_profile.h"
#include "network.h"
typedef struct TCP_Priority_List TCP_Priority_List;
@@ -66,6 +67,10 @@ typedef struct TCP_Connection {
TCP_Priority_List *priority_queue_start;
TCP_Priority_List *priority_queue_end;
+
+ // This is a shared pointer to the parent's respective Net_Profile object
+ // (either TCP_Server for TCP server packets or TCP_Connections for TCP client packets).
+ Net_Profile *net_profile;
} TCP_Connection;
/**
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_connection.c b/protocols/Tox/libtox/src/toxcore/TCP_connection.c
index c7161a9289..42269ad553 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_connection.c
+++ b/protocols/Tox/libtox/src/toxcore/TCP_connection.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2015 Tox project.
*/
@@ -20,6 +20,7 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
+#include "net_profile.h"
#include "network.h"
#include "util.h"
@@ -56,6 +57,9 @@ struct TCP_Connections {
bool onion_status;
uint16_t onion_num_conns;
+
+ /* Network profile for all TCP client packets. */
+ Net_Profile *net_profile;
};
static const TCP_Connection_to empty_tcp_connection_to = {0};
@@ -928,7 +932,8 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec
uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE];
memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE);
kill_tcp_connection(tcp_con->connection);
- tcp_con->connection = new_tcp_connection(tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
+ tcp_con->connection = new_tcp_connection(tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info,
+ tcp_c->net_profile);
if (tcp_con->connection == nullptr) {
kill_tcp_relay_connection(tcp_c, tcp_connections_number);
@@ -1017,7 +1022,7 @@ static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connecti
tcp_con->connection = new_tcp_connection(
tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &tcp_con->ip_port,
- tcp_con->relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
+ tcp_con->relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info, tcp_c->net_profile);
if (tcp_con->connection == nullptr) {
kill_tcp_relay_connection(tcp_c, tcp_connections_number);
@@ -1315,7 +1320,7 @@ static int add_tcp_relay_instance(TCP_Connections *tcp_c, const IP_Port *ip_port
tcp_con->connection = new_tcp_connection(
tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ipp_copy,
- relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
+ relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info, tcp_c->net_profile);
if (tcp_con->connection == nullptr) {
return -1;
@@ -1591,7 +1596,7 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status)
* Returns NULL on failure.
*/
TCP_Connections *new_tcp_connections(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns,
- Mono_Time *mono_time, const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info)
+ Mono_Time *mono_time, const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info, Net_Profile *tcp_np)
{
assert(logger != nullptr);
assert(mem != nullptr);
@@ -1609,6 +1614,7 @@ TCP_Connections *new_tcp_connections(const Logger *logger, const Memory *mem, co
return nullptr;
}
+ temp->net_profile = tcp_np;
temp->logger = logger;
temp->mem = mem;
temp->rng = rng;
@@ -1727,3 +1733,4 @@ void kill_tcp_connections(TCP_Connections *tcp_c)
mem_delete(tcp_c->mem, tcp_c->connections);
mem_delete(tcp_c->mem, tcp_c);
}
+
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_connection.h b/protocols/Tox/libtox/src/toxcore/TCP_connection.h
index 2d35919f10..3ff2173503 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_connection.h
+++ b/protocols/Tox/libtox/src/toxcore/TCP_connection.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2015 Tox project.
*/
@@ -21,6 +21,7 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
+#include "net_profile.h"
#include "network.h"
#define TCP_CONN_NONE 0
@@ -306,7 +307,7 @@ uint32_t tcp_copy_connected_relays_index(const TCP_Connections *tcp_c, Node_form
*/
non_null()
TCP_Connections *new_tcp_connections(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns,
- Mono_Time *mono_time, const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info);
+ Mono_Time *mono_time, const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info, Net_Profile *tcp_np);
non_null()
int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number);
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_server.c b/protocols/Tox/libtox/src/toxcore/TCP_server.c
index 1363d90220..288cd94c48 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_server.c
+++ b/protocols/Tox/libtox/src/toxcore/TCP_server.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2014 Tox project.
*/
@@ -27,6 +27,7 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
+#include "net_profile.h"
#include "network.h"
#include "onion.h"
@@ -91,6 +92,9 @@ struct TCP_Server {
uint64_t counter;
BS_List accepted_key_list;
+
+ /* Network profile for all TCP server packets. */
+ Net_Profile *net_profile;
};
static_assert(sizeof(TCP_Server) < 7 * 1024 * 1024,
@@ -236,6 +240,7 @@ static int add_accepted(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_
tcp_server->accepted_connection_array[index].identifier = ++tcp_server->counter;
tcp_server->accepted_connection_array[index].last_pinged = mono_time_get(mono_time);
tcp_server->accepted_connection_array[index].ping_id = 0;
+ tcp_server->accepted_connection_array[index].con.net_profile = tcp_server->net_profile;
return index;
}
@@ -327,7 +332,7 @@ static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
encrypt_precompute(data, self_secret_key, shared_key);
uint8_t plain[TCP_HANDSHAKE_PLAIN_SIZE];
- int len = decrypt_data_symmetric(shared_key, data + CRYPTO_PUBLIC_KEY_SIZE,
+ int len = decrypt_data_symmetric(con->con.mem, shared_key, data + CRYPTO_PUBLIC_KEY_SIZE,
data + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE, plain);
if (len != TCP_HANDSHAKE_PLAIN_SIZE) {
@@ -347,7 +352,7 @@ static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con
uint8_t response[TCP_SERVER_HANDSHAKE_SIZE];
random_nonce(con->con.rng, response);
- len = encrypt_data_symmetric(shared_key, response, resp_plain, TCP_HANDSHAKE_PLAIN_SIZE,
+ len = encrypt_data_symmetric(con->con.mem, shared_key, response, resp_plain, TCP_HANDSHAKE_PLAIN_SIZE,
response + CRYPTO_NONCE_SIZE);
if (len != TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE) {
@@ -357,7 +362,7 @@ static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con
const IP_Port ipp = {{{0}}};
- if (TCP_SERVER_HANDSHAKE_SIZE != net_send(con->con.ns, logger, con->con.sock, response, TCP_SERVER_HANDSHAKE_SIZE, &ipp)) {
+ if (TCP_SERVER_HANDSHAKE_SIZE != net_send(con->con.ns, logger, con->con.sock, response, TCP_SERVER_HANDSHAKE_SIZE, &ipp, con->con.net_profile)) {
crypto_memzero(shared_key, sizeof(shared_key));
return -1;
}
@@ -680,6 +685,7 @@ static int handle_tcp_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
}
TCP_Secure_Connection *const con = &tcp_server->accepted_connection_array[con_id];
+ netprof_record_packet(con->con.net_profile, data[0], length, PACKET_DIRECTION_RECV);
switch (data[0]) {
case TCP_PACKET_ROUTING_REQUEST: {
@@ -914,7 +920,7 @@ static int accept_connection(TCP_Server *tcp_server, Socket sock)
}
non_null()
-static Socket new_listening_tcp_socket(const Logger *logger, const Network *ns, Family family, uint16_t port)
+static Socket new_listening_tcp_socket(const Logger *logger, const Memory *mem, const Network *ns, Family family, uint16_t port)
{
const Socket sock = net_socket(ns, family, TOX_SOCK_STREAM, TOX_PROTO_TCP);
@@ -936,10 +942,9 @@ static Socket new_listening_tcp_socket(const Logger *logger, const Network *ns,
ok = ok && bind_to_port(ns, sock, family, port) && (net_listen(ns, sock, TCP_MAX_BACKLOG) == 0);
if (!ok) {
- char *const error = net_new_strerror(net_error());
+ Net_Strerror error_str;
LOGGER_WARNING(logger, "could not bind to TCP port %d (family = %d): %s",
- port, family.value, error != nullptr ? error : "(null)");
- net_kill_strerror(error);
+ port, family.value, net_strerror(net_error(), &error_str));
kill_sock(ns, sock);
return net_invalid_socket();
}
@@ -969,6 +974,14 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
return nullptr;
}
+ Net_Profile *np = netprof_new(logger, mem);
+
+ if (np == nullptr) {
+ mem_delete(mem, temp);
+ return nullptr;
+ }
+
+ temp->net_profile = np;
temp->logger = logger;
temp->mem = mem;
temp->ns = ns;
@@ -978,6 +991,7 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
if (socks_listening == nullptr) {
LOGGER_ERROR(logger, "socket allocation failed");
+ netprof_kill(mem, temp->net_profile);
mem_delete(mem, temp);
return nullptr;
}
@@ -989,6 +1003,7 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
if (temp->efd == -1) {
LOGGER_ERROR(logger, "epoll initialisation failed");
+ netprof_kill(mem, temp->net_profile);
mem_delete(mem, socks_listening);
mem_delete(mem, temp);
return nullptr;
@@ -999,7 +1014,7 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
const Family family = ipv6_enabled ? net_family_ipv6() : net_family_ipv4();
for (uint32_t i = 0; i < num_sockets; ++i) {
- const Socket sock = new_listening_tcp_socket(logger, ns, family, ports[i]);
+ const Socket sock = new_listening_tcp_socket(logger, mem, ns, family, ports[i]);
if (!sock_valid(sock)) {
continue;
@@ -1022,6 +1037,7 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
}
if (temp->num_listening_socks == 0) {
+ netprof_kill(mem, temp->net_profile);
mem_delete(mem, temp->socks_listening);
mem_delete(mem, temp);
return nullptr;
@@ -1040,7 +1056,7 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
memcpy(temp->secret_key, secret_key, CRYPTO_SECRET_KEY_SIZE);
crypto_derive_public_key(temp->public_key, temp->secret_key);
- bs_list_init(&temp->accepted_key_list, CRYPTO_PUBLIC_KEY_SIZE, 8, memcmp);
+ bs_list_init(&temp->accepted_key_list, mem, CRYPTO_PUBLIC_KEY_SIZE, 8, memcmp);
return temp;
}
@@ -1422,6 +1438,16 @@ void kill_tcp_server(TCP_Server *tcp_server)
crypto_memzero(tcp_server->secret_key, sizeof(tcp_server->secret_key));
+ netprof_kill(tcp_server->mem, tcp_server->net_profile);
mem_delete(tcp_server->mem, tcp_server->socks_listening);
mem_delete(tcp_server->mem, tcp_server);
}
+
+const Net_Profile *tcp_server_get_net_profile(const TCP_Server *tcp_server)
+{
+ if (tcp_server == nullptr) {
+ return nullptr;
+ }
+
+ return tcp_server->net_profile;
+}
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_server.h b/protocols/Tox/libtox/src/toxcore/TCP_server.h
index 1d3933a415..bd4c98b0cd 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_server.h
+++ b/protocols/Tox/libtox/src/toxcore/TCP_server.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2014 Tox project.
*/
@@ -15,6 +15,7 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
+#include "net_profile.h"
#include "network.h"
#include "onion.h"
@@ -52,4 +53,11 @@ void do_tcp_server(TCP_Server *tcp_server, const Mono_Time *mono_time);
nullable(1)
void kill_tcp_server(TCP_Server *tcp_server);
+/** @brief Returns a pointer to the net profile associated with `tcp_server`.
+ *
+ * Returns null if `tcp_server` is null.
+ */
+nullable(1)
+const Net_Profile *tcp_server_get_net_profile(const TCP_Server *tcp_server);
+
#endif /* C_TOXCORE_TOXCORE_TCP_SERVER_H */
diff --git a/protocols/Tox/libtox/src/toxcore/announce.c b/protocols/Tox/libtox/src/toxcore/announce.c
index b983cb0574..dc34ca05e3 100644
--- a/protocols/Tox/libtox/src/toxcore/announce.c
+++ b/protocols/Tox/libtox/src/toxcore/announce.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2020-2021 The TokTok team.
+ * Copyright © 2020-2025 The TokTok team.
*/
/**
@@ -9,7 +9,6 @@
#include "announce.h"
#include <assert.h>
-#include <stdlib.h>
#include <string.h>
#include "DHT.h"
@@ -239,9 +238,9 @@ bool announce_store_data(Announcements *announce, const uint8_t *data_public_key
if (length > 0) {
assert(data != nullptr);
- free(entry->data);
+ mem_delete(announce->mem, entry->data);
- uint8_t *entry_data = (uint8_t *)malloc(length);
+ uint8_t *entry_data = (uint8_t *)mem_balloc(announce->mem, length);
if (entry_data == nullptr) {
entry->data = nullptr; // TODO(iphydf): Is this necessary?
@@ -451,7 +450,7 @@ static int create_reply_plain_store_announce_request(Announcements *announce,
return -1;
}
- if (decrypt_data_symmetric(shared_key,
+ if (decrypt_data_symmetric(announce->mem, shared_key,
data + CRYPTO_PUBLIC_KEY_SIZE,
data + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
plain_len + CRYPTO_MAC_SIZE,
@@ -568,7 +567,7 @@ static int create_reply(Announcements *announce, const IP_Port *source,
VLA(uint8_t, plain, plain_len);
const uint8_t *shared_key = dht_get_shared_key_recv(announce->dht, data + 1);
- if (decrypt_data_symmetric(shared_key,
+ if (decrypt_data_symmetric(announce->mem, shared_key,
data + 1 + CRYPTO_PUBLIC_KEY_SIZE,
data + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
plain_len + CRYPTO_MAC_SIZE,
@@ -579,7 +578,7 @@ static int create_reply(Announcements *announce, const IP_Port *source,
const int plain_reply_max_len = (int)reply_max_length -
(1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE);
- if (plain_reply_max_len < sizeof(uint64_t)) {
+ if (plain_reply_max_len < (int)sizeof(uint64_t)) {
return -1;
}
@@ -651,7 +650,7 @@ Announcements *new_announcements(const Logger *log, const Memory *mem, const Ran
return nullptr;
}
- Announcements *announce = (Announcements *)calloc(1, sizeof(Announcements));
+ Announcements *announce = (Announcements *)mem_alloc(mem, sizeof(Announcements));
if (announce == nullptr) {
return nullptr;
@@ -669,7 +668,7 @@ Announcements *new_announcements(const Logger *log, const Memory *mem, const Ran
new_hmac_key(announce->rng, announce->hmac_key);
announce->shared_keys = shared_key_cache_new(log, mono_time, mem, announce->secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
if (announce->shared_keys == nullptr) {
- free(announce);
+ mem_delete(announce->mem, announce);
return nullptr;
}
@@ -700,8 +699,8 @@ void kill_announcements(Announcements *announce)
shared_key_cache_free(announce->shared_keys);
for (uint32_t i = 0; i < ANNOUNCE_BUCKETS * ANNOUNCE_BUCKET_SIZE; ++i) {
- free(announce->entries[i].data);
+ mem_delete(announce->mem, announce->entries[i].data);
}
- free(announce);
+ mem_delete(announce->mem, announce);
}
diff --git a/protocols/Tox/libtox/src/toxcore/announce.h b/protocols/Tox/libtox/src/toxcore/announce.h
index bd05088d06..c1397454ac 100644
--- a/protocols/Tox/libtox/src/toxcore/announce.h
+++ b/protocols/Tox/libtox/src/toxcore/announce.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2020-2021 The TokTok team.
+ * Copyright © 2020-2025 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_ANNOUNCE_H
diff --git a/protocols/Tox/libtox/src/toxcore/attributes.h b/protocols/Tox/libtox/src/toxcore/attributes.h
index 087efe20dc..009dfa359e 100644
--- a/protocols/Tox/libtox/src/toxcore/attributes.h
+++ b/protocols/Tox/libtox/src/toxcore/attributes.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
/**
diff --git a/protocols/Tox/libtox/src/toxcore/bin_pack.c b/protocols/Tox/libtox/src/toxcore/bin_pack.c
index 56bdc9ec75..82e9d20dd4 100644
--- a/protocols/Tox/libtox/src/toxcore/bin_pack.c
+++ b/protocols/Tox/libtox/src/toxcore/bin_pack.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#include "bin_pack.h"
diff --git a/protocols/Tox/libtox/src/toxcore/bin_pack.h b/protocols/Tox/libtox/src/toxcore/bin_pack.h
index ce6926a448..4b2927f972 100644
--- a/protocols/Tox/libtox/src/toxcore/bin_pack.h
+++ b/protocols/Tox/libtox/src/toxcore/bin_pack.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_BIN_PACK_H
#define C_TOXCORE_TOXCORE_BIN_PACK_H
diff --git a/protocols/Tox/libtox/src/toxcore/bin_unpack.c b/protocols/Tox/libtox/src/toxcore/bin_unpack.c
index d6b1c52ea5..e3110946bf 100644
--- a/protocols/Tox/libtox/src/toxcore/bin_unpack.c
+++ b/protocols/Tox/libtox/src/toxcore/bin_unpack.c
@@ -1,18 +1,20 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#include "bin_unpack.h"
#include <assert.h>
-#include <stdlib.h>
#include <string.h>
#include "../third_party/cmp/cmp.h"
#include "attributes.h"
#include "ccompat.h"
+#include "mem.h"
struct Bin_Unpack {
+ const Memory *mem;
+
const uint8_t *bytes;
uint32_t bytes_size;
cmp_ctx_t ctx;
@@ -54,17 +56,18 @@ static size_t null_writer(cmp_ctx_t *ctx, const void *data, size_t count)
}
non_null()
-static void bin_unpack_init(Bin_Unpack *bu, const uint8_t *buf, uint32_t buf_size)
+static void bin_unpack_init(Bin_Unpack *bu, const Memory *mem, const uint8_t *buf, uint32_t buf_size)
{
+ bu->mem = mem;
bu->bytes = buf;
bu->bytes_size = buf_size;
cmp_init(&bu->ctx, bu, buf_reader, buf_skipper, null_writer);
}
-bool bin_unpack_obj(bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size)
+bool bin_unpack_obj(const Memory *mem, bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size)
{
Bin_Unpack bu;
- bin_unpack_init(&bu, buf, buf_size);
+ bin_unpack_init(&bu, mem, buf, buf_size);
return callback(obj, &bu);
}
@@ -120,10 +123,14 @@ bool bin_unpack_bin(Bin_Unpack *bu, uint8_t **data_ptr, uint32_t *data_length_pt
// There aren't as many bytes as this bin claims to want to allocate.
return false;
}
- uint8_t *const data = (uint8_t *)malloc(bin_size);
+ uint8_t *const data = (uint8_t *)mem_balloc(bu->mem, bin_size);
+
+ if (data == nullptr) {
+ return false;
+ }
if (!bin_unpack_bin_b(bu, data, bin_size)) {
- free(data);
+ mem_delete(bu->mem, data);
return false;
}
diff --git a/protocols/Tox/libtox/src/toxcore/bin_unpack.h b/protocols/Tox/libtox/src/toxcore/bin_unpack.h
index 0554bd1a7a..029c3a0d0a 100644
--- a/protocols/Tox/libtox/src/toxcore/bin_unpack.h
+++ b/protocols/Tox/libtox/src/toxcore/bin_unpack.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_BIN_UNPACK_H
@@ -9,6 +9,7 @@
#include <stdint.h>
#include "attributes.h"
+#include "mem.h"
#ifdef __cplusplus
extern "C" {
@@ -46,7 +47,7 @@ typedef bool bin_unpack_cb(void *obj, Bin_Unpack *bu);
* @retval false if an error occurred (e.g. buffer overrun).
*/
non_null()
-bool bin_unpack_obj(bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size);
+bool bin_unpack_obj(const Memory *mem, bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size);
/** @brief Start unpacking a MessagePack array.
*
diff --git a/protocols/Tox/libtox/src/toxcore/ccompat.c b/protocols/Tox/libtox/src/toxcore/ccompat.c
index 6e4689736a..3ac18a270e 100644
--- a/protocols/Tox/libtox/src/toxcore/ccompat.c
+++ b/protocols/Tox/libtox/src/toxcore/ccompat.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#include "ccompat.h"
diff --git a/protocols/Tox/libtox/src/toxcore/ccompat.h b/protocols/Tox/libtox/src/toxcore/ccompat.h
index 47ab9ed2bf..df68413741 100644
--- a/protocols/Tox/libtox/src/toxcore/ccompat.h
+++ b/protocols/Tox/libtox/src/toxcore/ccompat.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2021 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
*/
/**
diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.c b/protocols/Tox/libtox/src/toxcore/crypto_core.c
index 7bb5bb929f..8a6aa38fba 100644
--- a/protocols/Tox/libtox/src/toxcore/crypto_core.c
+++ b/protocols/Tox/libtox/src/toxcore/crypto_core.c
@@ -1,18 +1,18 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2024 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
#include "crypto_core.h"
#include <assert.h>
-#include <stdlib.h>
#include <string.h>
#include <sodium.h>
#include "attributes.h"
#include "ccompat.h"
+#include "mem.h"
#include "util.h"
static_assert(CRYPTO_PUBLIC_KEY_SIZE == crypto_box_PUBLICKEYBYTES,
@@ -88,9 +88,10 @@ const uint8_t *get_chat_id(const Extended_Public_Key *key)
}
#if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
-static uint8_t *crypto_malloc(size_t bytes)
+non_null()
+static uint8_t *crypto_malloc(const Memory *mem, size_t bytes)
{
- uint8_t *ptr = (uint8_t *)malloc(bytes);
+ uint8_t *ptr = (uint8_t *)mem_balloc(mem, bytes);
if (ptr != nullptr) {
crypto_memlock(ptr, bytes);
@@ -99,15 +100,15 @@ static uint8_t *crypto_malloc(size_t bytes)
return ptr;
}
-nullable(1)
-static void crypto_free(uint8_t *ptr, size_t bytes)
+non_null(1) nullable(2)
+static void crypto_free(const Memory *mem, uint8_t *ptr, size_t bytes)
{
if (ptr != nullptr) {
crypto_memzero(ptr, bytes);
crypto_memunlock(ptr, bytes);
}
- free(ptr);
+ mem_delete(mem, ptr);
}
#endif /* !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) */
@@ -240,7 +241,8 @@ int32_t encrypt_precompute(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
}
-int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
+int32_t encrypt_data_symmetric(const Memory *mem,
+ const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *plain, size_t length, uint8_t *encrypted)
{
@@ -258,12 +260,12 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
const size_t size_temp_plain = length + crypto_box_ZEROBYTES;
const size_t size_temp_encrypted = length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES;
- uint8_t *temp_plain = crypto_malloc(size_temp_plain);
- uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted);
+ uint8_t *temp_plain = crypto_malloc(mem, size_temp_plain);
+ uint8_t *temp_encrypted = crypto_malloc(mem, size_temp_encrypted);
if (temp_plain == nullptr || temp_encrypted == nullptr) {
- crypto_free(temp_plain, size_temp_plain);
- crypto_free(temp_encrypted, size_temp_encrypted);
+ crypto_free(mem, temp_plain, size_temp_plain);
+ crypto_free(mem, temp_encrypted, size_temp_encrypted);
return -1;
}
@@ -278,22 +280,23 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce,
shared_key) != 0) {
- crypto_free(temp_plain, size_temp_plain);
- crypto_free(temp_encrypted, size_temp_encrypted);
+ crypto_free(mem, temp_plain, size_temp_plain);
+ crypto_free(mem, temp_encrypted, size_temp_encrypted);
return -1;
}
// Unpad the encrypted message.
memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES);
- crypto_free(temp_plain, size_temp_plain);
- crypto_free(temp_encrypted, size_temp_encrypted);
+ crypto_free(mem, temp_plain, size_temp_plain);
+ crypto_free(mem, temp_encrypted, size_temp_encrypted);
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
assert(length < INT32_MAX - crypto_box_MACBYTES);
return (int32_t)(length + crypto_box_MACBYTES);
}
-int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
+int32_t decrypt_data_symmetric(const Memory *mem,
+ const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *encrypted, size_t length, uint8_t *plain)
{
@@ -310,12 +313,12 @@ int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
const size_t size_temp_plain = length + crypto_box_ZEROBYTES;
const size_t size_temp_encrypted = length + crypto_box_BOXZEROBYTES;
- uint8_t *temp_plain = crypto_malloc(size_temp_plain);
- uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted);
+ uint8_t *temp_plain = crypto_malloc(mem, size_temp_plain);
+ uint8_t *temp_encrypted = crypto_malloc(mem, size_temp_encrypted);
if (temp_plain == nullptr || temp_encrypted == nullptr) {
- crypto_free(temp_plain, size_temp_plain);
- crypto_free(temp_encrypted, size_temp_encrypted);
+ crypto_free(mem, temp_plain, size_temp_plain);
+ crypto_free(mem, temp_encrypted, size_temp_encrypted);
return -1;
}
@@ -330,22 +333,23 @@ int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce,
shared_key) != 0) {
- crypto_free(temp_plain, size_temp_plain);
- crypto_free(temp_encrypted, size_temp_encrypted);
+ crypto_free(mem, temp_plain, size_temp_plain);
+ crypto_free(mem, temp_encrypted, size_temp_encrypted);
return -1;
}
memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES);
- crypto_free(temp_plain, size_temp_plain);
- crypto_free(temp_encrypted, size_temp_encrypted);
+ crypto_free(mem, temp_plain, size_temp_plain);
+ crypto_free(mem, temp_encrypted, size_temp_encrypted);
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
assert(length > crypto_box_MACBYTES);
assert(length < INT32_MAX);
return (int32_t)(length - crypto_box_MACBYTES);
}
-int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
+int32_t encrypt_data(const Memory *mem,
+ const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *plain, size_t length, uint8_t *encrypted)
@@ -356,12 +360,13 @@ int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
uint8_t k[crypto_box_BEFORENMBYTES];
encrypt_precompute(public_key, secret_key, k);
- const int ret = encrypt_data_symmetric(k, nonce, plain, length, encrypted);
+ const int ret = encrypt_data_symmetric(mem, k, nonce, plain, length, encrypted);
crypto_memzero(k, sizeof(k));
return ret;
}
-int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
+int32_t decrypt_data(const Memory *mem,
+ const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *encrypted, size_t length, uint8_t *plain)
@@ -372,7 +377,7 @@ int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
uint8_t k[crypto_box_BEFORENMBYTES];
encrypt_precompute(public_key, secret_key, k);
- const int ret = decrypt_data_symmetric(k, nonce, encrypted, length, plain);
+ const int ret = decrypt_data_symmetric(mem, k, nonce, encrypted, length, plain);
crypto_memzero(k, sizeof(k));
return ret;
}
diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.h b/protocols/Tox/libtox/src/toxcore/crypto_core.h
index 979791bd97..558118e397 100644
--- a/protocols/Tox/libtox/src/toxcore/crypto_core.h
+++ b/protocols/Tox/libtox/src/toxcore/crypto_core.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2024 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -16,6 +16,7 @@
#include <stdint.h>
#include "attributes.h"
+#include "mem.h"
#ifdef __cplusplus
extern "C" {
@@ -386,7 +387,8 @@ void crypto_derive_public_key(uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
* @return length of encrypted data if everything was fine.
*/
non_null()
-int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
+int32_t encrypt_data(const Memory *mem,
+ const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *plain, size_t length, uint8_t *encrypted);
@@ -403,7 +405,8 @@ int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
* @return length of plain text data if everything was fine.
*/
non_null()
-int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
+int32_t decrypt_data(const Memory *mem,
+ const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *encrypted, size_t length, uint8_t *plain);
@@ -431,7 +434,8 @@ int32_t encrypt_precompute(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
* @return length of encrypted data if everything was fine.
*/
non_null()
-int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
+int32_t encrypt_data_symmetric(const Memory *mem,
+ const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *plain, size_t length, uint8_t *encrypted);
@@ -446,7 +450,8 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
* @return length of plain data if everything was fine.
*/
non_null()
-int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
+int32_t decrypt_data_symmetric(const Memory *mem,
+ const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *encrypted, size_t length, uint8_t *plain);
diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core_pack.c b/protocols/Tox/libtox/src/toxcore/crypto_core_pack.c
index a173d39d8d..4c08fc7d2a 100644
--- a/protocols/Tox/libtox/src/toxcore/crypto_core_pack.c
+++ b/protocols/Tox/libtox/src/toxcore/crypto_core_pack.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2024 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core_pack.h b/protocols/Tox/libtox/src/toxcore/crypto_core_pack.h
index 1efefff840..85b47ff4e4 100644
--- a/protocols/Tox/libtox/src/toxcore/crypto_core_pack.h
+++ b/protocols/Tox/libtox/src/toxcore/crypto_core_pack.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2024 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
diff --git a/protocols/Tox/libtox/src/toxcore/events/conference_connected.c b/protocols/Tox/libtox/src/toxcore/events/conference_connected.c
index dbd9e4b51a..d19f0191a2 100644
--- a/protocols/Tox/libtox/src/toxcore/events/conference_connected.c
+++ b/protocols/Tox/libtox/src/toxcore/events/conference_connected.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -109,7 +110,10 @@ static Tox_Event_Conference_Connected *tox_events_add_conference_connected(Tox_E
event.type = TOX_EVENT_CONFERENCE_CONNECTED;
event.data.conference_connected = conference_connected;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_conference_connected_free(conference_connected, mem);
+ return nullptr;
+ }
return conference_connected;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/conference_invite.c b/protocols/Tox/libtox/src/toxcore/events/conference_invite.c
index fb1f794bf3..04206e768f 100644
--- a/protocols/Tox/libtox/src/toxcore/events/conference_invite.c
+++ b/protocols/Tox/libtox/src/toxcore/events/conference_invite.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -177,7 +178,10 @@ static Tox_Event_Conference_Invite *tox_events_add_conference_invite(Tox_Events
event.type = TOX_EVENT_CONFERENCE_INVITE;
event.data.conference_invite = conference_invite;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_conference_invite_free(conference_invite, mem);
+ return nullptr;
+ }
return conference_invite;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/conference_message.c b/protocols/Tox/libtox/src/toxcore/events/conference_message.c
index 74e1123e01..7cef201a35 100644
--- a/protocols/Tox/libtox/src/toxcore/events/conference_message.c
+++ b/protocols/Tox/libtox/src/toxcore/events/conference_message.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -193,7 +194,10 @@ static Tox_Event_Conference_Message *tox_events_add_conference_message(Tox_Event
event.type = TOX_EVENT_CONFERENCE_MESSAGE;
event.data.conference_message = conference_message;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_conference_message_free(conference_message, mem);
+ return nullptr;
+ }
return conference_message;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/conference_peer_list_changed.c b/protocols/Tox/libtox/src/toxcore/events/conference_peer_list_changed.c
index 050bfb08f8..68744208d6 100644
--- a/protocols/Tox/libtox/src/toxcore/events/conference_peer_list_changed.c
+++ b/protocols/Tox/libtox/src/toxcore/events/conference_peer_list_changed.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -109,7 +110,10 @@ static Tox_Event_Conference_Peer_List_Changed *tox_events_add_conference_peer_li
event.type = TOX_EVENT_CONFERENCE_PEER_LIST_CHANGED;
event.data.conference_peer_list_changed = conference_peer_list_changed;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_conference_peer_list_changed_free(conference_peer_list_changed, mem);
+ return nullptr;
+ }
return conference_peer_list_changed;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/conference_peer_name.c b/protocols/Tox/libtox/src/toxcore/events/conference_peer_name.c
index fc6c255791..36de6ba9c2 100644
--- a/protocols/Tox/libtox/src/toxcore/events/conference_peer_name.c
+++ b/protocols/Tox/libtox/src/toxcore/events/conference_peer_name.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -175,7 +176,10 @@ static Tox_Event_Conference_Peer_Name *tox_events_add_conference_peer_name(Tox_E
event.type = TOX_EVENT_CONFERENCE_PEER_NAME;
event.data.conference_peer_name = conference_peer_name;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_conference_peer_name_free(conference_peer_name, mem);
+ return nullptr;
+ }
return conference_peer_name;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/conference_title.c b/protocols/Tox/libtox/src/toxcore/events/conference_title.c
index d761f51285..cd92ba1651 100644
--- a/protocols/Tox/libtox/src/toxcore/events/conference_title.c
+++ b/protocols/Tox/libtox/src/toxcore/events/conference_title.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -175,7 +176,10 @@ static Tox_Event_Conference_Title *tox_events_add_conference_title(Tox_Events *e
event.type = TOX_EVENT_CONFERENCE_TITLE;
event.data.conference_title = conference_title;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_conference_title_free(conference_title, mem);
+ return nullptr;
+ }
return conference_title;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/dht_get_nodes_response.c b/protocols/Tox/libtox/src/toxcore/events/dht_get_nodes_response.c
deleted file mode 100644
index 6e03b73ea4..0000000000
--- a/protocols/Tox/libtox/src/toxcore/events/dht_get_nodes_response.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
- */
-
-#include "events_alloc.h"
-
-#include <assert.h>
-#include <string.h>
-
-#include "../attributes.h"
-#include "../bin_pack.h"
-#include "../bin_unpack.h"
-#include "../ccompat.h"
-#include "../mem.h"
-#include "../tox.h"
-#include "../tox_events.h"
-#include "../tox_private.h"
-
-/*****************************************************
- *
- * :: struct and accessors
- *
- *****************************************************/
-
-struct Tox_Event_Dht_Get_Nodes_Response {
- uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
- uint8_t *ip;
- uint32_t ip_length;
- uint16_t port;
-};
-
-non_null()
-static bool tox_event_dht_get_nodes_response_set_public_key(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE])
-{
- memcpy(dht_get_nodes_response->public_key, public_key, TOX_PUBLIC_KEY_SIZE);
- return true;
-}
-const uint8_t *tox_event_dht_get_nodes_response_get_public_key(const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response)
-{
- return dht_get_nodes_response->public_key;
-}
-
-non_null()
-static bool tox_event_dht_get_nodes_response_set_ip(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response,
- const char *ip, uint32_t ip_length, const Memory *mem)
-{
- if (dht_get_nodes_response->ip != nullptr) {
- mem_delete(mem, dht_get_nodes_response->ip);
- dht_get_nodes_response->ip = nullptr;
- dht_get_nodes_response->ip_length = 0;
- }
-
- uint8_t *ip_tmp = (uint8_t *)mem_balloc(mem, ip_length);
-
- if (ip_tmp == nullptr) {
- return false;
- }
-
- memcpy(ip_tmp, ip, ip_length);
- dht_get_nodes_response->ip = ip_tmp;
- dht_get_nodes_response->ip_length = ip_length;
- return true;
-}
-uint32_t tox_event_dht_get_nodes_response_get_ip_length(const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response)
-{
- return dht_get_nodes_response->ip_length;
-}
-const uint8_t *tox_event_dht_get_nodes_response_get_ip(const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response)
-{
- return dht_get_nodes_response->ip;
-}
-
-non_null()
-static bool tox_event_dht_get_nodes_response_set_port(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, uint16_t port)
-{
- dht_get_nodes_response->port = port;
- return true;
-}
-uint16_t tox_event_dht_get_nodes_response_get_port(const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response)
-{
- return dht_get_nodes_response->port;
-}
-
-non_null()
-static void tox_event_dht_get_nodes_response_construct(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response)
-{
- *dht_get_nodes_response = (Tox_Event_Dht_Get_Nodes_Response) {
- {
- 0
- }
- };
-}
-non_null()
-static void tox_event_dht_get_nodes_response_destruct(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, const Memory *mem)
-{
- mem_delete(mem, dht_get_nodes_response->ip);
-}
-
-bool tox_event_dht_get_nodes_response_pack(
- const Tox_Event_Dht_Get_Nodes_Response *event, Bin_Pack *bp)
-{
- return bin_pack_array(bp, 3)
- && bin_pack_bin(bp, event->public_key, TOX_PUBLIC_KEY_SIZE)
- && bin_pack_bin(bp, event->ip, event->ip_length)
- && bin_pack_u16(bp, event->port);
-}
-
-non_null()
-static bool tox_event_dht_get_nodes_response_unpack_into(
- Tox_Event_Dht_Get_Nodes_Response *event, Bin_Unpack *bu)
-{
- if (!bin_unpack_array_fixed(bu, 3, nullptr)) {
- return false;
- }
-
- return bin_unpack_bin_fixed(bu, event->public_key, TOX_PUBLIC_KEY_SIZE)
- && bin_unpack_bin(bu, &event->ip, &event->ip_length)
- && bin_unpack_u16(bu, &event->port);
-}
-
-const Tox_Event_Dht_Get_Nodes_Response *tox_event_get_dht_get_nodes_response(
- const Tox_Event *event)
-{
- return event->type == TOX_EVENT_DHT_GET_NODES_RESPONSE ? event->data.dht_get_nodes_response : nullptr;
-}
-
-Tox_Event_Dht_Get_Nodes_Response *tox_event_dht_get_nodes_response_new(const Memory *mem)
-{
- Tox_Event_Dht_Get_Nodes_Response *const dht_get_nodes_response =
- (Tox_Event_Dht_Get_Nodes_Response *)mem_alloc(mem, sizeof(Tox_Event_Dht_Get_Nodes_Response));
-
- if (dht_get_nodes_response == nullptr) {
- return nullptr;
- }
-
- tox_event_dht_get_nodes_response_construct(dht_get_nodes_response);
- return dht_get_nodes_response;
-}
-
-void tox_event_dht_get_nodes_response_free(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, const Memory *mem)
-{
- if (dht_get_nodes_response != nullptr) {
- tox_event_dht_get_nodes_response_destruct(dht_get_nodes_response, mem);
- }
- mem_delete(mem, dht_get_nodes_response);
-}
-
-non_null()
-static Tox_Event_Dht_Get_Nodes_Response *tox_events_add_dht_get_nodes_response(Tox_Events *events, const Memory *mem)
-{
- Tox_Event_Dht_Get_Nodes_Response *const dht_get_nodes_response = tox_event_dht_get_nodes_response_new(mem);
-
- if (dht_get_nodes_response == nullptr) {
- return nullptr;
- }
-
- Tox_Event event;
- event.type = TOX_EVENT_DHT_GET_NODES_RESPONSE;
- event.data.dht_get_nodes_response = dht_get_nodes_response;
-
- tox_events_add(events, &event);
- return dht_get_nodes_response;
-}
-
-bool tox_event_dht_get_nodes_response_unpack(
- Tox_Event_Dht_Get_Nodes_Response **event, Bin_Unpack *bu, const Memory *mem)
-{
- *event = tox_event_dht_get_nodes_response_new(mem);
-
- if (*event == nullptr) {
- return false;
- }
-
- return tox_event_dht_get_nodes_response_unpack_into(*event, bu);
-}
-
-non_null()
-static Tox_Event_Dht_Get_Nodes_Response *tox_event_dht_get_nodes_response_alloc(void *user_data)
-{
- Tox_Events_State *state = tox_events_alloc(user_data);
- assert(state != nullptr);
-
- if (state->events == nullptr) {
- return nullptr;
- }
-
- Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response = tox_events_add_dht_get_nodes_response(state->events, state->mem);
-
- if (dht_get_nodes_response == nullptr) {
- state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
- return nullptr;
- }
-
- return dht_get_nodes_response;
-}
-
-/*****************************************************
- *
- * :: event handler
- *
- *****************************************************/
-
-void tox_events_handle_dht_get_nodes_response(
- Tox *tox, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE],
- const char *ip, uint16_t port, void *user_data)
-{
- Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response = tox_event_dht_get_nodes_response_alloc(user_data);
-
- if (dht_get_nodes_response == nullptr) {
- return;
- }
-
- const size_t ip_length = strlen(ip);
- if (ip_length >= UINT32_MAX) {
- return;
- }
-
- const Tox_System *sys = tox_get_system(tox);
-
- tox_event_dht_get_nodes_response_set_public_key(dht_get_nodes_response, public_key);
- tox_event_dht_get_nodes_response_set_ip(dht_get_nodes_response, ip, ip_length + 1, sys->mem);
- tox_event_dht_get_nodes_response_set_port(dht_get_nodes_response, port);
-}
diff --git a/protocols/Tox/libtox/src/toxcore/events/dht_nodes_response.c b/protocols/Tox/libtox/src/toxcore/events/dht_nodes_response.c
new file mode 100644
index 0000000000..7a3f5f2730
--- /dev/null
+++ b/protocols/Tox/libtox/src/toxcore/events/dht_nodes_response.c
@@ -0,0 +1,222 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright © 2022-2025 The TokTok team.
+ */
+
+#include "events_alloc.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include "../attributes.h"
+#include "../bin_pack.h"
+#include "../bin_unpack.h"
+#include "../ccompat.h"
+#include "../mem.h"
+#include "../tox.h"
+#include "../tox_event.h"
+#include "../tox_events.h"
+#include "../tox_private.h"
+
+/*****************************************************
+ *
+ * :: struct and accessors
+ *
+ *****************************************************/
+
+struct Tox_Event_Dht_Nodes_Response {
+ uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
+ uint8_t *ip;
+ uint32_t ip_length;
+ uint16_t port;
+};
+
+non_null()
+static bool tox_event_dht_nodes_response_set_public_key(Tox_Event_Dht_Nodes_Response *dht_nodes_response, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE])
+{
+ memcpy(dht_nodes_response->public_key, public_key, TOX_PUBLIC_KEY_SIZE);
+ return true;
+}
+const uint8_t *tox_event_dht_nodes_response_get_public_key(const Tox_Event_Dht_Nodes_Response *dht_nodes_response)
+{
+ return dht_nodes_response->public_key;
+}
+
+non_null()
+static bool tox_event_dht_nodes_response_set_ip(Tox_Event_Dht_Nodes_Response *dht_nodes_response,
+ const char *ip, uint32_t ip_length, const Memory *mem)
+{
+ if (dht_nodes_response->ip != nullptr) {
+ mem_delete(mem, dht_nodes_response->ip);
+ dht_nodes_response->ip = nullptr;
+ dht_nodes_response->ip_length = 0;
+ }
+
+ uint8_t *ip_tmp = (uint8_t *)mem_balloc(mem, ip_length + 1);
+
+ if (ip_tmp == nullptr) {
+ return false;
+ }
+
+ memcpy(ip_tmp, ip, ip_length + 1);
+ dht_nodes_response->ip = ip_tmp;
+ dht_nodes_response->ip_length = ip_length;
+ return true;
+}
+uint32_t tox_event_dht_nodes_response_get_ip_length(const Tox_Event_Dht_Nodes_Response *dht_nodes_response)
+{
+ return dht_nodes_response->ip_length;
+}
+const uint8_t *tox_event_dht_nodes_response_get_ip(const Tox_Event_Dht_Nodes_Response *dht_nodes_response)
+{
+ return dht_nodes_response->ip;
+}
+
+non_null()
+static bool tox_event_dht_nodes_response_set_port(Tox_Event_Dht_Nodes_Response *dht_nodes_response, uint16_t port)
+{
+ dht_nodes_response->port = port;
+ return true;
+}
+uint16_t tox_event_dht_nodes_response_get_port(const Tox_Event_Dht_Nodes_Response *dht_nodes_response)
+{
+ return dht_nodes_response->port;
+}
+
+non_null()
+static void tox_event_dht_nodes_response_construct(Tox_Event_Dht_Nodes_Response *dht_nodes_response)
+{
+ *dht_nodes_response = (Tox_Event_Dht_Nodes_Response) {
+ {
+ 0
+ }
+ };
+}
+non_null()
+static void tox_event_dht_nodes_response_destruct(Tox_Event_Dht_Nodes_Response *dht_nodes_response, const Memory *mem)
+{
+ mem_delete(mem, dht_nodes_response->ip);
+}
+
+bool tox_event_dht_nodes_response_pack(
+ const Tox_Event_Dht_Nodes_Response *event, Bin_Pack *bp)
+{
+ return bin_pack_array(bp, 3)
+ && bin_pack_bin(bp, event->public_key, TOX_PUBLIC_KEY_SIZE)
+ && bin_pack_bin(bp, event->ip, event->ip_length)
+ && bin_pack_u16(bp, event->port);
+}
+
+non_null()
+static bool tox_event_dht_nodes_response_unpack_into(
+ Tox_Event_Dht_Nodes_Response *event, Bin_Unpack *bu)
+{
+ if (!bin_unpack_array_fixed(bu, 3, nullptr)) {
+ return false;
+ }
+
+ return bin_unpack_bin_fixed(bu, event->public_key, TOX_PUBLIC_KEY_SIZE)
+ && bin_unpack_bin(bu, &event->ip, &event->ip_length)
+ && bin_unpack_u16(bu, &event->port);
+}
+
+const Tox_Event_Dht_Nodes_Response *tox_event_get_dht_nodes_response(
+ const Tox_Event *event)
+{
+ return event->type == TOX_EVENT_DHT_NODES_RESPONSE ? event->data.dht_nodes_response : nullptr;
+}
+
+Tox_Event_Dht_Nodes_Response *tox_event_dht_nodes_response_new(const Memory *mem)
+{
+ Tox_Event_Dht_Nodes_Response *const dht_nodes_response =
+ (Tox_Event_Dht_Nodes_Response *)mem_alloc(mem, sizeof(Tox_Event_Dht_Nodes_Response));
+
+ if (dht_nodes_response == nullptr) {
+ return nullptr;
+ }
+
+ tox_event_dht_nodes_response_construct(dht_nodes_response);
+ return dht_nodes_response;
+}
+
+void tox_event_dht_nodes_response_free(Tox_Event_Dht_Nodes_Response *dht_nodes_response, const Memory *mem)
+{
+ if (dht_nodes_response != nullptr) {
+ tox_event_dht_nodes_response_destruct(dht_nodes_response, mem);
+ }
+ mem_delete(mem, dht_nodes_response);
+}
+
+non_null()
+static Tox_Event_Dht_Nodes_Response *tox_events_add_dht_nodes_response(Tox_Events *events, const Memory *mem)
+{
+ Tox_Event_Dht_Nodes_Response *const dht_nodes_response = tox_event_dht_nodes_response_new(mem);
+
+ if (dht_nodes_response == nullptr) {
+ return nullptr;
+ }
+
+ Tox_Event event;
+ event.type = TOX_EVENT_DHT_NODES_RESPONSE;
+ event.data.dht_nodes_response = dht_nodes_response;
+
+ if (!tox_events_add(events, &event)) {
+ tox_event_dht_nodes_response_free(dht_nodes_response, mem);
+ return nullptr;
+ }
+ return dht_nodes_response;
+}
+
+bool tox_event_dht_nodes_response_unpack(
+ Tox_Event_Dht_Nodes_Response **event, Bin_Unpack *bu, const Memory *mem)
+{
+ *event = tox_event_dht_nodes_response_new(mem);
+
+ if (*event == nullptr) {
+ return false;
+ }
+
+ return tox_event_dht_nodes_response_unpack_into(*event, bu);
+}
+
+non_null()
+static Tox_Event_Dht_Nodes_Response *tox_event_dht_nodes_response_alloc(void *user_data)
+{
+ Tox_Events_State *state = tox_events_alloc(user_data);
+ assert(state != nullptr);
+
+ if (state->events == nullptr) {
+ return nullptr;
+ }
+
+ Tox_Event_Dht_Nodes_Response *dht_nodes_response = tox_events_add_dht_nodes_response(state->events, state->mem);
+
+ if (dht_nodes_response == nullptr) {
+ state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
+ return nullptr;
+ }
+
+ return dht_nodes_response;
+}
+
+/*****************************************************
+ *
+ * :: event handler
+ *
+ *****************************************************/
+
+void tox_events_handle_dht_nodes_response(
+ Tox *tox, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE],
+ const char *ip, uint32_t ip_length, uint16_t port, void *user_data)
+{
+ Tox_Event_Dht_Nodes_Response *dht_nodes_response = tox_event_dht_nodes_response_alloc(user_data);
+
+ if (dht_nodes_response == nullptr) {
+ return;
+ }
+
+ const Tox_System *sys = tox_get_system(tox);
+
+ tox_event_dht_nodes_response_set_public_key(dht_nodes_response, public_key);
+ tox_event_dht_nodes_response_set_ip(dht_nodes_response, ip, ip_length, sys->mem);
+ tox_event_dht_nodes_response_set_port(dht_nodes_response, port);
+}
diff --git a/protocols/Tox/libtox/src/toxcore/events/events_alloc.c b/protocols/Tox/libtox/src/toxcore/events/events_alloc.c
index 24eebb3124..18405ea90d 100644
--- a/protocols/Tox/libtox/src/toxcore/events/events_alloc.c
+++ b/protocols/Tox/libtox/src/toxcore/events/events_alloc.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#include "events_alloc.h"
diff --git a/protocols/Tox/libtox/src/toxcore/events/events_alloc.h b/protocols/Tox/libtox/src/toxcore/events/events_alloc.h
index a40db97052..d0343d9ccb 100644
--- a/protocols/Tox/libtox/src/toxcore/events/events_alloc.h
+++ b/protocols/Tox/libtox/src/toxcore/events/events_alloc.h
@@ -1,16 +1,13 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_EVENTS_EVENTS_ALLOC_H
#define C_TOXCORE_TOXCORE_EVENTS_EVENTS_ALLOC_H
#include "../attributes.h"
-#include "../bin_pack.h"
-#include "../bin_unpack.h"
#include "../mem.h"
#include "../tox.h"
-#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_private.h"
@@ -38,7 +35,7 @@ tox_conference_message_cb tox_events_handle_conference_message;
tox_conference_peer_list_changed_cb tox_events_handle_conference_peer_list_changed;
tox_conference_peer_name_cb tox_events_handle_conference_peer_name;
tox_conference_title_cb tox_events_handle_conference_title;
-tox_dht_get_nodes_response_cb tox_events_handle_dht_get_nodes_response;
+tox_dht_nodes_response_cb tox_events_handle_dht_nodes_response;
tox_file_chunk_request_cb tox_events_handle_file_chunk_request;
tox_file_recv_cb tox_events_handle_file_recv;
tox_file_recv_chunk_cb tox_events_handle_file_recv_chunk;
diff --git a/protocols/Tox/libtox/src/toxcore/events/file_chunk_request.c b/protocols/Tox/libtox/src/toxcore/events/file_chunk_request.c
index 4117ef3c4b..d59b7a5ba7 100644
--- a/protocols/Tox/libtox/src/toxcore/events/file_chunk_request.c
+++ b/protocols/Tox/libtox/src/toxcore/events/file_chunk_request.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -162,7 +163,10 @@ static Tox_Event_File_Chunk_Request *tox_events_add_file_chunk_request(Tox_Event
event.type = TOX_EVENT_FILE_CHUNK_REQUEST;
event.data.file_chunk_request = file_chunk_request;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_file_chunk_request_free(file_chunk_request, mem);
+ return nullptr;
+ }
return file_chunk_request;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/file_recv.c b/protocols/Tox/libtox/src/toxcore/events/file_recv.c
index 45cec44b0d..6ba2fdecfd 100644
--- a/protocols/Tox/libtox/src/toxcore/events/file_recv.c
+++ b/protocols/Tox/libtox/src/toxcore/events/file_recv.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -207,7 +208,10 @@ static Tox_Event_File_Recv *tox_events_add_file_recv(Tox_Events *events, const M
event.type = TOX_EVENT_FILE_RECV;
event.data.file_recv = file_recv;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_file_recv_free(file_recv, mem);
+ return nullptr;
+ }
return file_recv;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/file_recv_chunk.c b/protocols/Tox/libtox/src/toxcore/events/file_recv_chunk.c
index 2edf7c5a7b..cb4487e23c 100644
--- a/protocols/Tox/libtox/src/toxcore/events/file_recv_chunk.c
+++ b/protocols/Tox/libtox/src/toxcore/events/file_recv_chunk.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -191,7 +192,10 @@ static Tox_Event_File_Recv_Chunk *tox_events_add_file_recv_chunk(Tox_Events *eve
event.type = TOX_EVENT_FILE_RECV_CHUNK;
event.data.file_recv_chunk = file_recv_chunk;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_file_recv_chunk_free(file_recv_chunk, mem);
+ return nullptr;
+ }
return file_recv_chunk;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/file_recv_control.c b/protocols/Tox/libtox/src/toxcore/events/file_recv_control.c
index 14a34aaf3b..72de182e72 100644
--- a/protocols/Tox/libtox/src/toxcore/events/file_recv_control.c
+++ b/protocols/Tox/libtox/src/toxcore/events/file_recv_control.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -148,7 +149,10 @@ static Tox_Event_File_Recv_Control *tox_events_add_file_recv_control(Tox_Events
event.type = TOX_EVENT_FILE_RECV_CONTROL;
event.data.file_recv_control = file_recv_control;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_file_recv_control_free(file_recv_control, mem);
+ return nullptr;
+ }
return file_recv_control;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/friend_connection_status.c b/protocols/Tox/libtox/src/toxcore/events/friend_connection_status.c
index 330554b05e..d57980ddff 100644
--- a/protocols/Tox/libtox/src/toxcore/events/friend_connection_status.c
+++ b/protocols/Tox/libtox/src/toxcore/events/friend_connection_status.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -132,7 +133,10 @@ static Tox_Event_Friend_Connection_Status *tox_events_add_friend_connection_stat
event.type = TOX_EVENT_FRIEND_CONNECTION_STATUS;
event.data.friend_connection_status = friend_connection_status;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_friend_connection_status_free(friend_connection_status, mem);
+ return nullptr;
+ }
return friend_connection_status;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/friend_lossless_packet.c b/protocols/Tox/libtox/src/toxcore/events/friend_lossless_packet.c
index 17e8fad926..098c5ab006 100644
--- a/protocols/Tox/libtox/src/toxcore/events/friend_lossless_packet.c
+++ b/protocols/Tox/libtox/src/toxcore/events/friend_lossless_packet.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -159,7 +160,10 @@ static Tox_Event_Friend_Lossless_Packet *tox_events_add_friend_lossless_packet(T
event.type = TOX_EVENT_FRIEND_LOSSLESS_PACKET;
event.data.friend_lossless_packet = friend_lossless_packet;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_friend_lossless_packet_free(friend_lossless_packet, mem);
+ return nullptr;
+ }
return friend_lossless_packet;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/friend_lossy_packet.c b/protocols/Tox/libtox/src/toxcore/events/friend_lossy_packet.c
index 6b2e9ed2b0..016fa5d25c 100644
--- a/protocols/Tox/libtox/src/toxcore/events/friend_lossy_packet.c
+++ b/protocols/Tox/libtox/src/toxcore/events/friend_lossy_packet.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -159,7 +160,10 @@ static Tox_Event_Friend_Lossy_Packet *tox_events_add_friend_lossy_packet(Tox_Eve
event.type = TOX_EVENT_FRIEND_LOSSY_PACKET;
event.data.friend_lossy_packet = friend_lossy_packet;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_friend_lossy_packet_free(friend_lossy_packet, mem);
+ return nullptr;
+ }
return friend_lossy_packet;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/friend_message.c b/protocols/Tox/libtox/src/toxcore/events/friend_message.c
index befcc74a24..cedc3b588c 100644
--- a/protocols/Tox/libtox/src/toxcore/events/friend_message.c
+++ b/protocols/Tox/libtox/src/toxcore/events/friend_message.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -177,7 +178,10 @@ static Tox_Event_Friend_Message *tox_events_add_friend_message(Tox_Events *event
event.type = TOX_EVENT_FRIEND_MESSAGE;
event.data.friend_message = friend_message;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_friend_message_free(friend_message, mem);
+ return nullptr;
+ }
return friend_message;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/friend_name.c b/protocols/Tox/libtox/src/toxcore/events/friend_name.c
index dfa9b39608..9f8de0ce31 100644
--- a/protocols/Tox/libtox/src/toxcore/events/friend_name.c
+++ b/protocols/Tox/libtox/src/toxcore/events/friend_name.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -159,7 +160,10 @@ static Tox_Event_Friend_Name *tox_events_add_friend_name(Tox_Events *events, con
event.type = TOX_EVENT_FRIEND_NAME;
event.data.friend_name = friend_name;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_friend_name_free(friend_name, mem);
+ return nullptr;
+ }
return friend_name;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/friend_read_receipt.c b/protocols/Tox/libtox/src/toxcore/events/friend_read_receipt.c
index e5f2f9db52..4ba426716e 100644
--- a/protocols/Tox/libtox/src/toxcore/events/friend_read_receipt.c
+++ b/protocols/Tox/libtox/src/toxcore/events/friend_read_receipt.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -130,7 +131,10 @@ static Tox_Event_Friend_Read_Receipt *tox_events_add_friend_read_receipt(Tox_Eve
event.type = TOX_EVENT_FRIEND_READ_RECEIPT;
event.data.friend_read_receipt = friend_read_receipt;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_friend_read_receipt_free(friend_read_receipt, mem);
+ return nullptr;
+ }
return friend_read_receipt;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/friend_request.c b/protocols/Tox/libtox/src/toxcore/events/friend_request.c
index b492c15147..631c236bac 100644
--- a/protocols/Tox/libtox/src/toxcore/events/friend_request.c
+++ b/protocols/Tox/libtox/src/toxcore/events/friend_request.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -13,6 +13,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_private.h"
@@ -152,7 +153,10 @@ static Tox_Event_Friend_Request *tox_events_add_friend_request(Tox_Events *event
event.type = TOX_EVENT_FRIEND_REQUEST;
event.data.friend_request = friend_request;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_friend_request_free(friend_request, mem);
+ return nullptr;
+ }
return friend_request;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/friend_status.c b/protocols/Tox/libtox/src/toxcore/events/friend_status.c
index 3d7499722b..209eed8bc5 100644
--- a/protocols/Tox/libtox/src/toxcore/events/friend_status.c
+++ b/protocols/Tox/libtox/src/toxcore/events/friend_status.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -132,7 +133,10 @@ static Tox_Event_Friend_Status *tox_events_add_friend_status(Tox_Events *events,
event.type = TOX_EVENT_FRIEND_STATUS;
event.data.friend_status = friend_status;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_friend_status_free(friend_status, mem);
+ return nullptr;
+ }
return friend_status;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/friend_status_message.c b/protocols/Tox/libtox/src/toxcore/events/friend_status_message.c
index ad0519911e..2c6d0fb02f 100644
--- a/protocols/Tox/libtox/src/toxcore/events/friend_status_message.c
+++ b/protocols/Tox/libtox/src/toxcore/events/friend_status_message.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -159,7 +160,10 @@ static Tox_Event_Friend_Status_Message *tox_events_add_friend_status_message(Tox
event.type = TOX_EVENT_FRIEND_STATUS_MESSAGE;
event.data.friend_status_message = friend_status_message;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_friend_status_message_free(friend_status_message, mem);
+ return nullptr;
+ }
return friend_status_message;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/friend_typing.c b/protocols/Tox/libtox/src/toxcore/events/friend_typing.c
index 692b07fb88..cb2cfac94d 100644
--- a/protocols/Tox/libtox/src/toxcore/events/friend_typing.c
+++ b/protocols/Tox/libtox/src/toxcore/events/friend_typing.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -130,7 +131,10 @@ static Tox_Event_Friend_Typing *tox_events_add_friend_typing(Tox_Events *events,
event.type = TOX_EVENT_FRIEND_TYPING;
event.data.friend_typing = friend_typing;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_friend_typing_free(friend_typing, mem);
+ return nullptr;
+ }
return friend_typing;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_custom_packet.c b/protocols/Tox/libtox/src/toxcore/events/group_custom_packet.c
index a82e2c3a6c..337d601f04 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_custom_packet.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_custom_packet.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -175,7 +176,10 @@ static Tox_Event_Group_Custom_Packet *tox_events_add_group_custom_packet(Tox_Eve
event.type = TOX_EVENT_GROUP_CUSTOM_PACKET;
event.data.group_custom_packet = group_custom_packet;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_custom_packet_free(group_custom_packet, mem);
+ return nullptr;
+ }
return group_custom_packet;
}
@@ -220,7 +224,7 @@ static Tox_Event_Group_Custom_Packet *tox_event_group_custom_packet_alloc(void *
*****************************************************/
void tox_events_handle_group_custom_packet(
- Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *data, size_t length,
+ Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *data, size_t data_length,
void *user_data)
{
Tox_Event_Group_Custom_Packet *group_custom_packet = tox_event_group_custom_packet_alloc(user_data);
@@ -231,5 +235,5 @@ void tox_events_handle_group_custom_packet(
tox_event_group_custom_packet_set_group_number(group_custom_packet, group_number);
tox_event_group_custom_packet_set_peer_id(group_custom_packet, peer_id);
- tox_event_group_custom_packet_set_data(group_custom_packet, data, length);
+ tox_event_group_custom_packet_set_data(group_custom_packet, data, data_length);
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_custom_private_packet.c b/protocols/Tox/libtox/src/toxcore/events/group_custom_private_packet.c
index 56282f0fb8..9408a8dc68 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_custom_private_packet.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_custom_private_packet.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -175,7 +176,10 @@ static Tox_Event_Group_Custom_Private_Packet *tox_events_add_group_custom_privat
event.type = TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET;
event.data.group_custom_private_packet = group_custom_private_packet;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_custom_private_packet_free(group_custom_private_packet, mem);
+ return nullptr;
+ }
return group_custom_private_packet;
}
@@ -220,7 +224,7 @@ static Tox_Event_Group_Custom_Private_Packet *tox_event_group_custom_private_pac
*****************************************************/
void tox_events_handle_group_custom_private_packet(
- Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *data, size_t length,
+ Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *data, size_t data_length,
void *user_data)
{
Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet = tox_event_group_custom_private_packet_alloc(user_data);
@@ -231,5 +235,5 @@ void tox_events_handle_group_custom_private_packet(
tox_event_group_custom_private_packet_set_group_number(group_custom_private_packet, group_number);
tox_event_group_custom_private_packet_set_peer_id(group_custom_private_packet, peer_id);
- tox_event_group_custom_private_packet_set_data(group_custom_private_packet, data, length);
+ tox_event_group_custom_private_packet_set_data(group_custom_private_packet, data, data_length);
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_invite.c b/protocols/Tox/libtox/src/toxcore/events/group_invite.c
index 0691dcd1fe..3385b89ad5 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_invite.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_invite.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -203,7 +204,10 @@ static Tox_Event_Group_Invite *tox_events_add_group_invite(Tox_Events *events, c
event.type = TOX_EVENT_GROUP_INVITE;
event.data.group_invite = group_invite;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_invite_free(group_invite, mem);
+ return nullptr;
+ }
return group_invite;
}
@@ -248,7 +252,7 @@ static Tox_Event_Group_Invite *tox_event_group_invite_alloc(void *user_data)
*****************************************************/
void tox_events_handle_group_invite(
- Tox *tox, uint32_t friend_number, const uint8_t *invite_data, size_t length, const uint8_t *group_name, size_t group_name_length,
+ Tox *tox, uint32_t friend_number, const uint8_t *invite_data, size_t invite_data_length, const uint8_t *group_name, size_t group_name_length,
void *user_data)
{
Tox_Event_Group_Invite *group_invite = tox_event_group_invite_alloc(user_data);
@@ -258,6 +262,6 @@ void tox_events_handle_group_invite(
}
tox_event_group_invite_set_friend_number(group_invite, friend_number);
- tox_event_group_invite_set_invite_data(group_invite, invite_data, length);
+ tox_event_group_invite_set_invite_data(group_invite, invite_data, invite_data_length);
tox_event_group_invite_set_group_name(group_invite, group_name, group_name_length);
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_join_fail.c b/protocols/Tox/libtox/src/toxcore/events/group_join_fail.c
index b85896858b..8fdefb77e4 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_join_fail.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_join_fail.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -132,7 +133,10 @@ static Tox_Event_Group_Join_Fail *tox_events_add_group_join_fail(Tox_Events *eve
event.type = TOX_EVENT_GROUP_JOIN_FAIL;
event.data.group_join_fail = group_join_fail;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_join_fail_free(group_join_fail, mem);
+ return nullptr;
+ }
return group_join_fail;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_message.c b/protocols/Tox/libtox/src/toxcore/events/group_message.c
index a200f84566..dfb2bc961a 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_message.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_message.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -27,7 +28,7 @@
struct Tox_Event_Group_Message {
uint32_t group_number;
uint32_t peer_id;
- Tox_Message_Type type;
+ Tox_Message_Type message_type;
uint8_t *message;
uint32_t message_length;
uint32_t message_id;
@@ -60,16 +61,16 @@ uint32_t tox_event_group_message_get_peer_id(const Tox_Event_Group_Message *grou
}
non_null()
-static void tox_event_group_message_set_type(Tox_Event_Group_Message *group_message,
- Tox_Message_Type type)
+static void tox_event_group_message_set_message_type(Tox_Event_Group_Message *group_message,
+ Tox_Message_Type message_type)
{
assert(group_message != nullptr);
- group_message->type = type;
+ group_message->message_type = message_type;
}
-Tox_Message_Type tox_event_group_message_get_type(const Tox_Event_Group_Message *group_message)
+Tox_Message_Type tox_event_group_message_get_message_type(const Tox_Event_Group_Message *group_message)
{
assert(group_message != nullptr);
- return group_message->type;
+ return group_message->message_type;
}
non_null(1) nullable(2)
@@ -143,7 +144,7 @@ bool tox_event_group_message_pack(
return bin_pack_array(bp, 5)
&& bin_pack_u32(bp, event->group_number)
&& bin_pack_u32(bp, event->peer_id)
- && tox_message_type_pack(event->type, bp)
+ && tox_message_type_pack(event->message_type, bp)
&& bin_pack_bin(bp, event->message, event->message_length)
&& bin_pack_u32(bp, event->message_id);
}
@@ -159,7 +160,7 @@ static bool tox_event_group_message_unpack_into(
return bin_unpack_u32(bu, &event->group_number)
&& bin_unpack_u32(bu, &event->peer_id)
- && tox_message_type_unpack(&event->type, bu)
+ && tox_message_type_unpack(&event->message_type, bu)
&& bin_unpack_bin(bu, &event->message, &event->message_length)
&& bin_unpack_u32(bu, &event->message_id);
}
@@ -209,7 +210,10 @@ static Tox_Event_Group_Message *tox_events_add_group_message(Tox_Events *events,
event.type = TOX_EVENT_GROUP_MESSAGE;
event.data.group_message = group_message;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_message_free(group_message, mem);
+ return nullptr;
+ }
return group_message;
}
@@ -254,7 +258,7 @@ static Tox_Event_Group_Message *tox_event_group_message_alloc(void *user_data)
*****************************************************/
void tox_events_handle_group_message(
- Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Message_Type type, const uint8_t *message, size_t length, uint32_t message_id,
+ Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Message_Type message_type, const uint8_t *message, size_t message_length, uint32_t message_id,
void *user_data)
{
Tox_Event_Group_Message *group_message = tox_event_group_message_alloc(user_data);
@@ -265,7 +269,7 @@ void tox_events_handle_group_message(
tox_event_group_message_set_group_number(group_message, group_number);
tox_event_group_message_set_peer_id(group_message, peer_id);
- tox_event_group_message_set_type(group_message, type);
- tox_event_group_message_set_message(group_message, message, length);
+ tox_event_group_message_set_message_type(group_message, message_type);
+ tox_event_group_message_set_message(group_message, message, message_length);
tox_event_group_message_set_message_id(group_message, message_id);
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_moderation.c b/protocols/Tox/libtox/src/toxcore/events/group_moderation.c
index ba510d5b2a..9e2b87e6c2 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_moderation.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_moderation.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -164,7 +165,10 @@ static Tox_Event_Group_Moderation *tox_events_add_group_moderation(Tox_Events *e
event.type = TOX_EVENT_GROUP_MODERATION;
event.data.group_moderation = group_moderation;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_moderation_free(group_moderation, mem);
+ return nullptr;
+ }
return group_moderation;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_password.c b/protocols/Tox/libtox/src/toxcore/events/group_password.c
index ad6e86b9d3..33b64a0a8b 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_password.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_password.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -159,7 +160,10 @@ static Tox_Event_Group_Password *tox_events_add_group_password(Tox_Events *event
event.type = TOX_EVENT_GROUP_PASSWORD;
event.data.group_password = group_password;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_password_free(group_password, mem);
+ return nullptr;
+ }
return group_password;
}
@@ -204,7 +208,7 @@ static Tox_Event_Group_Password *tox_event_group_password_alloc(void *user_data)
*****************************************************/
void tox_events_handle_group_password(
- Tox *tox, uint32_t group_number, const uint8_t *password, size_t length,
+ Tox *tox, uint32_t group_number, const uint8_t *password, size_t password_length,
void *user_data)
{
Tox_Event_Group_Password *group_password = tox_event_group_password_alloc(user_data);
@@ -214,5 +218,5 @@ void tox_events_handle_group_password(
}
tox_event_group_password_set_group_number(group_password, group_number);
- tox_event_group_password_set_password(group_password, password, length);
+ tox_event_group_password_set_password(group_password, password, password_length);
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_peer_exit.c b/protocols/Tox/libtox/src/toxcore/events/group_peer_exit.c
index 16d1eba7a6..a09f96b7d0 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_peer_exit.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_peer_exit.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -237,7 +238,10 @@ static Tox_Event_Group_Peer_Exit *tox_events_add_group_peer_exit(Tox_Events *eve
event.type = TOX_EVENT_GROUP_PEER_EXIT;
event.data.group_peer_exit = group_peer_exit;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_peer_exit_free(group_peer_exit, mem);
+ return nullptr;
+ }
return group_peer_exit;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_peer_join.c b/protocols/Tox/libtox/src/toxcore/events/group_peer_join.c
index af0d006e87..d450564429 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_peer_join.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_peer_join.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -130,7 +131,10 @@ static Tox_Event_Group_Peer_Join *tox_events_add_group_peer_join(Tox_Events *eve
event.type = TOX_EVENT_GROUP_PEER_JOIN;
event.data.group_peer_join = group_peer_join;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_peer_join_free(group_peer_join, mem);
+ return nullptr;
+ }
return group_peer_join;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_peer_limit.c b/protocols/Tox/libtox/src/toxcore/events/group_peer_limit.c
index 5e2e23558c..65c44e7a19 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_peer_limit.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_peer_limit.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -130,7 +131,10 @@ static Tox_Event_Group_Peer_Limit *tox_events_add_group_peer_limit(Tox_Events *e
event.type = TOX_EVENT_GROUP_PEER_LIMIT;
event.data.group_peer_limit = group_peer_limit;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_peer_limit_free(group_peer_limit, mem);
+ return nullptr;
+ }
return group_peer_limit;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_peer_name.c b/protocols/Tox/libtox/src/toxcore/events/group_peer_name.c
index f8273e94b4..d653ff5531 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_peer_name.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_peer_name.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -175,7 +176,10 @@ static Tox_Event_Group_Peer_Name *tox_events_add_group_peer_name(Tox_Events *eve
event.type = TOX_EVENT_GROUP_PEER_NAME;
event.data.group_peer_name = group_peer_name;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_peer_name_free(group_peer_name, mem);
+ return nullptr;
+ }
return group_peer_name;
}
@@ -220,7 +224,7 @@ static Tox_Event_Group_Peer_Name *tox_event_group_peer_name_alloc(void *user_dat
*****************************************************/
void tox_events_handle_group_peer_name(
- Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *name, size_t length,
+ Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *name, size_t name_length,
void *user_data)
{
Tox_Event_Group_Peer_Name *group_peer_name = tox_event_group_peer_name_alloc(user_data);
@@ -231,5 +235,5 @@ void tox_events_handle_group_peer_name(
tox_event_group_peer_name_set_group_number(group_peer_name, group_number);
tox_event_group_peer_name_set_peer_id(group_peer_name, peer_id);
- tox_event_group_peer_name_set_name(group_peer_name, name, length);
+ tox_event_group_peer_name_set_name(group_peer_name, name, name_length);
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_peer_status.c b/protocols/Tox/libtox/src/toxcore/events/group_peer_status.c
index 4165d90ec2..3dc56df5ff 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_peer_status.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_peer_status.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -148,7 +149,10 @@ static Tox_Event_Group_Peer_Status *tox_events_add_group_peer_status(Tox_Events
event.type = TOX_EVENT_GROUP_PEER_STATUS;
event.data.group_peer_status = group_peer_status;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_peer_status_free(group_peer_status, mem);
+ return nullptr;
+ }
return group_peer_status;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_privacy_state.c b/protocols/Tox/libtox/src/toxcore/events/group_privacy_state.c
index 1c683c255c..fde9e1d79c 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_privacy_state.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_privacy_state.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -132,7 +133,10 @@ static Tox_Event_Group_Privacy_State *tox_events_add_group_privacy_state(Tox_Eve
event.type = TOX_EVENT_GROUP_PRIVACY_STATE;
event.data.group_privacy_state = group_privacy_state;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_privacy_state_free(group_privacy_state, mem);
+ return nullptr;
+ }
return group_privacy_state;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_private_message.c b/protocols/Tox/libtox/src/toxcore/events/group_private_message.c
index 648f707880..24dd1db670 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_private_message.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_private_message.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -27,9 +28,10 @@
struct Tox_Event_Group_Private_Message {
uint32_t group_number;
uint32_t peer_id;
- Tox_Message_Type type;
+ Tox_Message_Type message_type;
uint8_t *message;
uint32_t message_length;
+ uint32_t message_id;
};
non_null()
@@ -59,16 +61,16 @@ uint32_t tox_event_group_private_message_get_peer_id(const Tox_Event_Group_Priva
}
non_null()
-static void tox_event_group_private_message_set_type(Tox_Event_Group_Private_Message *group_private_message,
- Tox_Message_Type type)
+static void tox_event_group_private_message_set_message_type(Tox_Event_Group_Private_Message *group_private_message,
+ Tox_Message_Type message_type)
{
assert(group_private_message != nullptr);
- group_private_message->type = type;
+ group_private_message->message_type = message_type;
}
-Tox_Message_Type tox_event_group_private_message_get_type(const Tox_Event_Group_Private_Message *group_private_message)
+Tox_Message_Type tox_event_group_private_message_get_message_type(const Tox_Event_Group_Private_Message *group_private_message)
{
assert(group_private_message != nullptr);
- return group_private_message->type;
+ return group_private_message->message_type;
}
non_null(1) nullable(2)
@@ -111,6 +113,19 @@ const uint8_t *tox_event_group_private_message_get_message(const Tox_Event_Group
}
non_null()
+static void tox_event_group_private_message_set_message_id(Tox_Event_Group_Private_Message *group_private_message,
+ uint32_t message_id)
+{
+ assert(group_private_message != nullptr);
+ group_private_message->message_id = message_id;
+}
+uint32_t tox_event_group_private_message_get_message_id(const Tox_Event_Group_Private_Message *group_private_message)
+{
+ assert(group_private_message != nullptr);
+ return group_private_message->message_id;
+}
+
+non_null()
static void tox_event_group_private_message_construct(Tox_Event_Group_Private_Message *group_private_message)
{
*group_private_message = (Tox_Event_Group_Private_Message) {
@@ -126,11 +141,12 @@ static void tox_event_group_private_message_destruct(Tox_Event_Group_Private_Mes
bool tox_event_group_private_message_pack(
const Tox_Event_Group_Private_Message *event, Bin_Pack *bp)
{
- return bin_pack_array(bp, 4)
+ return bin_pack_array(bp, 5)
&& bin_pack_u32(bp, event->group_number)
&& bin_pack_u32(bp, event->peer_id)
- && tox_message_type_pack(event->type, bp)
- && bin_pack_bin(bp, event->message, event->message_length);
+ && tox_message_type_pack(event->message_type, bp)
+ && bin_pack_bin(bp, event->message, event->message_length)
+ && bin_pack_u32(bp, event->message_id);
}
non_null()
@@ -138,14 +154,15 @@ static bool tox_event_group_private_message_unpack_into(
Tox_Event_Group_Private_Message *event, Bin_Unpack *bu)
{
assert(event != nullptr);
- if (!bin_unpack_array_fixed(bu, 4, nullptr)) {
+ if (!bin_unpack_array_fixed(bu, 5, nullptr)) {
return false;
}
return bin_unpack_u32(bu, &event->group_number)
&& bin_unpack_u32(bu, &event->peer_id)
- && tox_message_type_unpack(&event->type, bu)
- && bin_unpack_bin(bu, &event->message, &event->message_length);
+ && tox_message_type_unpack(&event->message_type, bu)
+ && bin_unpack_bin(bu, &event->message, &event->message_length)
+ && bin_unpack_u32(bu, &event->message_id);
}
/*****************************************************
@@ -193,7 +210,10 @@ static Tox_Event_Group_Private_Message *tox_events_add_group_private_message(Tox
event.type = TOX_EVENT_GROUP_PRIVATE_MESSAGE;
event.data.group_private_message = group_private_message;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_private_message_free(group_private_message, mem);
+ return nullptr;
+ }
return group_private_message;
}
@@ -238,7 +258,7 @@ static Tox_Event_Group_Private_Message *tox_event_group_private_message_alloc(vo
*****************************************************/
void tox_events_handle_group_private_message(
- Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Message_Type type, const uint8_t *message, size_t length,
+ Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Message_Type message_type, const uint8_t *message, size_t message_length, uint32_t message_id,
void *user_data)
{
Tox_Event_Group_Private_Message *group_private_message = tox_event_group_private_message_alloc(user_data);
@@ -249,6 +269,7 @@ void tox_events_handle_group_private_message(
tox_event_group_private_message_set_group_number(group_private_message, group_number);
tox_event_group_private_message_set_peer_id(group_private_message, peer_id);
- tox_event_group_private_message_set_type(group_private_message, type);
- tox_event_group_private_message_set_message(group_private_message, message, length);
+ tox_event_group_private_message_set_message_type(group_private_message, message_type);
+ tox_event_group_private_message_set_message(group_private_message, message, message_length);
+ tox_event_group_private_message_set_message_id(group_private_message, message_id);
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_self_join.c b/protocols/Tox/libtox/src/toxcore/events/group_self_join.c
index 0745e975f8..07038632aa 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_self_join.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_self_join.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -109,7 +110,10 @@ static Tox_Event_Group_Self_Join *tox_events_add_group_self_join(Tox_Events *eve
event.type = TOX_EVENT_GROUP_SELF_JOIN;
event.data.group_self_join = group_self_join;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_self_join_free(group_self_join, mem);
+ return nullptr;
+ }
return group_self_join;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_topic.c b/protocols/Tox/libtox/src/toxcore/events/group_topic.c
index 23cdd5d354..f9d1a7b953 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_topic.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_topic.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -14,6 +14,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
/*****************************************************
@@ -175,7 +176,10 @@ static Tox_Event_Group_Topic *tox_events_add_group_topic(Tox_Events *events, con
event.type = TOX_EVENT_GROUP_TOPIC;
event.data.group_topic = group_topic;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_topic_free(group_topic, mem);
+ return nullptr;
+ }
return group_topic;
}
@@ -220,7 +224,7 @@ static Tox_Event_Group_Topic *tox_event_group_topic_alloc(void *user_data)
*****************************************************/
void tox_events_handle_group_topic(
- Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *topic, size_t length,
+ Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *topic, size_t topic_length,
void *user_data)
{
Tox_Event_Group_Topic *group_topic = tox_event_group_topic_alloc(user_data);
@@ -231,5 +235,5 @@ void tox_events_handle_group_topic(
tox_event_group_topic_set_group_number(group_topic, group_number);
tox_event_group_topic_set_peer_id(group_topic, peer_id);
- tox_event_group_topic_set_topic(group_topic, topic, length);
+ tox_event_group_topic_set_topic(group_topic, topic, topic_length);
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_topic_lock.c b/protocols/Tox/libtox/src/toxcore/events/group_topic_lock.c
index 36fb49393a..a21acea293 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_topic_lock.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_topic_lock.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -132,7 +133,10 @@ static Tox_Event_Group_Topic_Lock *tox_events_add_group_topic_lock(Tox_Events *e
event.type = TOX_EVENT_GROUP_TOPIC_LOCK;
event.data.group_topic_lock = group_topic_lock;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_topic_lock_free(group_topic_lock, mem);
+ return nullptr;
+ }
return group_topic_lock;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/group_voice_state.c b/protocols/Tox/libtox/src/toxcore/events/group_voice_state.c
index fba0300389..ebc78dca21 100644
--- a/protocols/Tox/libtox/src/toxcore/events/group_voice_state.c
+++ b/protocols/Tox/libtox/src/toxcore/events/group_voice_state.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -132,7 +133,10 @@ static Tox_Event_Group_Voice_State *tox_events_add_group_voice_state(Tox_Events
event.type = TOX_EVENT_GROUP_VOICE_STATE;
event.data.group_voice_state = group_voice_state;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_group_voice_state_free(group_voice_state, mem);
+ return nullptr;
+ }
return group_voice_state;
}
diff --git a/protocols/Tox/libtox/src/toxcore/events/self_connection_status.c b/protocols/Tox/libtox/src/toxcore/events/self_connection_status.c
index 8d8bc803ea..f66daff544 100644
--- a/protocols/Tox/libtox/src/toxcore/events/self_connection_status.c
+++ b/protocols/Tox/libtox/src/toxcore/events/self_connection_status.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2023-2024 The TokTok team.
+ * Copyright © 2023-2025 The TokTok team.
*/
#include "events_alloc.h"
@@ -12,6 +12,7 @@
#include "../ccompat.h"
#include "../mem.h"
#include "../tox.h"
+#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_unpack.h"
@@ -111,7 +112,10 @@ static Tox_Event_Self_Connection_Status *tox_events_add_self_connection_status(T
event.type = TOX_EVENT_SELF_CONNECTION_STATUS;
event.data.self_connection_status = self_connection_status;
- tox_events_add(events, &event);
+ if (!tox_events_add(events, &event)) {
+ tox_event_self_connection_status_free(self_connection_status, mem);
+ return nullptr;
+ }
return self_connection_status;
}
diff --git a/protocols/Tox/libtox/src/toxcore/forwarding.c b/protocols/Tox/libtox/src/toxcore/forwarding.c
index 18ff3203fc..6d608b5e7b 100644
--- a/protocols/Tox/libtox/src/toxcore/forwarding.c
+++ b/protocols/Tox/libtox/src/toxcore/forwarding.c
@@ -1,11 +1,10 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2019-2022 The TokTok team.
+ * Copyright © 2019-2025 The TokTok team.
*/
#include "forwarding.h"
#include <assert.h>
-#include <stdlib.h>
#include <string.h>
#include "DHT.h"
@@ -13,12 +12,14 @@
#include "ccompat.h"
#include "crypto_core.h"
#include "logger.h"
+#include "mem.h"
#include "mono_time.h"
#include "network.h"
#include "timed_auth.h"
struct Forwarding {
const Logger *log;
+ const Memory *mem;
const Random *rng;
DHT *dht;
const Mono_Time *mono_time;
@@ -357,19 +358,20 @@ void set_callback_forward_reply(Forwarding *forwarding, forward_reply_cb *functi
forwarding->forward_reply_callback_object = object;
}
-Forwarding *new_forwarding(const Logger *log, const Random *rng, const Mono_Time *mono_time, DHT *dht)
+Forwarding *new_forwarding(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time, DHT *dht)
{
if (log == nullptr || mono_time == nullptr || dht == nullptr) {
return nullptr;
}
- Forwarding *forwarding = (Forwarding *)calloc(1, sizeof(Forwarding));
+ Forwarding *forwarding = (Forwarding *)mem_alloc(mem, sizeof(Forwarding));
if (forwarding == nullptr) {
return nullptr;
}
forwarding->log = log;
+ forwarding->mem = mem;
forwarding->rng = rng;
forwarding->mono_time = mono_time;
forwarding->dht = dht;
@@ -396,5 +398,5 @@ void kill_forwarding(Forwarding *forwarding)
crypto_memzero(forwarding->hmac_key, CRYPTO_HMAC_KEY_SIZE);
- free(forwarding);
+ mem_delete(forwarding->mem, forwarding);
}
diff --git a/protocols/Tox/libtox/src/toxcore/forwarding.h b/protocols/Tox/libtox/src/toxcore/forwarding.h
index bd0ef09e1c..b4431f57af 100644
--- a/protocols/Tox/libtox/src/toxcore/forwarding.h
+++ b/protocols/Tox/libtox/src/toxcore/forwarding.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2019-2022 The TokTok team.
+ * Copyright © 2019-2025 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_FORWARDING_H
@@ -9,6 +9,7 @@
#include "attributes.h"
#include "crypto_core.h"
#include "logger.h"
+#include "mem.h"
#include "mono_time.h"
#include "network.h"
@@ -116,7 +117,7 @@ non_null(1) nullable(2, 3)
void set_callback_forward_reply(Forwarding *forwarding, forward_reply_cb *function, void *object);
non_null()
-Forwarding *new_forwarding(const Logger *log, const Random *rng, const Mono_Time *mono_time, DHT *dht);
+Forwarding *new_forwarding(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time, DHT *dht);
nullable(1)
void kill_forwarding(Forwarding *forwarding);
diff --git a/protocols/Tox/libtox/src/toxcore/friend_connection.c b/protocols/Tox/libtox/src/toxcore/friend_connection.c
index 33bfa40d34..78c6d4acdc 100644
--- a/protocols/Tox/libtox/src/toxcore/friend_connection.c
+++ b/protocols/Tox/libtox/src/toxcore/friend_connection.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2014 Tox project.
*/
@@ -8,7 +8,6 @@
*/
#include "friend_connection.h"
-#include <stdlib.h>
#include <string.h>
#include "DHT.h"
@@ -18,6 +17,7 @@
#include "ccompat.h"
#include "crypto_core.h"
#include "logger.h"
+#include "mem.h"
#include "mono_time.h"
#include "net_crypto.h"
#include "network.h"
@@ -69,6 +69,7 @@ static const Friend_Conn empty_friend_conn = {0};
struct Friend_Connections {
const Mono_Time *mono_time;
+ const Memory *mem;
const Logger *logger;
Net_Crypto *net_crypto;
DHT *dht;
@@ -126,12 +127,12 @@ non_null()
static bool realloc_friendconns(Friend_Connections *fr_c, uint32_t num)
{
if (num == 0) {
- free(fr_c->conns);
+ mem_delete(fr_c->mem, fr_c->conns);
fr_c->conns = nullptr;
return true;
}
- Friend_Conn *newgroup_cons = (Friend_Conn *)realloc(fr_c->conns, num * sizeof(Friend_Conn));
+ Friend_Conn *newgroup_cons = (Friend_Conn *)mem_vrealloc(fr_c->mem, fr_c->conns, num, sizeof(Friend_Conn));
if (newgroup_cons == nullptr) {
return false;
@@ -875,6 +876,10 @@ void set_friend_request_callback(Friend_Connections *fr_c, fr_request_cb *fr_req
int send_friend_request_packet(Friend_Connections *fr_c, int friendcon_id, uint32_t nospam_num, const uint8_t *data,
uint16_t length)
{
+ // TODO(Jfreegman): This max packet size is too large to be handled by receiving clients
+ // when sent via the onion. We currently limit the length at a higher level, but
+ // this bounds check should be fixed to represent the max size of a packet that
+ // the onion client can handle.
if (1 + sizeof(nospam_num) + length > ONION_CLIENT_MAX_DATA_SIZE || length == 0) {
return -1;
}
@@ -908,14 +913,14 @@ int send_friend_request_packet(Friend_Connections *fr_c, int friendcon_id, uint3
/** Create new friend_connections instance. */
Friend_Connections *new_friend_connections(
- const Logger *logger, const Mono_Time *mono_time, const Network *ns,
+ const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Network *ns,
Onion_Client *onion_c, bool local_discovery_enabled)
{
if (onion_c == nullptr) {
return nullptr;
}
- Friend_Connections *const temp = (Friend_Connections *)calloc(1, sizeof(Friend_Connections));
+ Friend_Connections *const temp = (Friend_Connections *)mem_alloc(mem, sizeof(Friend_Connections));
if (temp == nullptr) {
return nullptr;
@@ -924,7 +929,7 @@ Friend_Connections *new_friend_connections(
temp->local_discovery_enabled = local_discovery_enabled;
if (temp->local_discovery_enabled) {
- temp->broadcast = lan_discovery_init(ns);
+ temp->broadcast = lan_discovery_init(mem, ns);
if (temp->broadcast == nullptr) {
LOGGER_ERROR(logger, "could not initialise LAN discovery");
@@ -933,6 +938,7 @@ Friend_Connections *new_friend_connections(
}
temp->mono_time = mono_time;
+ temp->mem = mem;
temp->logger = logger;
temp->dht = onion_get_dht(onion_c);
temp->net_crypto = onion_get_net_crypto(onion_c);
@@ -1032,6 +1038,11 @@ void kill_friend_connections(Friend_Connections *fr_c)
kill_friend_connection(fr_c, i);
}
+ // there might be allocated NONE connections
+ if (fr_c->conns != nullptr) {
+ mem_delete(fr_c->mem, fr_c->conns);
+ }
+
lan_discovery_kill(fr_c->broadcast);
- free(fr_c);
+ mem_delete(fr_c->mem, fr_c);
}
diff --git a/protocols/Tox/libtox/src/toxcore/friend_connection.h b/protocols/Tox/libtox/src/toxcore/friend_connection.h
index bbd4454729..8c3c84f1c5 100644
--- a/protocols/Tox/libtox/src/toxcore/friend_connection.h
+++ b/protocols/Tox/libtox/src/toxcore/friend_connection.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2014 Tox project.
*/
@@ -12,9 +12,9 @@
#include <stdint.h>
#include "DHT.h"
-#include "LAN_discovery.h"
#include "attributes.h"
#include "logger.h"
+#include "mem.h"
#include "mono_time.h"
#include "net_crypto.h"
#include "network.h"
@@ -161,7 +161,7 @@ void set_friend_request_callback(Friend_Connections *fr_c, fr_request_cb *fr_req
/** Create new friend_connections instance. */
non_null()
Friend_Connections *new_friend_connections(
- const Logger *logger, const Mono_Time *mono_time, const Network *ns,
+ const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Network *ns,
Onion_Client *onion_c, bool local_discovery_enabled);
/** main friend_connections loop. */
diff --git a/protocols/Tox/libtox/src/toxcore/friend_requests.c b/protocols/Tox/libtox/src/toxcore/friend_requests.c
index 8b915449cd..e28ce7df85 100644
--- a/protocols/Tox/libtox/src/toxcore/friend_requests.c
+++ b/protocols/Tox/libtox/src/toxcore/friend_requests.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -8,18 +8,22 @@
*/
#include "friend_requests.h"
-#include <stdlib.h>
#include <string.h>
#include "attributes.h"
#include "ccompat.h"
#include "crypto_core.h"
#include "friend_connection.h"
+#include "mem.h"
#include "network.h"
#include "onion.h"
#include "onion_announce.h"
#include "onion_client.h"
+static_assert(ONION_CLIENT_MAX_DATA_SIZE <= MAX_DATA_REQUEST_SIZE, "ONION_CLIENT_MAX_DATA_SIZE is too big");
+static_assert(MAX_DATA_REQUEST_SIZE <= ONION_MAX_DATA_SIZE, "MAX_DATA_REQUEST_SIZE is too big");
+static_assert(SIZE_IPPORT <= ONION_SEND_BASE, "IP_Port does not fit in the onion packet");
+
/**
* NOTE: The following is just a temporary fix for the multiple friend requests received at the same time problem.
* TODO(irungentoo): Make this better (This will most likely tie in with the way we will handle spam).
@@ -32,6 +36,8 @@ struct Received_Requests {
};
struct Friend_Requests {
+ const Memory *mem;
+
uint32_t nospam;
fr_friend_request_cb *handle_friendrequest;
uint8_t handle_friendrequest_isset;
@@ -164,12 +170,24 @@ void friendreq_init(Friend_Requests *fr, Friend_Connections *fr_c)
set_friend_request_callback(fr_c, &friendreq_handlepacket, fr);
}
-Friend_Requests *friendreq_new(void)
+Friend_Requests *friendreq_new(const Memory *mem)
{
- return (Friend_Requests *)calloc(1, sizeof(Friend_Requests));
+ Friend_Requests *fr = (Friend_Requests *)mem_alloc(mem, sizeof(Friend_Requests));
+
+ if (fr == nullptr) {
+ return nullptr;
+ }
+
+ fr->mem = mem;
+
+ return fr;
}
void friendreq_kill(Friend_Requests *fr)
{
- free(fr);
+ if (fr == nullptr) {
+ return;
+ }
+
+ mem_delete(fr->mem, fr);
}
diff --git a/protocols/Tox/libtox/src/toxcore/friend_requests.h b/protocols/Tox/libtox/src/toxcore/friend_requests.h
index a78a570dfa..c7bae81fb8 100644
--- a/protocols/Tox/libtox/src/toxcore/friend_requests.h
+++ b/protocols/Tox/libtox/src/toxcore/friend_requests.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2014 Tox project.
*/
@@ -13,8 +13,10 @@
#include "attributes.h"
#include "friend_connection.h"
+#include "mem.h"
-#define MAX_FRIEND_REQUEST_DATA_SIZE (ONION_CLIENT_MAX_DATA_SIZE - (1 + sizeof(uint32_t)))
+// TODO(Jfreegman): This should be the maximum size that an onion client can handle.
+#define MAX_FRIEND_REQUEST_DATA_SIZE (ONION_CLIENT_MAX_DATA_SIZE - 100)
typedef struct Friend_Requests Friend_Requests;
@@ -49,7 +51,8 @@ void set_filter_function(Friend_Requests *fr, filter_function_cb *function, void
non_null()
void friendreq_init(Friend_Requests *fr, Friend_Connections *fr_c);
-Friend_Requests *friendreq_new(void);
+non_null()
+Friend_Requests *friendreq_new(const Memory *mem);
nullable(1)
void friendreq_kill(Friend_Requests *fr);
diff --git a/protocols/Tox/libtox/src/toxcore/group.c b/protocols/Tox/libtox/src/toxcore/group.c
index 14e61e6ffc..dbc3876403 100644
--- a/protocols/Tox/libtox/src/toxcore/group.c
+++ b/protocols/Tox/libtox/src/toxcore/group.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2014 Tox project.
*/
@@ -9,7 +9,6 @@
#include "group.h"
#include <assert.h>
-#include <stdlib.h>
#include <string.h>
#include "DHT.h"
@@ -20,9 +19,11 @@
#include "friend_connection.h"
#include "group_common.h"
#include "logger.h"
+#include "mem.h"
#include "mono_time.h"
#include "net_crypto.h"
#include "network.h"
+#include "sort.h"
#include "state.h"
#include "util.h"
@@ -147,6 +148,7 @@ typedef struct Group_c {
} Group_c;
struct Group_Chats {
+ const Memory *mem;
const Mono_Time *mono_time;
Messenger *m;
@@ -246,19 +248,19 @@ static bool is_groupnumber_valid(const Group_Chats *g_c, uint32_t groupnumber)
/** @brief Set the size of the groupchat list to num.
*
- * @retval false if realloc fails.
+ * @retval false if mem_vrealloc fails.
* @retval true if it succeeds.
*/
non_null()
static bool realloc_conferences(Group_Chats *g_c, uint16_t num)
{
if (num == 0) {
- free(g_c->chats);
+ mem_delete(g_c->mem, g_c->chats);
g_c->chats = nullptr;
return true;
}
- Group_c *newgroup_chats = (Group_c *)realloc(g_c->chats, num * sizeof(Group_c));
+ Group_c *newgroup_chats = (Group_c *)mem_vrealloc(g_c->mem, g_c->chats, num, sizeof(Group_c));
if (newgroup_chats == nullptr) {
return false;
@@ -300,10 +302,10 @@ static int32_t create_group_chat(Group_Chats *g_c)
}
non_null()
-static void wipe_group_c(Group_c *g)
+static void wipe_group_c(const Memory *mem, Group_c *g)
{
- free(g->frozen);
- free(g->group);
+ mem_delete(mem, g->frozen);
+ mem_delete(mem, g->group);
crypto_memzero(g, sizeof(Group_c));
}
@@ -318,7 +320,7 @@ static bool wipe_group_chat(Group_Chats *g_c, uint32_t groupnumber)
return false;
}
- wipe_group_c(&g_c->chats[groupnumber]);
+ wipe_group_c(g_c->mem, &g_c->chats[groupnumber]);
uint16_t i;
@@ -667,7 +669,7 @@ static int get_frozen_index(const Group_c *g, uint16_t peer_number)
}
non_null()
-static bool delete_frozen(Group_c *g, uint32_t frozen_index)
+static bool delete_frozen(const Memory *mem, Group_c *g, uint32_t frozen_index)
{
if (frozen_index >= g->numfrozen) {
return false;
@@ -676,14 +678,14 @@ static bool delete_frozen(Group_c *g, uint32_t frozen_index)
--g->numfrozen;
if (g->numfrozen == 0) {
- free(g->frozen);
+ mem_delete(mem, g->frozen);
g->frozen = nullptr;
} else {
if (g->numfrozen != frozen_index) {
g->frozen[frozen_index] = g->frozen[g->numfrozen];
}
- Group_Peer *const frozen_temp = (Group_Peer *)realloc(g->frozen, g->numfrozen * sizeof(Group_Peer));
+ Group_Peer *const frozen_temp = (Group_Peer *)mem_vrealloc(mem, g->frozen, g->numfrozen, sizeof(Group_Peer));
if (frozen_temp == nullptr) {
return false;
@@ -724,7 +726,7 @@ static int note_peer_active(Group_Chats *g_c, uint32_t groupnumber, uint16_t pee
/* Now thaw the peer */
- Group_Peer *temp = (Group_Peer *)realloc(g->group, (g->numpeers + 1) * sizeof(Group_Peer));
+ Group_Peer *temp = (Group_Peer *)mem_vrealloc(g_c->mem, g->group, g->numpeers + 1, sizeof(Group_Peer));
if (temp == nullptr) {
return -1;
@@ -741,7 +743,7 @@ static int note_peer_active(Group_Chats *g_c, uint32_t groupnumber, uint16_t pee
++g->numpeers;
- delete_frozen(g, frozen_index);
+ delete_frozen(g_c->mem, g, frozen_index);
if (g_c->peer_list_changed_callback != nullptr) {
g_c->peer_list_changed_callback(g_c->m, groupnumber, userdata);
@@ -777,7 +779,7 @@ static void delete_any_peer_with_pk(Group_Chats *g_c, uint32_t groupnumber, cons
const int frozen_index = frozen_in_group(g, real_pk);
if (frozen_index >= 0) {
- delete_frozen(g, frozen_index);
+ delete_frozen(g_c->mem, g, frozen_index);
}
}
@@ -837,7 +839,7 @@ static int addpeer(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_p
delete_any_peer_with_pk(g_c, groupnumber, real_pk, userdata);
- Group_Peer *temp = (Group_Peer *)realloc(g->group, (g->numpeers + 1) * sizeof(Group_Peer));
+ Group_Peer *temp = (Group_Peer *)mem_vrealloc(g_c->mem, g->group, g->numpeers + 1, sizeof(Group_Peer));
if (temp == nullptr) {
return -1;
@@ -928,14 +930,14 @@ static bool delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void
void *peer_object = g->group[peer_index].object;
if (g->numpeers == 0) {
- free(g->group);
+ mem_delete(g_c->mem, g->group);
g->group = nullptr;
} else {
if (g->numpeers != (uint32_t)peer_index) {
g->group[peer_index] = g->group[g->numpeers];
}
- Group_Peer *temp = (Group_Peer *)realloc(g->group, g->numpeers * sizeof(Group_Peer));
+ Group_Peer *temp = (Group_Peer *)mem_vrealloc(g_c->mem, g->group, g->numpeers, sizeof(Group_Peer));
if (temp == nullptr) {
return false;
@@ -957,39 +959,90 @@ static bool delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void
/** Order peers with friends first and with more recently active earlier */
non_null()
-static int cmp_frozen(const void *a, const void *b)
+static bool group_peer_less_handler(const void *object, const void *a, const void *b)
{
const Group_Peer *pa = (const Group_Peer *)a;
const Group_Peer *pb = (const Group_Peer *)b;
- if (pa->is_friend ^ pb->is_friend) {
- return pa->is_friend ? -1 : 1;
+ if (((pa->is_friend ? 1 : 0) ^ (pb->is_friend ? 1 : 0)) != 0) {
+ return pa->is_friend;
}
- return cmp_uint(pb->last_active, pa->last_active);
+ return cmp_uint(pb->last_active, pa->last_active) < 0;
}
+non_null()
+static const void *group_peer_get_handler(const void *arr, uint32_t index)
+{
+ const Group_Peer *entries = (const Group_Peer *)arr;
+ return &entries[index];
+}
+
+non_null()
+static void group_peer_set_handler(void *arr, uint32_t index, const void *val)
+{
+ Group_Peer *entries = (Group_Peer *)arr;
+ const Group_Peer *entry = (const Group_Peer *)val;
+ entries[index] = *entry;
+}
+
+non_null()
+static void *group_peer_subarr_handler(void *arr, uint32_t index, uint32_t size)
+{
+ Group_Peer *entries = (Group_Peer *)arr;
+ return &entries[index];
+}
+
+non_null()
+static void *group_peer_alloc_handler(const void *object, uint32_t size)
+{
+ const Memory *mem = (const Memory *)object;
+ Group_Peer *tmp = (Group_Peer *)mem_valloc(mem, size, sizeof(Group_Peer));
+
+ if (tmp == nullptr) {
+ return nullptr;
+ }
+
+ return tmp;
+}
+
+non_null()
+static void group_peer_delete_handler(const void *object, void *arr, uint32_t size)
+{
+ const Memory *mem = (const Memory *)object;
+ mem_delete(mem, arr);
+}
+
+static const Sort_Funcs group_peer_cmp_funcs = {
+ group_peer_less_handler,
+ group_peer_get_handler,
+ group_peer_set_handler,
+ group_peer_subarr_handler,
+ group_peer_alloc_handler,
+ group_peer_delete_handler,
+};
+
/** @brief Delete frozen peers as necessary to ensure at most `g->maxfrozen` remain.
*
* @retval true if any frozen peers are removed.
*/
non_null()
-static bool delete_old_frozen(Group_c *g)
+static bool delete_old_frozen(Group_c *g, const Memory *mem)
{
if (g->numfrozen <= g->maxfrozen) {
return false;
}
if (g->maxfrozen == 0) {
- free(g->frozen);
+ mem_delete(mem, g->frozen);
g->frozen = nullptr;
g->numfrozen = 0;
return true;
}
- qsort(g->frozen, g->numfrozen, sizeof(Group_Peer), cmp_frozen);
+ merge_sort(g->frozen, g->numfrozen, mem, &group_peer_cmp_funcs);
- Group_Peer *temp = (Group_Peer *)realloc(g->frozen, g->maxfrozen * sizeof(Group_Peer));
+ Group_Peer *temp = (Group_Peer *)mem_vrealloc(mem, g->frozen, g->maxfrozen, sizeof(Group_Peer));
if (temp == nullptr) {
return false;
@@ -1014,7 +1067,7 @@ static bool freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index,
return false;
}
- Group_Peer *temp = (Group_Peer *)realloc(g->frozen, (g->numfrozen + 1) * sizeof(Group_Peer));
+ Group_Peer *temp = (Group_Peer *)mem_vrealloc(g_c->mem, g->frozen, g->numfrozen + 1, sizeof(Group_Peer));
if (temp == nullptr) {
return false;
@@ -1032,7 +1085,7 @@ static bool freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index,
++g->numfrozen;
- delete_old_frozen(g);
+ delete_old_frozen(g, g_c->mem);
return true;
}
@@ -1519,7 +1572,7 @@ int group_set_max_frozen(const Group_Chats *g_c, uint32_t groupnumber, uint32_t
}
g->maxfrozen = maxfrozen;
- delete_old_frozen(g);
+ delete_old_frozen(g, g_c->mem);
return 0;
}
@@ -2520,7 +2573,7 @@ static int handle_send_peers(Group_Chats *g_c, uint32_t groupnumber, const uint8
non_null(1, 3) nullable(6)
static void handle_direct_packet(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *data, uint16_t length,
- int connection_index, void *userdata)
+ uint32_t connection_index, void *userdata)
{
if (length == 0) {
return;
@@ -2832,7 +2885,7 @@ static bool check_message_info(uint32_t message_number, uint8_t message_id, Grou
non_null(1, 3) nullable(6)
static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *data, uint16_t length,
- int connection_index, void *userdata)
+ uint32_t connection_index, void *userdata)
{
if (length < sizeof(uint16_t) + sizeof(uint32_t) + 1) {
return;
@@ -3612,7 +3665,7 @@ static uint32_t load_group(Group_c *g, const Group_Chats *g_c, const uint8_t *da
}
// This is inefficient, but allows us to check data consistency before allocating memory
- Group_Peer *tmp_frozen = (Group_Peer *)realloc(g->frozen, (j + 1) * sizeof(Group_Peer));
+ Group_Peer *tmp_frozen = (Group_Peer *)mem_vrealloc(g_c->mem, g->frozen, j + 1, sizeof(Group_Peer));
if (tmp_frozen == nullptr) {
// Memory allocation failure
@@ -3752,18 +3805,19 @@ bool conferences_load_state_section(Group_Chats *g_c, const uint8_t *data, uint3
}
/** Create new groupchat instance. */
-Group_Chats *new_groupchats(const Mono_Time *mono_time, Messenger *m)
+Group_Chats *new_groupchats(const Mono_Time *mono_time, const Memory *mem, Messenger *m)
{
if (m == nullptr) {
return nullptr;
}
- Group_Chats *temp = (Group_Chats *)calloc(1, sizeof(Group_Chats));
+ Group_Chats *temp = (Group_Chats *)mem_alloc(mem, sizeof(Group_Chats));
if (temp == nullptr) {
return nullptr;
}
+ temp->mem = mem;
temp->mono_time = mono_time;
temp->m = m;
temp->fr_c = m->fr_c;
@@ -3814,7 +3868,7 @@ void kill_groupchats(Group_Chats *g_c)
m_callback_conference_invite(g_c->m, nullptr);
set_global_status_callback(g_c->m->fr_c, nullptr, nullptr);
g_c->m->conferences_object = nullptr;
- free(g_c);
+ mem_delete(g_c->mem, g_c);
}
/**
diff --git a/protocols/Tox/libtox/src/toxcore/group.h b/protocols/Tox/libtox/src/toxcore/group.h
index 5ce03275ec..706428fdda 100644
--- a/protocols/Tox/libtox/src/toxcore/group.h
+++ b/protocols/Tox/libtox/src/toxcore/group.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2014 Tox project.
*/
@@ -15,6 +15,7 @@
#include "Messenger.h"
#include "attributes.h"
#include "crypto_core.h"
+#include "mem.h"
#include "mono_time.h"
#include "state.h"
@@ -390,7 +391,7 @@ bool conferences_load_state_section(
/** Create new groupchat instance. */
non_null()
-Group_Chats *new_groupchats(const Mono_Time *mono_time, Messenger *m);
+Group_Chats *new_groupchats(const Mono_Time *mono_time, const Memory *mem, Messenger *m);
/** main groupchats loop. */
non_null(1) nullable(2)
diff --git a/protocols/Tox/libtox/src/toxcore/group_announce.c b/protocols/Tox/libtox/src/toxcore/group_announce.c
index ee083198c1..caa70193aa 100644
--- a/protocols/Tox/libtox/src/toxcore/group_announce.c
+++ b/protocols/Tox/libtox/src/toxcore/group_announce.c
@@ -5,7 +5,6 @@
#include "group_announce.h"
-#include <stdlib.h>
#include <string.h>
#include "DHT.h"
@@ -13,6 +12,7 @@
#include "ccompat.h"
#include "crypto_core.h"
#include "logger.h"
+#include "mem.h"
#include "mono_time.h"
#include "network.h"
@@ -36,7 +36,7 @@ static void remove_announces(GC_Announces_List *gc_announces_list, GC_Announces
announces->next_announce->prev_announce = announces->prev_announce;
}
- free(announces);
+ mem_delete(gc_announces_list->mem, announces);
}
/**
@@ -343,10 +343,11 @@ int gca_unpack_announces_list(const Logger *log, const uint8_t *data, uint16_t l
non_null()
static GC_Announces *gca_new_announces(
+ const Memory *mem,
GC_Announces_List *gc_announces_list,
const GC_Public_Announce *public_announce)
{
- GC_Announces *announces = (GC_Announces *)calloc(1, sizeof(GC_Announces));
+ GC_Announces *announces = (GC_Announces *)mem_alloc(mem, sizeof(GC_Announces));
if (announces == nullptr) {
return nullptr;
@@ -366,7 +367,7 @@ static GC_Announces *gca_new_announces(
return announces;
}
-GC_Peer_Announce *gca_add_announce(const Mono_Time *mono_time, GC_Announces_List *gc_announces_list,
+GC_Peer_Announce *gca_add_announce(const Memory *mem, const Mono_Time *mono_time, GC_Announces_List *gc_announces_list,
const GC_Public_Announce *public_announce)
{
if (gc_announces_list == nullptr || public_announce == nullptr) {
@@ -377,7 +378,7 @@ GC_Peer_Announce *gca_add_announce(const Mono_Time *mono_time, GC_Announces_List
// No entry for this chat_id exists so we create one
if (announces == nullptr) {
- announces = gca_new_announces(gc_announces_list, public_announce);
+ announces = gca_new_announces(mem, gc_announces_list, public_announce);
if (announces == nullptr) {
return nullptr;
@@ -410,9 +411,17 @@ bool gca_is_valid_announce(const GC_Announce *announce)
return announce->tcp_relays_count > 0 || announce->ip_port_is_set;
}
-GC_Announces_List *new_gca_list(void)
+GC_Announces_List *new_gca_list(const Memory *mem)
{
- return (GC_Announces_List *)calloc(1, sizeof(GC_Announces_List));
+ GC_Announces_List *announces_list = (GC_Announces_List *)mem_alloc(mem, sizeof(GC_Announces_List));
+
+ if (announces_list == nullptr) {
+ return nullptr;
+ }
+
+ announces_list->mem = mem;
+
+ return announces_list;
}
void kill_gca(GC_Announces_List *announces_list)
@@ -425,11 +434,11 @@ void kill_gca(GC_Announces_List *announces_list)
while (root != nullptr) {
GC_Announces *next = root->next_announce;
- free(root);
+ mem_delete(announces_list->mem, root);
root = next;
}
- free(announces_list);
+ mem_delete(announces_list->mem, announces_list);
}
/* How long we save a peer's announce before we consider it stale and remove it. */
diff --git a/protocols/Tox/libtox/src/toxcore/group_announce.h b/protocols/Tox/libtox/src/toxcore/group_announce.h
index 72f2cfc1b8..2e043a069a 100644
--- a/protocols/Tox/libtox/src/toxcore/group_announce.h
+++ b/protocols/Tox/libtox/src/toxcore/group_announce.h
@@ -16,6 +16,7 @@
#include "attributes.h"
#include "crypto_core.h"
#include "logger.h"
+#include "mem.h"
#include "mono_time.h"
#include "network.h"
@@ -79,6 +80,8 @@ struct GC_Announces {
/* A list of all announces. */
struct GC_Announces_List {
+ const Memory *mem;
+
GC_Announces *root_announces;
uint64_t last_timeout_check;
};
@@ -87,7 +90,8 @@ struct GC_Announces_List {
*
* The caller is responsible for freeing the memory with `kill_gca`.
*/
-GC_Announces_List *new_gca_list(void);
+non_null()
+GC_Announces_List *new_gca_list(const Memory *mem);
/** @brief Frees all dynamically allocated memory associated with `announces_list`. */
nullable(1)
@@ -135,7 +139,7 @@ int gca_get_announces(const GC_Announces_List *gc_announces_list, GC_Announce *g
* @retval null on failure.
*/
non_null()
-GC_Peer_Announce *gca_add_announce(const Mono_Time *mono_time, GC_Announces_List *gc_announces_list,
+GC_Peer_Announce *gca_add_announce(const Memory *mem, const Mono_Time *mono_time, GC_Announces_List *gc_announces_list,
const GC_Public_Announce *public_announce);
/** @brief Packs an announce into a data buffer.
diff --git a/protocols/Tox/libtox/src/toxcore/group_chats.c b/protocols/Tox/libtox/src/toxcore/group_chats.c
index 96f647cc2e..43ed7e8272 100644
--- a/protocols/Tox/libtox/src/toxcore/group_chats.c
+++ b/protocols/Tox/libtox/src/toxcore/group_chats.c
@@ -12,7 +12,6 @@
#include <sodium.h>
#include <assert.h>
-#include <stdlib.h>
#include <string.h>
#include "DHT.h"
@@ -30,6 +29,7 @@
#include "group_moderation.h"
#include "group_pack.h"
#include "logger.h"
+#include "mem.h"
#include "mono_time.h"
#include "net_crypto.h"
#include "network.h"
@@ -168,8 +168,6 @@ non_null() static void group_delete(GC_Session *c, GC_Chat *chat);
non_null() static void group_cleanup(const GC_Session *c, GC_Chat *chat);
non_null() static bool group_exists(const GC_Session *c, const uint8_t *chat_id);
non_null() static void add_tcp_relays_to_chat(const GC_Session *c, GC_Chat *chat);
-non_null(1, 2) nullable(4)
-static bool peer_delete(const GC_Session *c, GC_Chat *chat, uint32_t peer_number, void *userdata);
non_null() static void create_gc_session_keypair(const Logger *log, const Random *rng, uint8_t *public_key,
uint8_t *secret_key);
non_null() static size_t load_gc_peers(GC_Chat *chat, const GC_SavedPeerInfo *addrs, uint16_t num_addrs);
@@ -837,6 +835,21 @@ static int saved_peer_index(const GC_Chat *chat, const uint8_t *public_key)
return -1;
}
+/** @brief Removes entry containing `public_key` from the saved peers list. */
+non_null()
+static void saved_peers_remove_entry(GC_Chat *chat, const uint8_t *public_key)
+{
+ const int idx = saved_peer_index(chat, public_key);
+
+ if (idx < 0) {
+ return;
+ }
+
+ chat->saved_peers[idx] = (GC_SavedPeerInfo) {
+ 0
+ };
+}
+
/** @brief Returns the index of the first vacant entry in saved peers list.
*
* If `public_key` is non-null and already exists in the list, its index will be returned.
@@ -961,7 +974,7 @@ non_null() static bool broadcast_gc_mod_list(const GC_Chat *chat);
non_null() static bool broadcast_gc_shared_state(const GC_Chat *chat);
non_null() static bool update_gc_sanctions_list(GC_Chat *chat, const uint8_t *public_sig_key);
non_null() static bool update_gc_topic(GC_Chat *chat, const uint8_t *public_sig_key);
-non_null() static bool send_gc_set_observer(const GC_Chat *chat, const uint8_t *target_ext_pk,
+non_null() static bool send_gc_set_observer(const GC_Chat *chat, const Extended_Public_Key *target_ext_pk,
const uint8_t *sanction_data, uint16_t length, bool add_obs);
/** Returns true if peer designated by `peer_number` is in the sanctions list as an observer. */
@@ -1119,7 +1132,7 @@ static bool prune_gc_mod_list(GC_Chat *chat)
non_null()
static bool prune_gc_sanctions_list_inner(
GC_Chat *chat, const Mod_Sanction *sanction,
- const uint8_t target_ext_pk[ENC_PUBLIC_KEY_SIZE + SIG_PUBLIC_KEY_SIZE])
+ const Extended_Public_Key *target_ext_pk)
{
if (!sanctions_list_remove_observer(&chat->moderation, sanction->target_public_enc_key, nullptr)) {
LOGGER_WARNING(chat->log, "Failed to remove entry from observer list");
@@ -1159,10 +1172,10 @@ static bool prune_gc_sanctions_list(GC_Chat *chat)
if (peer_number == -1) {
const Mod_Sanction *sanction = &chat->moderation.sanctions[i];
- uint8_t target_ext_pk[ENC_PUBLIC_KEY_SIZE + SIG_PUBLIC_KEY_SIZE];
- memcpy(target_ext_pk, sanction->target_public_enc_key, ENC_PUBLIC_KEY_SIZE);
- memcpy(target_ext_pk + ENC_PUBLIC_KEY_SIZE, sanction->setter_public_sig_key, SIG_PUBLIC_KEY_SIZE);
- return prune_gc_sanctions_list_inner(chat, sanction, target_ext_pk);
+ Extended_Public_Key target_ext_pk;
+ memcpy(target_ext_pk.enc, sanction->target_public_enc_key, ENC_PUBLIC_KEY_SIZE);
+ memcpy(target_ext_pk.sig, sanction->setter_public_sig_key, SIG_PUBLIC_KEY_SIZE);
+ return prune_gc_sanctions_list_inner(chat, sanction, &target_ext_pk);
}
}
@@ -1473,8 +1486,8 @@ static bool sign_gc_shared_state(GC_Chat *chat)
* Return -2 on decryption failure.
* Return -3 if plaintext payload length is invalid.
*/
-non_null(1, 2, 3, 5, 6) nullable(4)
-static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, uint8_t *data, uint64_t *message_id,
+non_null(1, 2, 3, 4, 6, 7) nullable(5)
+static int group_packet_unwrap(const Logger *log, const Memory *mem, const GC_Connection *gconn, uint8_t *data, uint64_t *message_id,
uint8_t *packet_type, const uint8_t *packet, uint16_t length)
{
assert(data != nullptr);
@@ -1485,18 +1498,18 @@ static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, ui
return -1;
}
- uint8_t *plain = (uint8_t *)malloc(length);
+ uint8_t *plain = (uint8_t *)mem_balloc(mem, length);
if (plain == nullptr) {
LOGGER_ERROR(log, "Failed to allocate memory for plain data buffer");
return -1;
}
- int plain_len = decrypt_data_symmetric(gconn->session_shared_key, packet, packet + CRYPTO_NONCE_SIZE,
+ int plain_len = decrypt_data_symmetric(mem, gconn->session_shared_key, packet, packet + CRYPTO_NONCE_SIZE,
length - CRYPTO_NONCE_SIZE, plain);
if (plain_len <= 0) {
- free(plain);
+ mem_delete(mem, plain);
return plain_len == 0 ? -3 : -2;
}
@@ -1510,7 +1523,7 @@ static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, ui
--plain_len;
if (plain_len < min_plain_len) {
- free(plain);
+ mem_delete(mem, plain);
return -3;
}
}
@@ -1527,13 +1540,13 @@ static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, ui
memcpy(data, real_plain + header_len, plain_len);
- free(plain);
+ mem_delete(mem, plain);
return plain_len;
}
int group_packet_wrap(
- const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet,
+ const Logger *log, const Memory *mem, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet,
uint16_t packet_size, const uint8_t *data, uint16_t length, uint64_t message_id,
uint8_t gp_packet_type, Net_Packet_Type net_packet_type)
{
@@ -1553,7 +1566,7 @@ int group_packet_wrap(
return -1;
}
- uint8_t *plain = (uint8_t *)malloc(packet_size);
+ uint8_t *plain = (uint8_t *)mem_balloc(mem, packet_size);
if (plain == nullptr) {
return -1;
@@ -1581,20 +1594,20 @@ int group_packet_wrap(
const uint16_t plain_len = padding_len + enc_header_len + length;
const uint16_t encrypt_buf_size = plain_len + CRYPTO_MAC_SIZE;
- uint8_t *encrypt = (uint8_t *)malloc(encrypt_buf_size);
+ uint8_t *encrypt = (uint8_t *)mem_balloc(mem, encrypt_buf_size);
if (encrypt == nullptr) {
- free(plain);
+ mem_delete(mem, plain);
return -2;
}
- const int enc_len = encrypt_data_symmetric(shared_key, nonce, plain, plain_len, encrypt);
+ const int enc_len = encrypt_data_symmetric(mem, shared_key, nonce, plain, plain_len, encrypt);
- free(plain);
+ mem_delete(mem, plain);
if (enc_len != encrypt_buf_size) {
LOGGER_ERROR(log, "encryption failed. packet type: 0x%02x, enc_len: %d", gp_packet_type, enc_len);
- free(encrypt);
+ mem_delete(mem, encrypt);
return -3;
}
@@ -1603,7 +1616,7 @@ int group_packet_wrap(
memcpy(packet + 1 + ENC_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE);
memcpy(packet + 1 + ENC_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, encrypt, enc_len);
- free(encrypt);
+ mem_delete(mem, encrypt);
return 1 + ENC_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + enc_len;
}
@@ -1613,7 +1626,7 @@ int group_packet_wrap(
* Returns true on success.
*/
non_null()
-static bool send_lossy_group_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *data,
+static bool send_lossy_group_packet(const GC_Chat *chat, GC_Connection *gconn, const uint8_t *data,
uint16_t length, uint8_t packet_type)
{
assert(length <= MAX_GC_CUSTOM_LOSSY_PACKET_SIZE);
@@ -1627,25 +1640,25 @@ static bool send_lossy_group_packet(const GC_Chat *chat, const GC_Connection *gc
}
const uint16_t packet_size = gc_get_wrapped_packet_size(length, NET_PACKET_GC_LOSSY);
- uint8_t *packet = (uint8_t *)malloc(packet_size);
+ uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, packet_size);
if (packet == nullptr) {
return false;
}
const int len = group_packet_wrap(
- chat->log, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet,
+ chat->log, chat->mem, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet,
packet_size, data, length, 0, packet_type, NET_PACKET_GC_LOSSY);
if (len < 0) {
LOGGER_ERROR(chat->log, "Failed to encrypt packet (type: 0x%02x, error: %d)", packet_type, len);
- free(packet);
+ mem_delete(chat->mem, packet);
return false;
}
const bool ret = gcc_send_packet(chat, gconn, packet, (uint16_t)len);
- free(packet);
+ mem_delete(chat->mem, packet);
return ret;
}
@@ -1883,7 +1896,7 @@ static bool sync_response_send_peers(GC_Chat *chat, GC_Connection *gconn, uint32
return true;
}
- uint8_t *response = (uint8_t *)malloc(MAX_GC_PACKET_CHUNK_SIZE);
+ uint8_t *response = (uint8_t *)mem_balloc(chat->mem, MAX_GC_PACKET_CHUNK_SIZE);
if (response == nullptr) {
return false;
@@ -1923,7 +1936,7 @@ static bool sync_response_send_peers(GC_Chat *chat, GC_Connection *gconn, uint32
++num_announces;
}
- free(response);
+ mem_delete(chat->mem, response);
if (num_announces == 0) {
// we send an empty sync response even if we didn't send any peers as an acknowledgement
@@ -2223,7 +2236,7 @@ static int handle_gc_invite_response_reject(const GC_Session *c, GC_Chat *chat,
* Return true on success.
*/
non_null()
-static bool send_gc_invite_response_reject(const GC_Chat *chat, const GC_Connection *gconn, uint8_t type)
+static bool send_gc_invite_response_reject(const GC_Chat *chat, GC_Connection *gconn, uint8_t type)
{
if (type >= GJ_INVALID) {
type = GJ_INVITE_FAILED;
@@ -2340,7 +2353,7 @@ static bool send_gc_lossy_packet_all_peers(const GC_Chat *chat, const uint8_t *d
uint32_t confirmed_peers = 0;
for (uint32_t i = 1; i < chat->numpeers; ++i) {
- const GC_Connection *gconn = get_gc_connection(chat, i);
+ GC_Connection *gconn = get_gc_connection(chat, i);
assert(gconn != nullptr);
@@ -2387,7 +2400,7 @@ static bool send_gc_broadcast_message(const GC_Chat *chat, const uint8_t *data,
return false;
}
- uint8_t *packet = (uint8_t *)malloc(length + GC_BROADCAST_ENC_HEADER_SIZE);
+ uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, length + GC_BROADCAST_ENC_HEADER_SIZE);
if (packet == nullptr) {
return false;
@@ -2397,7 +2410,7 @@ static bool send_gc_broadcast_message(const GC_Chat *chat, const uint8_t *data,
const bool ret = send_gc_lossless_packet_all_peers(chat, packet, packet_len, GP_BROADCAST);
- free(packet);
+ mem_delete(chat->mem, packet);
return ret;
}
@@ -2631,7 +2644,7 @@ void gc_get_chat_id(const GC_Chat *chat, uint8_t *dest)
non_null()
static bool send_self_to_peer(const GC_Chat *chat, GC_Connection *gconn)
{
- GC_Peer *self = (GC_Peer *)calloc(1, sizeof(GC_Peer));
+ GC_Peer *self = (GC_Peer *)mem_alloc(chat->mem, sizeof(GC_Peer));
if (self == nullptr) {
return false;
@@ -2640,10 +2653,10 @@ static bool send_self_to_peer(const GC_Chat *chat, GC_Connection *gconn)
copy_self(chat, self);
const uint16_t data_size = PACKED_GC_PEER_SIZE + sizeof(uint16_t) + MAX_GC_PASSWORD_SIZE;
- uint8_t *data = (uint8_t *)malloc(data_size);
+ uint8_t *data = (uint8_t *)mem_balloc(chat->mem, data_size);
if (data == nullptr) {
- free(self);
+ mem_delete(chat->mem, self);
return false;
}
@@ -2660,17 +2673,17 @@ static bool send_self_to_peer(const GC_Chat *chat, GC_Connection *gconn)
const int packed_len = pack_gc_peer(data + length, data_size - length, self);
length += packed_len;
- free(self);
+ mem_delete(chat->mem, self);
if (packed_len <= 0) {
LOGGER_DEBUG(chat->log, "pack_gc_peer failed in handle_gc_peer_info_request_request %d", packed_len);
- free(data);
+ mem_delete(chat->mem, data);
return false;
}
const bool ret = send_lossless_group_packet(chat, gconn, data, length, GP_PEER_INFO_RESPONSE);
- free(data);
+ mem_delete(chat->mem, data);
return ret;
}
@@ -2736,7 +2749,7 @@ static bool send_gc_peer_exchange(const GC_Chat *chat, GC_Connection *gconn)
* Return -5 if supplied group password is invalid.
* Return -6 if we fail to add the peer to the peer list.
* Return -7 if peer's role cannot be validated.
- * Return -8 if malloc fails.
+ * Return -8 if memory allocation fails.
*/
non_null(1, 2, 4) nullable(6)
static int handle_gc_peer_info_response(const GC_Session *c, GC_Chat *chat, uint32_t peer_number,
@@ -2781,7 +2794,7 @@ static int handle_gc_peer_info_response(const GC_Session *c, GC_Chat *chat, uint
return -1;
}
- GC_Peer *peer_info = (GC_Peer *)calloc(1, sizeof(GC_Peer));
+ GC_Peer *peer_info = (GC_Peer *)mem_alloc(chat->mem, sizeof(GC_Peer));
if (peer_info == nullptr) {
return -8;
@@ -2789,17 +2802,17 @@ static int handle_gc_peer_info_response(const GC_Session *c, GC_Chat *chat, uint
if (unpack_gc_peer(peer_info, data + unpacked_len, length - unpacked_len) == -1) {
LOGGER_ERROR(chat->log, "unpack_gc_peer() failed");
- free(peer_info);
+ mem_delete(chat->mem, peer_info);
return -6;
}
if (peer_update(chat, peer_info, peer_number) == -1) {
LOGGER_WARNING(chat->log, "peer_update() failed");
- free(peer_info);
+ mem_delete(chat->mem, peer_info);
return -6;
}
- free(peer_info);
+ mem_delete(chat->mem, peer_info);
const bool was_confirmed = gconn->confirmed;
gconn->confirmed = true;
@@ -3181,7 +3194,7 @@ static int handle_gc_sanctions_list(const GC_Session *c, GC_Chat *chat, const ui
Mod_Sanction_Creds creds;
- Mod_Sanction *sanctions = (Mod_Sanction *)calloc(num_sanctions, sizeof(Mod_Sanction));
+ Mod_Sanction *sanctions = (Mod_Sanction *)mem_valloc(chat->mem, num_sanctions, sizeof(Mod_Sanction));
if (sanctions == nullptr) {
return -1;
@@ -3192,25 +3205,25 @@ static int handle_gc_sanctions_list(const GC_Session *c, GC_Chat *chat, const ui
if (unpacked_num != num_sanctions) {
LOGGER_WARNING(chat->log, "Failed to unpack sanctions list: %d", unpacked_num);
- free(sanctions);
+ mem_delete(chat->mem, sanctions);
return handle_gc_sanctions_list_error(chat);
}
if (!sanctions_list_check_integrity(&chat->moderation, &creds, sanctions, num_sanctions)) {
LOGGER_WARNING(chat->log, "Sanctions list failed integrity check");
- free(sanctions);
+ mem_delete(chat->mem, sanctions);
return handle_gc_sanctions_list_error(chat);
}
if (creds.version < chat->moderation.sanctions_creds.version) {
- free(sanctions);
+ mem_delete(chat->mem, sanctions);
return 0;
}
// this may occur if two mods change the sanctions list at the exact same time
if (creds.version == chat->moderation.sanctions_creds.version
&& creds.checksum <= chat->moderation.sanctions_creds.checksum) {
- free(sanctions);
+ mem_delete(chat->mem, sanctions);
return 0;
}
@@ -3247,7 +3260,7 @@ static int make_gc_mod_list_packet(const GC_Chat *chat, uint8_t *data, uint32_t
const uint16_t length = sizeof(uint16_t) + mod_list_size;
if (mod_list_size > 0) {
- uint8_t *packed_mod_list = (uint8_t *)malloc(mod_list_size);
+ uint8_t *packed_mod_list = (uint8_t *)mem_balloc(chat->mem, mod_list_size);
if (packed_mod_list == nullptr) {
return -1;
@@ -3256,7 +3269,7 @@ static int make_gc_mod_list_packet(const GC_Chat *chat, uint8_t *data, uint32_t
mod_list_pack(&chat->moderation, packed_mod_list);
memcpy(data + sizeof(uint16_t), packed_mod_list, mod_list_size);
- free(packed_mod_list);
+ mem_delete(chat->mem, packed_mod_list);
}
return length;
@@ -3271,7 +3284,7 @@ static bool send_peer_mod_list(const GC_Chat *chat, GC_Connection *gconn)
{
const uint16_t mod_list_size = chat->moderation.num_mods * MOD_LIST_ENTRY_SIZE;
const uint16_t length = sizeof(uint16_t) + mod_list_size;
- uint8_t *packet = (uint8_t *)malloc(length);
+ uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, length);
if (packet == nullptr) {
return false;
@@ -3280,13 +3293,13 @@ static bool send_peer_mod_list(const GC_Chat *chat, GC_Connection *gconn)
const int packet_len = make_gc_mod_list_packet(chat, packet, length, mod_list_size);
if (packet_len != length) {
- free(packet);
+ mem_delete(chat->mem, packet);
return false;
}
const bool ret = send_lossless_group_packet(chat, gconn, packet, length, GP_MOD_LIST);
- free(packet);
+ mem_delete(chat->mem, packet);
return ret;
}
@@ -3330,7 +3343,7 @@ static bool send_peer_sanctions_list(const GC_Chat *chat, GC_Connection *gconn)
const uint16_t packet_size = MOD_SANCTION_PACKED_SIZE * chat->moderation.num_sanctions +
sizeof(uint16_t) + MOD_SANCTIONS_CREDS_SIZE;
- uint8_t *packet = (uint8_t *)malloc(packet_size);
+ uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, packet_size);
if (packet == nullptr) {
return false;
@@ -3339,13 +3352,13 @@ static bool send_peer_sanctions_list(const GC_Chat *chat, GC_Connection *gconn)
const int packet_len = make_gc_sanctions_list_packet(chat, packet, packet_size);
if (packet_len == -1) {
- free(packet);
+ mem_delete(chat->mem, packet);
return false;
}
const bool ret = send_lossless_group_packet(chat, gconn, packet, (uint16_t)packet_len, GP_SANCTIONS_LIST);
- free(packet);
+ mem_delete(chat->mem, packet);
return ret;
}
@@ -3360,7 +3373,7 @@ static bool broadcast_gc_sanctions_list(const GC_Chat *chat)
const uint16_t packet_size = MOD_SANCTION_PACKED_SIZE * chat->moderation.num_sanctions +
sizeof(uint16_t) + MOD_SANCTIONS_CREDS_SIZE;
- uint8_t *packet = (uint8_t *)malloc(packet_size);
+ uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, packet_size);
if (packet == nullptr) {
return false;
@@ -3369,13 +3382,13 @@ static bool broadcast_gc_sanctions_list(const GC_Chat *chat)
const int packet_len = make_gc_sanctions_list_packet(chat, packet, packet_size);
if (packet_len == -1) {
- free(packet);
+ mem_delete(chat->mem, packet);
return false;
}
const bool ret = send_gc_lossless_packet_all_peers(chat, packet, (uint16_t)packet_len, GP_SANCTIONS_LIST);
- free(packet);
+ mem_delete(chat->mem, packet);
return ret;
}
@@ -3406,7 +3419,7 @@ static bool broadcast_gc_mod_list(const GC_Chat *chat)
{
const uint16_t mod_list_size = chat->moderation.num_mods * MOD_LIST_ENTRY_SIZE;
const uint16_t length = sizeof(uint16_t) + mod_list_size;
- uint8_t *packet = (uint8_t *)malloc(length);
+ uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, length);
if (packet == nullptr) {
return false;
@@ -3415,13 +3428,13 @@ static bool broadcast_gc_mod_list(const GC_Chat *chat)
const int packet_len = make_gc_mod_list_packet(chat, packet, length, mod_list_size);
if (packet_len != length) {
- free(packet);
+ mem_delete(chat->mem, packet);
return false;
}
const bool ret = send_gc_lossless_packet_all_peers(chat, packet, length, GP_MOD_LIST);
- free(packet);
+ mem_delete(chat->mem, packet);
return ret;
}
@@ -3699,7 +3712,7 @@ non_null()
static bool send_peer_topic(const GC_Chat *chat, GC_Connection *gconn)
{
const uint16_t packet_buf_size = SIGNATURE_SIZE + chat->topic_info.length + GC_MIN_PACKED_TOPIC_INFO_SIZE;
- uint8_t *packet = (uint8_t *)malloc(packet_buf_size);
+ uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, packet_buf_size);
if (packet == nullptr) {
return false;
@@ -3708,16 +3721,16 @@ static bool send_peer_topic(const GC_Chat *chat, GC_Connection *gconn)
const int packet_len = make_gc_topic_packet(chat, packet, packet_buf_size);
if (packet_len != packet_buf_size) {
- free(packet);
+ mem_delete(chat->mem, packet);
return false;
}
if (!send_lossless_group_packet(chat, gconn, packet, packet_buf_size, GP_TOPIC)) {
- free(packet);
+ mem_delete(chat->mem, packet);
return false;
}
- free(packet);
+ mem_delete(chat->mem, packet);
return true;
}
@@ -3767,7 +3780,7 @@ non_null()
static bool broadcast_gc_topic(const GC_Chat *chat)
{
const uint16_t packet_buf_size = SIGNATURE_SIZE + chat->topic_info.length + GC_MIN_PACKED_TOPIC_INFO_SIZE;
- uint8_t *packet = (uint8_t *)malloc(packet_buf_size);
+ uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, packet_buf_size);
if (packet == nullptr) {
return false;
@@ -3776,13 +3789,13 @@ static bool broadcast_gc_topic(const GC_Chat *chat)
const int packet_len = make_gc_topic_packet(chat, packet, packet_buf_size);
if (packet_len != packet_buf_size) {
- free(packet);
+ mem_delete(chat->mem, packet);
return false;
}
const bool ret = send_gc_lossless_packet_all_peers(chat, packet, packet_buf_size, GP_TOPIC);
- free(packet);
+ mem_delete(chat->mem, packet);
return ret;
}
@@ -3832,7 +3845,7 @@ int gc_set_topic(GC_Chat *chat, const uint8_t *topic, uint16_t length)
chat->topic_info.checksum = get_gc_topic_checksum(&chat->topic_info);
const uint16_t packet_buf_size = length + GC_MIN_PACKED_TOPIC_INFO_SIZE;
- uint8_t *packed_topic = (uint8_t *)malloc(packet_buf_size);
+ uint8_t *packed_topic = (uint8_t *)mem_balloc(chat->mem, packet_buf_size);
if (packed_topic == nullptr) {
return -3;
@@ -3859,13 +3872,13 @@ int gc_set_topic(GC_Chat *chat, const uint8_t *topic, uint16_t length)
chat->topic_prev_checksum = old_topic_info.checksum;
chat->topic_time_set = mono_time_get(chat->mono_time);
- free(packed_topic);
+ mem_delete(chat->mem, packed_topic);
return 0;
ON_ERROR:
chat->topic_info = old_topic_info;
memcpy(chat->topic_sig, old_topic_sig, SIGNATURE_SIZE);
- free(packed_topic);
+ mem_delete(chat->mem, packed_topic);
return err;
}
@@ -4116,24 +4129,24 @@ int gc_founder_set_password(GC_Chat *chat, const uint8_t *password, uint16_t pas
}
const uint16_t oldlen = chat->shared_state.password_length;
- uint8_t *oldpasswd = memdup(chat->shared_state.password, oldlen);
+ uint8_t *oldpasswd = memdup(chat->mem, chat->shared_state.password, oldlen);
if (oldpasswd == nullptr && oldlen > 0) {
return -4;
}
if (!set_gc_password_local(chat, password, password_length)) {
- free(oldpasswd);
+ mem_delete(chat->mem, oldpasswd);
return -2;
}
if (!sign_gc_shared_state(chat)) {
set_gc_password_local(chat, oldpasswd, oldlen);
- free(oldpasswd);
+ mem_delete(chat->mem, oldpasswd);
return -2;
}
- free(oldpasswd);
+ mem_delete(chat->mem, oldpasswd);
if (!broadcast_gc_shared_state(chat)) {
return -3;
@@ -4258,7 +4271,7 @@ non_null()
static bool send_gc_set_mod(const GC_Chat *chat, const GC_Connection *gconn, bool add_mod)
{
const uint16_t length = 1 + SIG_PUBLIC_KEY_SIZE;
- uint8_t *data = (uint8_t *)malloc(length);
+ uint8_t *data = (uint8_t *)mem_balloc(chat->mem, length);
if (data == nullptr) {
return false;
@@ -4269,11 +4282,11 @@ static bool send_gc_set_mod(const GC_Chat *chat, const GC_Connection *gconn, boo
memcpy(data + 1, get_sig_pk(&gconn->addr.public_key), SIG_PUBLIC_KEY_SIZE);
if (!send_gc_broadcast_message(chat, data, length, GM_SET_MOD)) {
- free(data);
+ mem_delete(chat->mem, data);
return false;
}
- free(data);
+ mem_delete(chat->mem, data);
return true;
}
@@ -4457,11 +4470,11 @@ static int handle_gc_set_observer(const GC_Session *c, GC_Chat *chat, uint32_t p
* Returns true on success.
*/
non_null()
-static bool send_gc_set_observer(const GC_Chat *chat, const uint8_t *target_ext_pk, const uint8_t *sanction_data,
- uint16_t length, bool add_obs)
+static bool send_gc_set_observer(const GC_Chat *chat, const Extended_Public_Key *target_ext_pk,
+ const uint8_t *sanction_data, uint16_t length, bool add_obs)
{
- const uint16_t packet_len = 1 + EXT_PUBLIC_KEY_SIZE + length;
- uint8_t *packet = (uint8_t *)malloc(packet_len);
+ const uint16_t packet_len = 1 + ENC_PUBLIC_KEY_SIZE + SIG_PUBLIC_KEY_SIZE + length;
+ uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, packet_len);
if (packet == nullptr) {
return false;
@@ -4469,15 +4482,16 @@ static bool send_gc_set_observer(const GC_Chat *chat, const uint8_t *target_ext_
net_pack_bool(&packet[0], add_obs);
- memcpy(packet + 1, target_ext_pk, EXT_PUBLIC_KEY_SIZE);
- memcpy(packet + 1 + EXT_PUBLIC_KEY_SIZE, sanction_data, length);
+ memcpy(packet + 1, target_ext_pk->enc, ENC_PUBLIC_KEY_SIZE);
+ memcpy(packet + 1 + ENC_PUBLIC_KEY_SIZE, target_ext_pk->sig, SIG_PUBLIC_KEY_SIZE);
+ memcpy(packet + 1 + ENC_PUBLIC_KEY_SIZE + SIG_PUBLIC_KEY_SIZE, sanction_data, length);
if (!send_gc_broadcast_message(chat, packet, packet_len, GM_SET_OBSERVER)) {
- free(packet);
+ mem_delete(chat->mem, packet);
return false;
}
- free(packet);
+ mem_delete(chat->mem, packet);
return true;
}
@@ -4557,7 +4571,7 @@ static bool mod_gc_set_observer(GC_Chat *chat, uint32_t peer_number, bool add_ob
update_gc_peer_roles(chat);
- return send_gc_set_observer(chat, gconn->addr.public_key.enc, sanction_data, length, add_obs);
+ return send_gc_set_observer(chat, &gconn->addr.public_key, sanction_data, length, add_obs);
}
/** @brief Sets the role of `peer_number` to `new_role`. If necessary this function will first
@@ -4894,7 +4908,7 @@ int gc_send_message(const GC_Chat *chat, const uint8_t *message, uint16_t length
const uint8_t packet_type = type == GC_MESSAGE_TYPE_NORMAL ? GM_PLAIN_MESSAGE : GM_ACTION_MESSAGE;
const uint16_t length_raw = length + GC_MESSAGE_PSEUDO_ID_SIZE;
- uint8_t *message_raw = (uint8_t *)malloc(length_raw);
+ uint8_t *message_raw = (uint8_t *)mem_balloc(chat->mem, length_raw);
if (message_raw == nullptr) {
return -5;
@@ -4906,15 +4920,16 @@ int gc_send_message(const GC_Chat *chat, const uint8_t *message, uint16_t length
memcpy(message_raw + GC_MESSAGE_PSEUDO_ID_SIZE, message, length);
if (!send_gc_broadcast_message(chat, message_raw, length_raw, packet_type)) {
- free(message_raw);
+ mem_delete(chat->mem, message_raw);
return -5;
}
+ mem_delete(chat->mem, message_raw);
+
if (message_id != nullptr) {
*message_id = pseudo_msg_id;
}
- free(message_raw);
return 0;
}
@@ -4954,7 +4969,7 @@ static int handle_gc_message(const GC_Session *c, const GC_Chat *chat, const GC_
}
int gc_send_private_message(const GC_Chat *chat, GC_Peer_Id peer_id, uint8_t type, const uint8_t *message,
- uint16_t length)
+ uint16_t length, uint32_t *message_id)
{
if (length > MAX_GC_MESSAGE_SIZE) {
return -1;
@@ -4980,32 +4995,41 @@ int gc_send_private_message(const GC_Chat *chat, GC_Peer_Id peer_id, uint8_t typ
return -5;
}
- uint8_t *message_with_type = (uint8_t *)malloc(length + 1);
+ const uint16_t raw_length = 1 + length + GC_MESSAGE_PSEUDO_ID_SIZE;
+ uint8_t *message_with_type = (uint8_t *)mem_balloc(chat->mem, raw_length);
if (message_with_type == nullptr) {
return -6;
}
message_with_type[0] = type;
- memcpy(message_with_type + 1, message, length);
- uint8_t *packet = (uint8_t *)malloc(length + 1 + GC_BROADCAST_ENC_HEADER_SIZE);
+ const uint32_t pseudo_msg_id = random_u32(chat->rng);
+ net_pack_u32(message_with_type + 1, pseudo_msg_id);
+
+ memcpy(message_with_type + 1 + GC_MESSAGE_PSEUDO_ID_SIZE, message, length);
+
+ uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, raw_length + GC_BROADCAST_ENC_HEADER_SIZE);
if (packet == nullptr) {
- free(message_with_type);
+ mem_delete(chat->mem, message_with_type);
return -6;
}
- const uint16_t packet_len = make_gc_broadcast_header(message_with_type, length + 1, packet, GM_PRIVATE_MESSAGE);
+ const uint16_t packet_len = make_gc_broadcast_header(message_with_type, raw_length, packet, GM_PRIVATE_MESSAGE);
- free(message_with_type);
+ mem_delete(chat->mem, message_with_type);
if (!send_lossless_group_packet(chat, gconn, packet, packet_len, GP_BROADCAST)) {
- free(packet);
+ mem_delete(chat->mem, packet);
return -6;
}
- free(packet);
+ mem_delete(chat->mem, packet);
+
+ if (message_id != nullptr) {
+ *message_id = pseudo_msg_id;
+ }
return 0;
}
@@ -5019,7 +5043,7 @@ non_null(1, 2, 3, 4) nullable(6)
static int handle_gc_private_message(const GC_Session *c, const GC_Chat *chat, const GC_Peer *peer, const uint8_t *data,
uint16_t length, void *userdata)
{
- if (data == nullptr || length > MAX_GC_MESSAGE_SIZE || length <= 1) {
+ if (data == nullptr || length > MAX_GC_MESSAGE_SIZE || length <= 1 + GC_MESSAGE_PSEUDO_ID_SIZE) {
return -1;
}
@@ -5034,8 +5058,13 @@ static int handle_gc_private_message(const GC_Session *c, const GC_Chat *chat, c
return 0;
}
+ uint32_t message_id;
+ net_unpack_u32(data + 1, &message_id);
+
if (c->private_message != nullptr) {
- c->private_message(c->messenger, chat->group_number, peer->peer_id, message_type, data + 1, length - 1, userdata);
+ c->private_message(c->messenger, chat->group_number, peer->peer_id, message_type,
+ data + 1 + GC_MESSAGE_PSEUDO_ID_SIZE, length - 1 - GC_MESSAGE_PSEUDO_ID_SIZE,
+ message_id, userdata);
}
return 0;
@@ -5066,10 +5095,6 @@ int gc_send_custom_private_packet(const GC_Chat *chat, bool lossless, GC_Peer_Id
return -3;
}
- if (gc_get_self_role(chat) >= GR_OBSERVER) {
- return -4;
- }
-
bool ret;
if (lossless) {
@@ -5078,7 +5103,7 @@ int gc_send_custom_private_packet(const GC_Chat *chat, bool lossless, GC_Peer_Id
ret = send_lossy_group_packet(chat, gconn, message, length, GP_CUSTOM_PRIVATE_PACKET);
}
- return ret ? 0 : -5;
+ return ret ? 0 : -4;
}
/** @brief Handles a custom private packet.
@@ -5098,10 +5123,6 @@ static int handle_gc_custom_private_packet(const GC_Session *c, const GC_Chat *c
return -1;
}
- if (peer->ignore || peer->role >= GR_OBSERVER) {
- return 0;
- }
-
if (c->custom_private_packet != nullptr) {
c->custom_private_packet(c->messenger, chat->group_number, peer->peer_id, data, length, userdata);
}
@@ -5119,10 +5140,6 @@ int gc_send_custom_packet(const GC_Chat *chat, bool lossless, const uint8_t *dat
return -2;
}
- if (gc_get_self_role(chat) >= GR_OBSERVER) {
- return -3;
- }
-
bool success;
if (lossless) {
@@ -5131,7 +5148,7 @@ int gc_send_custom_packet(const GC_Chat *chat, bool lossless, const uint8_t *dat
success = send_gc_lossy_packet_all_peers(chat, data, length, GP_CUSTOM_PACKET);
}
- return success ? 0 : -4;
+ return success ? 0 : -3;
}
/** @brief Handles a custom packet.
@@ -5151,10 +5168,6 @@ static int handle_gc_custom_packet(const GC_Session *c, const GC_Chat *chat, con
return -1;
}
- if (peer->ignore || peer->role >= GR_OBSERVER) {
- return 0;
- }
-
if (c->custom_packet != nullptr) {
c->custom_packet(c->messenger, chat->group_number, peer->peer_id, data, length, userdata);
}
@@ -5330,7 +5343,7 @@ static int handle_gc_message_ack(const GC_Chat *chat, GC_Connection *gconn, cons
const Group_Message_Ack_Type type = (Group_Message_Ack_Type) data[0];
if (type == GR_ACK_RECV) {
- if (!gcc_handle_ack(chat->log, gconn, message_id)) {
+ if (!gcc_handle_ack(chat->log, chat->mem, gconn, message_id)) {
return -2;
}
@@ -5508,7 +5521,7 @@ static int handle_gc_broadcast(const GC_Session *c, GC_Chat *chat, uint32_t peer
* Return -2 if decryption fails.
*/
non_null()
-static int unwrap_group_handshake_packet(const Logger *log, const uint8_t *self_sk, const uint8_t *sender_pk,
+static int unwrap_group_handshake_packet(const Logger *log, const Memory *mem, const uint8_t *self_sk, const uint8_t *sender_pk,
uint8_t *plain, size_t plain_size, const uint8_t *packet, uint16_t length)
{
if (length <= CRYPTO_NONCE_SIZE) {
@@ -5516,7 +5529,7 @@ static int unwrap_group_handshake_packet(const Logger *log, const uint8_t *self_
return -1;
}
- const int plain_len = decrypt_data(sender_pk, self_sk, packet, packet + CRYPTO_NONCE_SIZE,
+ const int plain_len = decrypt_data(mem, sender_pk, self_sk, packet, packet + CRYPTO_NONCE_SIZE,
length - CRYPTO_NONCE_SIZE, plain);
if (plain_len < 0 || (uint32_t)plain_len != plain_size) {
@@ -5534,12 +5547,12 @@ static int unwrap_group_handshake_packet(const Logger *log, const uint8_t *self_
*
* Return length of encrypted packet on success.
* Return -1 if packet size is invalid.
- * Return -2 on malloc failure.
+ * Return -2 on memory allocation failure.
* Return -3 if encryption fails.
*/
non_null()
static int wrap_group_handshake_packet(
- const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *self_sk,
+ const Logger *log, const Memory *mem, const Random *rng, const uint8_t *self_pk, const uint8_t *self_sk,
const uint8_t *target_pk, uint8_t *packet, uint32_t packet_size,
const uint8_t *data, uint16_t length)
{
@@ -5552,17 +5565,17 @@ static int wrap_group_handshake_packet(
random_nonce(rng, nonce);
const size_t encrypt_buf_size = length + CRYPTO_MAC_SIZE;
- uint8_t *encrypt = (uint8_t *)malloc(encrypt_buf_size);
+ uint8_t *encrypt = (uint8_t *)mem_balloc(mem, encrypt_buf_size);
if (encrypt == nullptr) {
return -2;
}
- const int enc_len = encrypt_data(target_pk, self_sk, nonce, data, length, encrypt);
+ const int enc_len = encrypt_data(mem, target_pk, self_sk, nonce, data, length, encrypt);
if (enc_len < 0 || (size_t)enc_len != encrypt_buf_size) {
LOGGER_ERROR(log, "Failed to encrypt group handshake packet (len: %d)", enc_len);
- free(encrypt);
+ mem_delete(mem, encrypt);
return -3;
}
@@ -5572,7 +5585,7 @@ static int wrap_group_handshake_packet(
memcpy(packet + 1 + ENC_PUBLIC_KEY_SIZE + ENC_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE);
memcpy(packet + 1 + ENC_PUBLIC_KEY_SIZE + ENC_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, encrypt, enc_len);
- free(encrypt);
+ mem_delete(mem, encrypt);
return 1 + ENC_PUBLIC_KEY_SIZE + ENC_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + enc_len;
}
@@ -5622,7 +5635,7 @@ static int make_gc_handshake_packet(const GC_Chat *chat, const GC_Connection *gc
}
const int enc_len = wrap_group_handshake_packet(
- chat->log, chat->rng, chat->self_public_key.enc, chat->self_secret_key.enc,
+ chat->log, chat->mem, chat->rng, chat->self_public_key.enc, chat->self_secret_key.enc,
gconn->addr.public_key.enc, packet, (uint16_t)packet_size, data, length);
if (enc_len != GC_MIN_ENCRYPTED_HS_PAYLOAD_SIZE + nodes_size) {
@@ -5945,18 +5958,18 @@ static int handle_gc_handshake_packet(GC_Chat *chat, const uint8_t *sender_pk, c
}
const size_t data_buf_size = length - CRYPTO_NONCE_SIZE - CRYPTO_MAC_SIZE;
- uint8_t *data = (uint8_t *)malloc(data_buf_size);
+ uint8_t *data = (uint8_t *)mem_balloc(chat->mem, data_buf_size);
if (data == nullptr) {
return -1;
}
- const int plain_len = unwrap_group_handshake_packet(chat->log, chat->self_secret_key.enc, sender_pk, data,
+ const int plain_len = unwrap_group_handshake_packet(chat->log, chat->mem, chat->self_secret_key.enc, sender_pk, data,
data_buf_size, packet, length);
if (plain_len < GC_MIN_HS_PACKET_PAYLOAD_SIZE) {
LOGGER_DEBUG(chat->log, "Failed to unwrap handshake packet (probably a stale request using an old key)");
- free(data);
+ mem_delete(chat->mem, data);
return -1;
}
@@ -5972,11 +5985,11 @@ static int handle_gc_handshake_packet(GC_Chat *chat, const uint8_t *sender_pk, c
} else if (handshake_type == GH_RESPONSE) {
peer_number = handle_gc_handshake_response(chat, sender_pk, real_data, real_len);
} else {
- free(data);
+ mem_delete(chat->mem, data);
return -1;
}
- free(data);
+ mem_delete(chat->mem, data);
GC_Connection *gconn = get_gc_connection(chat, peer_number);
@@ -6171,7 +6184,7 @@ static bool handle_gc_lossless_packet(const GC_Session *c, GC_Chat *chat, const
return true;
}
- uint8_t *data = (uint8_t *)malloc(length);
+ uint8_t *data = (uint8_t *)mem_balloc(chat->mem, length);
if (data == nullptr) {
LOGGER_DEBUG(chat->log, "Failed to allocate memory for packet data buffer");
@@ -6181,19 +6194,19 @@ static bool handle_gc_lossless_packet(const GC_Session *c, GC_Chat *chat, const
uint8_t packet_type;
uint64_t message_id;
- const int len = group_packet_unwrap(chat->log, gconn, data, &message_id, &packet_type, packet, length);
+ const int len = group_packet_unwrap(chat->log, chat->mem, gconn, data, &message_id, &packet_type, packet, length);
if (len < 0) {
Ip_Ntoa ip_str;
LOGGER_DEBUG(chat->log, "Failed to unwrap lossless packet from %s:%d: %d",
net_ip_ntoa(&gconn->addr.ip_port.ip, &ip_str), net_ntohs(gconn->addr.ip_port.port), len);
- free(data);
+ mem_delete(chat->mem, data);
return false;
}
if (!gconn->handshaked && (packet_type != GP_HS_RESPONSE_ACK && packet_type != GP_INVITE_REQUEST)) {
LOGGER_DEBUG(chat->log, "Got lossless packet type 0x%02x from unconfirmed peer", packet_type);
- free(data);
+ mem_delete(chat->mem, data);
return false;
}
@@ -6203,28 +6216,27 @@ static bool handle_gc_lossless_packet(const GC_Session *c, GC_Chat *chat, const
if (message_id == 3 && is_invite_packet && gconn->received_message_id <= 1) {
// we missed initial handshake request. Drop this packet and wait for another handshake request.
LOGGER_DEBUG(chat->log, "Missed handshake packet, type: 0x%02x", packet_type);
- free(data);
+ mem_delete(chat->mem, data);
return false;
}
- const int lossless_ret = gcc_handle_received_message(chat->log, chat->mono_time, gconn, data, (uint16_t) len,
- packet_type, message_id, direct_conn);
+ const int lossless_ret = gcc_handle_received_message(chat->log, chat->mem, chat->mono_time, gconn, data, (uint16_t) len, packet_type, message_id, direct_conn);
if (packet_type == GP_INVITE_REQUEST && !gconn->handshaked) { // Both peers sent request at same time
- free(data);
+ mem_delete(chat->mem, data);
return true;
}
if (lossless_ret < 0) {
LOGGER_DEBUG(chat->log, "failed to handle packet %llu (type: 0x%02x, id: %llu)",
(unsigned long long)message_id, packet_type, (unsigned long long)message_id);
- free(data);
+ mem_delete(chat->mem, data);
return false;
}
/* Duplicate packet */
if (lossless_ret == 0) {
- free(data);
+ mem_delete(chat->mem, data);
return gc_send_message_ack(chat, gconn, message_id, GR_ACK_RECV);
}
@@ -6232,7 +6244,7 @@ static bool handle_gc_lossless_packet(const GC_Session *c, GC_Chat *chat, const
if (lossless_ret == 1) {
LOGGER_TRACE(chat->log, "received out of order packet from peer %u. expected %llu, got %llu", peer_number,
(unsigned long long)gconn->received_message_id + 1, (unsigned long long)message_id);
- free(data);
+ mem_delete(chat->mem, data);
return gc_send_message_ack(chat, gconn, gconn->received_message_id + 1, GR_ACK_REQ);
}
@@ -6240,13 +6252,13 @@ static bool handle_gc_lossless_packet(const GC_Session *c, GC_Chat *chat, const
if (lossless_ret == 3) {
const bool frag_ret = handle_gc_packet_fragment(c, chat, peer_number, gconn, data, (uint16_t)len, packet_type,
message_id, userdata);
- free(data);
+ mem_delete(chat->mem, data);
return frag_ret;
}
const bool ret = handle_gc_lossless_helper(c, chat, peer_number, data, (uint16_t)len, packet_type, userdata);
- free(data);
+ mem_delete(chat->mem, data);
if (!ret) {
return false;
@@ -6325,7 +6337,7 @@ static bool handle_gc_lossy_packet(const GC_Session *c, GC_Chat *chat, const uin
return false;
}
- uint8_t *data = (uint8_t *)malloc(length);
+ uint8_t *data = (uint8_t *)mem_balloc(chat->mem, length);
if (data == nullptr) {
LOGGER_ERROR(chat->log, "Failed to allocate memory for packet buffer");
@@ -6334,19 +6346,19 @@ static bool handle_gc_lossy_packet(const GC_Session *c, GC_Chat *chat, const uin
uint8_t packet_type;
- const int len = group_packet_unwrap(chat->log, gconn, data, nullptr, &packet_type, packet, length);
+ const int len = group_packet_unwrap(chat->log, chat->mem, gconn, data, nullptr, &packet_type, packet, length);
if (len <= 0) {
Ip_Ntoa ip_str;
LOGGER_DEBUG(chat->log, "Failed to unwrap lossy packet from %s:%d: %d",
net_ip_ntoa(&gconn->addr.ip_port.ip, &ip_str), net_ntohs(gconn->addr.ip_port.port), len);
- free(data);
+ mem_delete(chat->mem, data);
return false;
}
const int ret = handle_gc_lossy_packet_decoded(c, chat, gconn, peer, packet_type, data, (uint16_t)len, userdata);
- free(data);
+ mem_delete(chat->mem, data);
if (ret < 0) {
LOGGER_DEBUG(chat->log, "Lossy packet handle error %d: type: 0x%02x, peernumber %d", ret, packet_type,
@@ -6702,6 +6714,7 @@ void gc_callback_rejected(const Messenger *m, gc_rejected_cb *function)
*
* Return true on success.
*/
+non_null(1, 2) nullable(4)
static bool peer_delete(const GC_Session *c, GC_Chat *chat, uint32_t peer_number, void *userdata)
{
GC_Peer *peer = get_gc_peer(chat, peer_number);
@@ -6710,17 +6723,23 @@ static bool peer_delete(const GC_Session *c, GC_Chat *chat, uint32_t peer_number
return false;
}
+ GC_Connection *gconn = &peer->gconn;
+
// We need to save some peer info for the callback before deleting it
- const bool peer_confirmed = peer->gconn.confirmed;
+ const bool peer_confirmed = gconn->confirmed;
const GC_Peer_Id peer_id = peer->peer_id;
uint8_t nick[MAX_GC_NICK_SIZE];
const uint16_t nick_length = peer->nick_length;
- const GC_Exit_Info exit_info = peer->gconn.exit_info;
+ const GC_Exit_Info exit_info = gconn->exit_info;
assert(nick_length <= MAX_GC_NICK_SIZE);
memcpy(nick, peer->nick, nick_length);
- gcc_peer_cleanup(&peer->gconn);
+ if (exit_info.exit_type == GC_EXIT_TYPE_KICKED) {
+ saved_peers_remove_entry(chat, gconn->addr.public_key.enc);
+ }
+
+ gcc_peer_cleanup(chat->mem, gconn);
--chat->numpeers;
@@ -6732,7 +6751,7 @@ static bool peer_delete(const GC_Session *c, GC_Chat *chat, uint32_t peer_number
0
};
- GC_Peer *tmp_group = (GC_Peer *)realloc(chat->group, chat->numpeers * sizeof(GC_Peer));
+ GC_Peer *tmp_group = (GC_Peer *)mem_vrealloc(chat->mem, chat->group, chat->numpeers, sizeof(GC_Peer));
if (tmp_group == nullptr) {
return false;
@@ -6808,8 +6827,8 @@ int peer_add(GC_Chat *chat, const IP_Port *ipp, const uint8_t *public_key)
}
}
- GC_Message_Array_Entry *send = (GC_Message_Array_Entry *)calloc(GCC_BUFFER_SIZE, sizeof(GC_Message_Array_Entry));
- GC_Message_Array_Entry *recv = (GC_Message_Array_Entry *)calloc(GCC_BUFFER_SIZE, sizeof(GC_Message_Array_Entry));
+ GC_Message_Array_Entry *send = (GC_Message_Array_Entry *)mem_valloc(chat->mem, GCC_BUFFER_SIZE, sizeof(GC_Message_Array_Entry));
+ GC_Message_Array_Entry *recv = (GC_Message_Array_Entry *)mem_valloc(chat->mem, GCC_BUFFER_SIZE, sizeof(GC_Message_Array_Entry));
if (send == nullptr || recv == nullptr) {
LOGGER_ERROR(chat->log, "Failed to allocate memory for gconn buffers");
@@ -6818,22 +6837,22 @@ int peer_add(GC_Chat *chat, const IP_Port *ipp, const uint8_t *public_key)
kill_tcp_connection_to(chat->tcp_conn, tcp_connection_num);
}
- free(send);
- free(recv);
+ mem_delete(chat->mem, send);
+ mem_delete(chat->mem, recv);
return -1;
}
- GC_Peer *tmp_group = (GC_Peer *)realloc(chat->group, (chat->numpeers + 1) * sizeof(GC_Peer));
+ GC_Peer *tmp_group = (GC_Peer *)mem_vrealloc(chat->mem, chat->group, chat->numpeers + 1, sizeof(GC_Peer));
if (tmp_group == nullptr) {
- LOGGER_ERROR(chat->log, "Failed to allocate memory for group realloc");
+ LOGGER_ERROR(chat->log, "Failed to allocate memory for group mem_vrealloc");
if (tcp_connection_num != -1) {
kill_tcp_connection_to(chat->tcp_conn, tcp_connection_num);
}
- free(send);
- free(recv);
+ mem_delete(chat->mem, send);
+ mem_delete(chat->mem, recv);
return -1;
}
@@ -7053,10 +7072,10 @@ static void do_peer_delete(const GC_Session *c, GC_Chat *chat, void *userdata)
* Return true on success.
*/
non_null()
-static bool ping_peer(const GC_Chat *chat, const GC_Connection *gconn)
+static bool ping_peer(const GC_Chat *chat, GC_Connection *gconn)
{
const uint16_t buf_size = GC_PING_PACKET_MIN_DATA_SIZE + sizeof(IP_Port);
- uint8_t *data = (uint8_t *)malloc(buf_size);
+ uint8_t *data = (uint8_t *)mem_balloc(chat->mem, buf_size);
if (data == nullptr) {
return false;
@@ -7102,11 +7121,11 @@ static bool ping_peer(const GC_Chat *chat, const GC_Connection *gconn)
}
if (!send_lossy_group_packet(chat, gconn, data, packed_len, GP_PING)) {
- free(data);
+ mem_delete(chat->mem, data);
return false;
}
- free(data);
+ mem_delete(chat->mem, data);
return true;
}
@@ -7319,15 +7338,15 @@ void do_gc(GC_Session *c, void *userdata)
* Return true on success.
*/
non_null()
-static bool realloc_groupchats(GC_Session *c, uint32_t n)
+static bool realloc_groupchats(const Memory *mem, GC_Session *c, uint32_t n)
{
if (n == 0) {
- free(c->chats);
+ mem_delete(mem, c->chats);
c->chats = nullptr;
return true;
}
- GC_Chat *temp = (GC_Chat *)realloc(c->chats, n * sizeof(GC_Chat));
+ GC_Chat *temp = (GC_Chat *)mem_vrealloc(mem, c->chats, n, sizeof(GC_Chat));
if (temp == nullptr) {
return false;
@@ -7338,7 +7357,7 @@ static bool realloc_groupchats(GC_Session *c, uint32_t n)
}
non_null()
-static int get_new_group_index(GC_Session *c)
+static int get_new_group_index(const Memory *mem, GC_Session *c)
{
if (c == nullptr) {
return -1;
@@ -7350,7 +7369,7 @@ static int get_new_group_index(GC_Session *c)
}
}
- if (!realloc_groupchats(c, c->chats_index + 1)) {
+ if (!realloc_groupchats(mem, c, c->chats_index + 1)) {
return -1;
}
@@ -7378,7 +7397,7 @@ static void add_tcp_relays_to_chat(const GC_Session *c, GC_Chat *chat)
return;
}
- Node_format *tcp_relays = (Node_format *)calloc(num_relays, sizeof(Node_format));
+ Node_format *tcp_relays = (Node_format *)mem_valloc(chat->mem, num_relays, sizeof(Node_format));
if (tcp_relays == nullptr) {
return;
@@ -7390,7 +7409,7 @@ static void add_tcp_relays_to_chat(const GC_Session *c, GC_Chat *chat)
add_tcp_relay_global(chat->tcp_conn, &tcp_relays[i].ip_port, tcp_relays[i].public_key);
}
- free(tcp_relays);
+ mem_delete(chat->mem, tcp_relays);
}
non_null()
@@ -7399,7 +7418,7 @@ static bool init_gc_tcp_connection(const GC_Session *c, GC_Chat *chat)
const Messenger *m = c->messenger;
chat->tcp_conn = new_tcp_connections(chat->log, chat->mem, chat->rng, m->ns, chat->mono_time, chat->self_secret_key.enc,
- &m->options.proxy_info);
+ &m->options.proxy_info, c->tcp_np);
if (chat->tcp_conn == nullptr) {
return false;
@@ -7460,7 +7479,7 @@ non_null()
static bool create_new_chat_ext_keypair(GC_Chat *chat);
non_null()
-static int create_new_group(GC_Session *c, const uint8_t *nick, size_t nick_length, bool founder,
+static int create_new_group(const Memory *mem, GC_Session *c, const uint8_t *nick, size_t nick_length, bool founder,
const Group_Privacy_State privacy_state)
{
if (nick == nullptr || nick_length == 0) {
@@ -7471,7 +7490,7 @@ static int create_new_group(GC_Session *c, const uint8_t *nick, size_t nick_leng
return -1;
}
- const int group_number = get_new_group_index(c);
+ const int group_number = get_new_group_index(mem, c);
if (group_number == -1) {
return -1;
@@ -7610,7 +7629,7 @@ void gc_group_save(const GC_Chat *chat, Bin_Pack *bp)
int gc_group_load(GC_Session *c, Bin_Unpack *bu)
{
- const int group_number = get_new_group_index(c);
+ const int group_number = get_new_group_index(c->messenger->mem, c);
if (group_number < 0) {
return -1;
@@ -7680,7 +7699,7 @@ int gc_group_add(GC_Session *c, Group_Privacy_State privacy_state,
return -2;
}
- const int group_number = create_new_group(c, nick, nick_length, true, privacy_state);
+ const int group_number = create_new_group(c->messenger->mem, c, nick, nick_length, true, privacy_state);
if (group_number == -1) {
return -3;
@@ -7732,10 +7751,52 @@ int gc_group_add(GC_Session *c, Group_Privacy_State privacy_state,
return group_number;
}
+int gc_rejoin_group(GC_Session *c, GC_Chat *chat, const uint8_t *passwd, uint16_t passwd_len)
+{
+ if (c == nullptr) {
+ LOGGER_ERROR(chat->log, "NULL group session pointer.");
+ return -1;
+ }
+
+ if (passwd != nullptr && passwd_len > 0) {
+ if (!set_gc_password_local(chat, passwd, passwd_len)) {
+ LOGGER_WARNING(chat->log, "Failed to set new password during reconnect.");
+ }
+ }
+
+ chat->time_connected = 0;
+
+ if (group_can_handle_packets(chat)) {
+ send_gc_self_exit(chat, nullptr, 0);
+ }
+
+ for (uint32_t i = 1; i < chat->numpeers; ++i) {
+ GC_Connection *gconn = get_gc_connection(chat, i);
+ assert(gconn != nullptr);
+
+ gcc_mark_for_deletion(gconn, chat->tcp_conn, GC_EXIT_TYPE_SELF_DISCONNECTED, nullptr, 0);
+ }
+
+ if (is_public_chat(chat)) {
+ kill_group_friend_connection(c, chat);
+
+ if (!m_create_group_connection(c->messenger, chat)) {
+ LOGGER_WARNING(chat->log, "Failed to create new messenger connection for group");
+ return -1;
+ }
+
+ chat->update_self_announces = true;
+ }
+
+ chat->connection_state = CS_CONNECTING;
+
+ return 0;
+}
+
int gc_group_join(GC_Session *c, const uint8_t *chat_id, const uint8_t *nick, size_t nick_length, const uint8_t *passwd,
uint16_t passwd_len)
{
- if (chat_id == nullptr || group_exists(c, chat_id) || getfriend_id(c->messenger, chat_id) != -1) {
+ if (chat_id == nullptr) {
return -2;
}
@@ -7747,7 +7808,15 @@ int gc_group_join(GC_Session *c, const uint8_t *chat_id, const uint8_t *nick, si
return -4;
}
- const int group_number = create_new_group(c, nick, nick_length, false, GI_PUBLIC);
+ GC_Chat *existing_group = gc_get_group_by_public_key(c, chat_id);
+
+ // If we're already in the group we try to reconnect to it
+ if (existing_group != nullptr) {
+ const int ret = gc_rejoin_group(c, existing_group, passwd, passwd_len);
+ return ret != 0 ? -6 : ret;
+ }
+
+ const int group_number = create_new_group(c->messenger->mem, c, nick, nick_length, false, GI_PUBLIC);
if (group_number == -1) {
return -1;
@@ -7805,41 +7874,6 @@ bool gc_disconnect_from_group(const GC_Session *c, GC_Chat *chat)
return true;
}
-int gc_rejoin_group(GC_Session *c, GC_Chat *chat)
-{
- if (c == nullptr || chat == nullptr) {
- return -1;
- }
-
- chat->time_connected = 0;
-
- if (group_can_handle_packets(chat)) {
- send_gc_self_exit(chat, nullptr, 0);
- }
-
- for (uint32_t i = 1; i < chat->numpeers; ++i) {
- GC_Connection *gconn = get_gc_connection(chat, i);
- assert(gconn != nullptr);
-
- gcc_mark_for_deletion(gconn, chat->tcp_conn, GC_EXIT_TYPE_SELF_DISCONNECTED, nullptr, 0);
- }
-
- if (is_public_chat(chat)) {
- kill_group_friend_connection(c, chat);
-
- if (!m_create_group_connection(c->messenger, chat)) {
- LOGGER_WARNING(chat->log, "Failed to create new messenger connection for group");
- return -2;
- }
-
- chat->update_self_announces = true;
- }
-
- chat->connection_state = CS_CONNECTING;
-
- return 0;
-}
-
bool group_not_added(const GC_Session *c, const uint8_t *chat_id, uint32_t length)
{
if (length < CHAT_ID_SIZE) {
@@ -7860,7 +7894,7 @@ int gc_invite_friend(const GC_Session *c, GC_Chat *chat, int32_t friend_number,
assert(group_name_length <= MAX_GC_GROUP_NAME_SIZE);
- uint8_t *packet = (uint8_t *)malloc(2 + CHAT_ID_SIZE + ENC_PUBLIC_KEY_SIZE + group_name_length);
+ uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, 2 + CHAT_ID_SIZE + ENC_PUBLIC_KEY_SIZE + group_name_length);
if (packet == nullptr) {
return -1;
@@ -7881,11 +7915,11 @@ int gc_invite_friend(const GC_Session *c, GC_Chat *chat, int32_t friend_number,
assert(length <= MAX_GC_PACKET_SIZE);
if (!callback(c->messenger, friend_number, packet, length)) {
- free(packet);
+ mem_delete(chat->mem, packet);
return -2;
}
- free(packet);
+ mem_delete(chat->mem, packet);
chat->saved_invites[chat->saved_invites_index] = friend_number;
chat->saved_invites_index = (chat->saved_invites_index + 1) % MAX_GC_SAVED_INVITES;
@@ -7954,7 +7988,7 @@ static bool send_gc_invite_confirmed_packet(const Messenger *m, const GC_Chat *c
}
const uint16_t packet_length = 2 + length;
- uint8_t *packet = (uint8_t *)malloc(packet_length);
+ uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, packet_length);
if (packet == nullptr) {
return false;
@@ -7966,11 +8000,11 @@ static bool send_gc_invite_confirmed_packet(const Messenger *m, const GC_Chat *c
memcpy(packet + 2, data, length);
if (!send_group_invite_packet(m, friend_number, packet, packet_length)) {
- free(packet);
+ mem_delete(chat->mem, packet);
return false;
}
- free(packet);
+ mem_delete(chat->mem, packet);
return true;
}
@@ -8183,7 +8217,7 @@ int gc_accept_invite(GC_Session *c, int32_t friend_number, const uint8_t *data,
const uint8_t *chat_id = data;
const uint8_t *invite_chat_pk = data + CHAT_ID_SIZE;
- const int group_number = create_new_group(c, nick, nick_length, false, GI_PUBLIC);
+ const int group_number = create_new_group(c->messenger->mem, c, nick, nick_length, false, GI_PUBLIC);
if (group_number == -1) {
return -2;
@@ -8232,7 +8266,7 @@ GC_Session *new_dht_groupchats(Messenger *m)
return nullptr;
}
- GC_Session *c = (GC_Session *)calloc(1, sizeof(GC_Session));
+ GC_Session *c = (GC_Session *)mem_alloc(m->mem, sizeof(GC_Session));
if (c == nullptr) {
return nullptr;
@@ -8240,6 +8274,7 @@ GC_Session *new_dht_groupchats(Messenger *m)
c->messenger = m;
c->announces_list = m->group_announce;
+ c->tcp_np = m->tcp_np;
networking_registerhandler(m->net, NET_PACKET_GC_LOSSLESS, &handle_gc_udp_packet, m);
networking_registerhandler(m->net, NET_PACKET_GC_LOSSY, &handle_gc_udp_packet, m);
@@ -8263,7 +8298,7 @@ static void group_cleanup(const GC_Session *c, GC_Chat *chat)
gcc_cleanup(chat);
if (chat->group != nullptr) {
- free(chat->group);
+ mem_delete(chat->mem, chat->group);
chat->group = nullptr;
}
@@ -8298,7 +8333,7 @@ static void group_delete(GC_Session *c, GC_Chat *chat)
if (c->chats_index != i) {
c->chats_index = i;
- if (!realloc_groupchats(c, c->chats_index)) {
+ if (!realloc_groupchats(c->messenger->mem, c, c->chats_index)) {
LOGGER_ERROR(c->messenger->log, "Failed to reallocate groupchats array");
}
}
@@ -8341,8 +8376,8 @@ void kill_dht_groupchats(GC_Session *c)
networking_registerhandler(c->messenger->net, NET_PACKET_GC_HANDSHAKE, nullptr, nullptr);
onion_group_announce_register(c->messenger->onion_c, nullptr, nullptr);
- free(c->chats);
- free(c);
+ mem_delete(c->messenger->mem, c->chats);
+ mem_delete(c->messenger->mem, c);
}
bool gc_group_is_valid(const GC_Chat *chat)
@@ -8353,7 +8388,7 @@ bool gc_group_is_valid(const GC_Chat *chat)
/** Return true if `group_number` designates an active group in session `c`. */
static bool group_number_valid(const GC_Session *c, int group_number)
{
- if (group_number < 0 || group_number >= c->chats_index) {
+ if (group_number < 0 || (uint32_t)group_number >= c->chats_index) {
return false;
}
@@ -8408,19 +8443,7 @@ GC_Chat *gc_get_group_by_public_key(const GC_Session *c, const uint8_t *public_k
/** Return True if chat_id exists in the session chat array */
static bool group_exists(const GC_Session *c, const uint8_t *chat_id)
{
- for (uint32_t i = 0; i < c->chats_index; ++i) {
- const GC_Chat *chat = &c->chats[i];
-
- if (chat->connection_state == CS_NONE) {
- continue;
- }
-
- if (memcmp(get_chat_id(&chat->chat_public_key), chat_id, CHAT_ID_SIZE) == 0) {
- return true;
- }
- }
-
- return false;
+ return gc_get_group_by_public_key(c, chat_id) != nullptr;
}
/** Creates a new 32-byte session encryption keypair and puts the results in `public_key` and `secret_key`. */
diff --git a/protocols/Tox/libtox/src/toxcore/group_chats.h b/protocols/Tox/libtox/src/toxcore/group_chats.h
index 32a7323dc4..481dee19eb 100644
--- a/protocols/Tox/libtox/src/toxcore/group_chats.h
+++ b/protocols/Tox/libtox/src/toxcore/group_chats.h
@@ -22,6 +22,7 @@
#include "group_common.h"
#include "group_connection.h"
#include "logger.h"
+#include "mem.h"
#include "network.h"
#define GC_PING_TIMEOUT 12
@@ -141,9 +142,9 @@ int get_peer_number_of_enc_pk(const GC_Chat *chat, const uint8_t *public_enc_key
* Return -2 if malloc fails.
* Return -3 if encryption fails.
*/
-non_null(1, 2, 3, 4, 5) nullable(7)
+non_null(1, 2, 3, 4, 5, 6) nullable(8)
int group_packet_wrap(
- const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet,
+ const Logger *log, const Memory *mem, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet,
uint16_t packet_size, const uint8_t *data, uint16_t length, uint64_t message_id,
uint8_t gp_packet_type, Net_Packet_Type net_packet_type);
@@ -181,9 +182,9 @@ int gc_send_message(const GC_Chat *chat, const uint8_t *message, uint16_t length
* Returns -5 if the sender has the observer role.
* Returns -6 if the packet fails to send.
*/
-non_null()
+non_null(1, 4) nullable(6)
int gc_send_private_message(const GC_Chat *chat, GC_Peer_Id peer_id, uint8_t type, const uint8_t *message,
- uint16_t length);
+ uint16_t length, uint32_t *message_id);
/** @brief Sends a custom packet to the group. If lossless is true, the packet will be lossless.
*
@@ -192,8 +193,7 @@ int gc_send_private_message(const GC_Chat *chat, GC_Peer_Id peer_id, uint8_t typ
* Returns 0 on success.
* Returns -1 if the message is too long.
* Returns -2 if the message pointer is NULL or length is zero.
- * Returns -3 if the sender has the observer role.
- * Returns -4 if the packet did not successfully send to any peer.
+ * Returns -3 if the packet did not successfully send to any peer.
*/
non_null()
int gc_send_custom_packet(const GC_Chat *chat, bool lossless, const uint8_t *data, uint16_t length);
@@ -206,8 +206,7 @@ int gc_send_custom_packet(const GC_Chat *chat, bool lossless, const uint8_t *dat
* @retval -1 if the message is too long.
* @retval -2 if the message pointer is NULL or length is zero.
* @retval -3 if the supplied peer_id does not designate a valid peer.
- * @retval -4 if the sender has the observer role.
- * @retval -5 if the packet fails to send.
+ * @retval -4 if the packet fails to send.
*/
non_null()
int gc_send_custom_private_packet(const GC_Chat *chat, bool lossless, GC_Peer_Id peer_id, const uint8_t *message,
@@ -651,7 +650,7 @@ int gc_group_add(GC_Session *c, Group_Privacy_State privacy_state, const uint8_t
*
* Return group_number on success.
* Return -1 if the group object fails to initialize.
- * Return -2 if chat_id is NULL or a group with chat_id already exists in the chats array.
+ * Return -2 if chat_id is NULL.
* Return -3 if nick is too long.
* Return -4 if nick is empty or nick length is zero.
* Return -5 if there is an error setting the group password.
@@ -677,8 +676,8 @@ bool gc_disconnect_from_group(const GC_Session *c, GC_Chat *chat);
* Returns -1 if the group handler object or chat object is null.
* Returns -2 if the Messenger friend connection fails to initialize.
*/
-non_null()
-int gc_rejoin_group(GC_Session *c, GC_Chat *chat);
+non_null(1, 2) nullable(3)
+int gc_rejoin_group(GC_Session *c, GC_Chat *chat, const uint8_t *passwd, uint16_t passwd_len);
/** @brief Joins a group using the invite data received in a friend's group invite.
*
diff --git a/protocols/Tox/libtox/src/toxcore/group_common.h b/protocols/Tox/libtox/src/toxcore/group_common.h
index bb1e6f9a64..19217706a7 100644
--- a/protocols/Tox/libtox/src/toxcore/group_common.h
+++ b/protocols/Tox/libtox/src/toxcore/group_common.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2022 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
*/
/**
@@ -20,6 +20,7 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
+#include "net_profile.h"
#include "network.h"
#define MAX_GC_PART_MESSAGE_SIZE 128
@@ -52,7 +53,7 @@
#define MAX_GC_PACKET_SIZE (MAX_GC_PACKET_CHUNK_SIZE * 100)
/* Max number of messages to store in the send/recv arrays */
-#define GCC_BUFFER_SIZE 8192
+#define GCC_BUFFER_SIZE 2048
/** Self UDP status. Must correspond to return values from `ipport_self_copy()`. */
typedef enum Self_UDP_Status {
@@ -114,6 +115,7 @@ typedef struct GC_Connection {
uint64_t last_sent_tcp_relays_time; /* the last time we attempted to send this peer our tcp relays */
uint16_t tcp_relay_share_index;
uint64_t last_received_direct_time; /* the last time we received a direct UDP packet from this connection */
+ uint64_t last_sent_direct_try_time; /* the last time we tried sending a direct UDP packet */
uint64_t last_sent_ip_time; /* the last time we sent our ip info to this peer in a ping packet */
Node_format connected_tcp_relays[MAX_FRIEND_TCP_CONNECTIONS];
@@ -348,7 +350,7 @@ typedef struct Messenger Messenger;
typedef void gc_message_cb(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, unsigned int type,
const uint8_t *message, size_t length, uint32_t message_id, void *user_data);
typedef void gc_private_message_cb(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, unsigned int type,
- const uint8_t *message, size_t length, void *user_data);
+ const uint8_t *message, size_t length, uint32_t message_id, void *user_data);
typedef void gc_custom_packet_cb(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, const uint8_t *data,
size_t length, void *user_data);
typedef void gc_custom_private_packet_cb(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id,
@@ -377,6 +379,7 @@ typedef void gc_rejected_cb(const Messenger *m, uint32_t group_number, unsigned
typedef struct GC_Session {
Messenger *messenger;
GC_Chat *chats;
+ Net_Profile *tcp_np;
struct GC_Announces_List *announces_list;
uint32_t chats_index;
diff --git a/protocols/Tox/libtox/src/toxcore/group_connection.c b/protocols/Tox/libtox/src/toxcore/group_connection.c
index 1c2d1ec3da..dd6d21fd7c 100644
--- a/protocols/Tox/libtox/src/toxcore/group_connection.c
+++ b/protocols/Tox/libtox/src/toxcore/group_connection.c
@@ -11,7 +11,6 @@
#include <assert.h>
#include <stdint.h>
-#include <stdlib.h>
#include <string.h>
#include "DHT.h"
@@ -22,6 +21,7 @@
#include "group_chats.h"
#include "group_common.h"
#include "logger.h"
+#include "mem.h"
#include "mono_time.h"
#include "network.h"
#include "util.h"
@@ -29,6 +29,9 @@
/** Seconds since last direct UDP packet was received before the connection is considered dead */
#define GCC_UDP_DIRECT_TIMEOUT (GC_PING_TIMEOUT + 4)
+/** Seconds since last direct UDP packet was sent before we can try again. Cheap NAT hole punch */
+#define GCC_UDP_DIRECT_RETRY 1
+
/** Returns true if array entry does not contain an active packet. */
non_null()
static bool array_entry_is_empty(const GC_Message_Array_Entry *array_entry)
@@ -39,9 +42,9 @@ static bool array_entry_is_empty(const GC_Message_Array_Entry *array_entry)
/** @brief Clears an array entry. */
non_null()
-static void clear_array_entry(GC_Message_Array_Entry *const array_entry)
+static void clear_array_entry(const Memory *mem, GC_Message_Array_Entry *const array_entry)
{
- free(array_entry->data);
+ mem_delete(mem, array_entry->data);
*array_entry = (GC_Message_Array_Entry) {
nullptr
@@ -54,14 +57,14 @@ static void clear_array_entry(GC_Message_Array_Entry *const array_entry)
* to `start_id`.
*/
non_null()
-static void clear_send_queue_id_range(GC_Connection *gconn, uint64_t start_id, uint64_t end_id)
+static void clear_send_queue_id_range(const Memory *mem, GC_Connection *gconn, uint64_t start_id, uint64_t end_id)
{
const uint16_t start_idx = gcc_get_array_index(start_id);
const uint16_t end_idx = gcc_get_array_index(end_id);
for (uint16_t i = start_idx; i != end_idx; i = (i + 1) % GCC_BUFFER_SIZE) {
GC_Message_Array_Entry *entry = &gconn->send_array[i];
- clear_array_entry(entry);
+ clear_array_entry(mem, entry);
}
gconn->send_message_id = start_id;
@@ -90,8 +93,8 @@ void gcc_set_recv_message_id(GC_Connection *gconn, uint64_t id)
*
* Return true on success.
*/
-non_null(1, 2, 3) nullable(4)
-static bool create_array_entry(const Logger *log, const Mono_Time *mono_time, GC_Message_Array_Entry *array_entry,
+non_null(1, 2, 3, 4) nullable(5)
+static bool create_array_entry(const Logger *log, const Memory *mem, const Mono_Time *mono_time, GC_Message_Array_Entry *array_entry,
const uint8_t *data, uint16_t length, uint8_t packet_type, uint64_t message_id)
{
if (!array_entry_is_empty(array_entry)) {
@@ -109,7 +112,7 @@ static bool create_array_entry(const Logger *log, const Mono_Time *mono_time, GC
return false;
}
- uint8_t *entry_data = (uint8_t *)malloc(length);
+ uint8_t *entry_data = (uint8_t *)mem_balloc(mem, length);
if (entry_data == nullptr) {
return false;
@@ -134,9 +137,9 @@ static bool create_array_entry(const Logger *log, const Mono_Time *mono_time, GC
*
* Returns true and increments gconn's send_message_id on success.
*/
-non_null(1, 2, 3) nullable(4)
-static bool add_to_send_array(const Logger *log, const Mono_Time *mono_time, GC_Connection *gconn, const uint8_t *data,
- uint16_t length, uint8_t packet_type)
+non_null(1, 2, 3, 4) nullable(5)
+static bool add_to_send_array(const Logger *log, const Memory *mem, const Mono_Time *mono_time, GC_Connection *gconn,
+ const uint8_t *data, uint16_t length, uint8_t packet_type)
{
/* check if send_array is full */
if ((gconn->send_message_id % GCC_BUFFER_SIZE) == (uint16_t)(gconn->send_array_start - 1)) {
@@ -147,7 +150,7 @@ static bool add_to_send_array(const Logger *log, const Mono_Time *mono_time, GC_
const uint16_t idx = gcc_get_array_index(gconn->send_message_id);
GC_Message_Array_Entry *array_entry = &gconn->send_array[idx];
- if (!create_array_entry(log, mono_time, array_entry, data, length, packet_type, gconn->send_message_id)) {
+ if (!create_array_entry(log, mem, mono_time, array_entry, data, length, packet_type, gconn->send_message_id)) {
return false;
}
@@ -161,7 +164,7 @@ int gcc_send_lossless_packet(const GC_Chat *chat, GC_Connection *gconn, const ui
{
const uint64_t message_id = gconn->send_message_id;
- if (!add_to_send_array(chat->log, chat->mono_time, gconn, data, length, packet_type)) {
+ if (!add_to_send_array(chat->log, chat->mem, chat->mono_time, gconn, data, length, packet_type)) {
LOGGER_WARNING(chat->log, "Failed to add payload to send array: (type: 0x%02x, length: %d)", packet_type, length);
return -1;
}
@@ -172,7 +175,7 @@ int gcc_send_lossless_packet(const GC_Chat *chat, GC_Connection *gconn, const ui
if (gcc_encrypt_and_send_lossless_packet(chat, gconn, data, length, message_id, packet_type) == -1) {
const uint16_t idx = gcc_get_array_index(message_id);
GC_Message_Array_Entry *array_entry = &gconn->send_array[idx];
- clear_array_entry(array_entry);
+ clear_array_entry(chat->mem, array_entry);
gconn->send_message_id = message_id;
LOGGER_ERROR(chat->log, "Failed to encrypt payload: (type: 0x%02x, length: %d)", packet_type, length);
return -2;
@@ -196,7 +199,7 @@ bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gcon
chunk[0] = packet_type;
memcpy(chunk + 1, data, MAX_GC_PACKET_CHUNK_SIZE - 1);
- if (!add_to_send_array(chat->log, chat->mono_time, gconn, chunk, MAX_GC_PACKET_CHUNK_SIZE, GP_FRAGMENT)) {
+ if (!add_to_send_array(chat->log, chat->mem, chat->mono_time, gconn, chunk, MAX_GC_PACKET_CHUNK_SIZE, GP_FRAGMENT)) {
return false;
}
@@ -209,15 +212,15 @@ bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gcon
memcpy(chunk, data + processed, chunk_len);
processed += chunk_len;
- if (!add_to_send_array(chat->log, chat->mono_time, gconn, chunk, chunk_len, GP_FRAGMENT)) {
- clear_send_queue_id_range(gconn, start_id, gconn->send_message_id);
+ if (!add_to_send_array(chat->log, chat->mem, chat->mono_time, gconn, chunk, chunk_len, GP_FRAGMENT)) {
+ clear_send_queue_id_range(chat->mem, gconn, start_id, gconn->send_message_id);
return false;
}
}
// empty packet signals the end of the sequence
- if (!add_to_send_array(chat->log, chat->mono_time, gconn, nullptr, 0, GP_FRAGMENT)) {
- clear_send_queue_id_range(gconn, start_id, gconn->send_message_id);
+ if (!add_to_send_array(chat->log, chat->mem, chat->mono_time, gconn, nullptr, 0, GP_FRAGMENT)) {
+ clear_send_queue_id_range(chat->mem, gconn, start_id, gconn->send_message_id);
return false;
}
@@ -241,7 +244,7 @@ bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gcon
return true;
}
-bool gcc_handle_ack(const Logger *log, GC_Connection *gconn, uint64_t message_id)
+bool gcc_handle_ack(const Logger *log, const Memory *mem, GC_Connection *gconn, uint64_t message_id)
{
uint16_t idx = gcc_get_array_index(message_id);
GC_Message_Array_Entry *array_entry = &gconn->send_array[idx];
@@ -255,7 +258,7 @@ bool gcc_handle_ack(const Logger *log, GC_Connection *gconn, uint64_t message_id
return false;
}
- clear_array_entry(array_entry);
+ clear_array_entry(mem, array_entry);
/* Put send_array_start in proper position */
if (idx == gconn->send_array_start) {
@@ -336,15 +339,15 @@ int gcc_save_tcp_relay(const Random *rng, GC_Connection *gconn, const Node_forma
*
* Return true on success.
*/
-non_null(1, 2, 3) nullable(4)
-static bool store_in_recv_array(const Logger *log, const Mono_Time *mono_time, GC_Connection *gconn,
- const uint8_t *data,
+non_null(1, 2, 3, 4) nullable(5)
+static bool store_in_recv_array(const Logger *log, const Memory *mem, const Mono_Time *mono_time,
+ GC_Connection *gconn, const uint8_t *data,
uint16_t length, uint8_t packet_type, uint64_t message_id)
{
const uint16_t idx = gcc_get_array_index(message_id);
GC_Message_Array_Entry *ary_entry = &gconn->recv_array[idx];
- return create_array_entry(log, mono_time, ary_entry, data, length, packet_type, message_id);
+ return create_array_entry(log, mem, mono_time, ary_entry, data, length, packet_type, message_id);
}
/**
@@ -358,8 +361,8 @@ static bool store_in_recv_array(const Logger *log, const Mono_Time *mono_time, G
* Return the length of the fully reassembled packet on success.
* Return 0 on failure.
*/
-non_null(1, 3) nullable(2)
-static uint16_t reassemble_packet(const Logger *log, GC_Connection *gconn, uint8_t **payload, uint64_t message_id)
+non_null(1, 2, 4) nullable(3)
+static uint16_t reassemble_packet(const Logger *log, const Memory *mem, GC_Connection *gconn, uint8_t **payload, uint64_t message_id)
{
uint16_t end_idx = gcc_get_array_index(message_id - 1);
uint16_t start_idx = end_idx;
@@ -395,7 +398,7 @@ static uint16_t reassemble_packet(const Logger *log, GC_Connection *gconn, uint8
return 0;
}
- uint8_t *tmp_payload = (uint8_t *)malloc(packet_length);
+ uint8_t *tmp_payload = (uint8_t *)mem_balloc(mem, packet_length);
if (tmp_payload == nullptr) {
LOGGER_ERROR(log, "Failed to allocate %u bytes for payload buffer", packet_length);
@@ -414,7 +417,7 @@ static uint16_t reassemble_packet(const Logger *log, GC_Connection *gconn, uint8
memcpy(tmp_payload + processed, entry->data, entry->data_length);
processed += entry->data_length;
- clear_array_entry(entry);
+ clear_array_entry(mem, entry);
}
assert(*payload == nullptr);
@@ -428,7 +431,7 @@ int gcc_handle_packet_fragment(const GC_Session *c, GC_Chat *chat, uint32_t peer
uint64_t message_id, void *userdata)
{
if (length > 0) {
- if (!store_in_recv_array(chat->log, chat->mono_time, gconn, chunk, length, packet_type, message_id)) {
+ if (!store_in_recv_array(chat->log, chat->mem, chat->mono_time, gconn, chunk, length, packet_type, message_id)) {
return -1;
}
@@ -442,15 +445,15 @@ int gcc_handle_packet_fragment(const GC_Session *c, GC_Chat *chat, uint32_t peer
memcpy(sender_pk, get_enc_key(&gconn->addr.public_key), ENC_PUBLIC_KEY_SIZE);
uint8_t *payload = nullptr;
- const uint16_t processed_len = reassemble_packet(chat->log, gconn, &payload, message_id);
+ const uint16_t processed_len = reassemble_packet(chat->log, chat->mem, gconn, &payload, message_id);
if (processed_len == 0) {
- free(payload);
+ mem_delete(chat->mem, payload);
return -1;
}
if (!handle_gc_lossless_helper(c, chat, peer_number, payload + 1, processed_len - 1, payload[0], userdata)) {
- free(payload);
+ mem_delete(chat->mem, payload);
return -1;
}
@@ -459,19 +462,19 @@ int gcc_handle_packet_fragment(const GC_Session *c, GC_Chat *chat, uint32_t peer
gconn = get_gc_connection(chat, peer_number);
if (gconn == nullptr) {
- free(payload);
+ mem_delete(chat->mem, payload);
return 0;
}
gcc_set_recv_message_id(gconn, gconn->received_message_id + 1);
gconn->last_chunk_id = 0;
- free(payload);
+ mem_delete(chat->mem, payload);
return 0;
}
-int gcc_handle_received_message(const Logger *log, const Mono_Time *mono_time, GC_Connection *gconn,
+int gcc_handle_received_message(const Logger *log, const Memory *mem, const Mono_Time *mono_time, GC_Connection *gconn,
const uint8_t *data, uint16_t length, uint8_t packet_type, uint64_t message_id,
bool direct_conn)
{
@@ -490,7 +493,7 @@ int gcc_handle_received_message(const Logger *log, const Mono_Time *mono_time, G
/* we're missing an older message from this peer so we store it in recv_array */
if (message_id > gconn->received_message_id + 1) {
- if (!store_in_recv_array(log, mono_time, gconn, data, length, packet_type, message_id)) {
+ if (!store_in_recv_array(log, mem, mono_time, gconn, data, length, packet_type, message_id)) {
return -1;
}
@@ -522,7 +525,7 @@ static bool process_recv_array_entry(const GC_Session *c, GC_Chat *chat, GC_Conn
peer_number = get_peer_number_of_enc_pk(chat, sender_pk, false);
gconn = get_gc_connection(chat, peer_number);
- clear_array_entry(array_entry);
+ clear_array_entry(chat->mem, array_entry);
if (gconn == nullptr) {
return true;
@@ -595,7 +598,7 @@ void gcc_resend_packets(const GC_Chat *chat, GC_Connection *gconn)
}
}
-bool gcc_send_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *packet, uint16_t length)
+bool gcc_send_packet(const GC_Chat *chat, GC_Connection *gconn, const uint8_t *packet, uint16_t length)
{
if (packet == nullptr || length == 0) {
return false;
@@ -608,8 +611,12 @@ bool gcc_send_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint
return (uint16_t) sendpacket(chat->net, &gconn->addr.ip_port, packet, length) == length;
}
- if ((uint16_t) sendpacket(chat->net, &gconn->addr.ip_port, packet, length) == length) {
- direct_send_attempt = true;
+ if (gcc_conn_should_try_direct(chat->mono_time, gconn)) {
+ gconn->last_sent_direct_try_time = mono_time_get(chat->mono_time);
+
+ if ((uint16_t) sendpacket(chat->net, &gconn->addr.ip_port, packet, length) == length) {
+ direct_send_attempt = true;
+ }
}
}
@@ -617,11 +624,11 @@ bool gcc_send_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint
return ret == 0 || direct_send_attempt;
}
-int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *data,
+int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, GC_Connection *gconn, const uint8_t *data,
uint16_t length, uint64_t message_id, uint8_t packet_type)
{
const uint16_t packet_size = gc_get_wrapped_packet_size(length, NET_PACKET_GC_LOSSLESS);
- uint8_t *packet = (uint8_t *)malloc(packet_size);
+ uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, packet_size);
if (packet == nullptr) {
LOGGER_ERROR(chat->log, "Failed to allocate memory for packet buffer");
@@ -629,22 +636,22 @@ int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connectio
}
const int enc_len = group_packet_wrap(
- chat->log, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet,
+ chat->log, chat->mem, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet,
packet_size, data, length, message_id, packet_type, NET_PACKET_GC_LOSSLESS);
if (enc_len < 0) {
LOGGER_ERROR(chat->log, "Failed to wrap packet (type: 0x%02x, error: %d)", packet_type, enc_len);
- free(packet);
+ mem_delete(chat->mem, packet);
return -1;
}
if (!gcc_send_packet(chat, gconn, packet, (uint16_t)enc_len)) {
LOGGER_DEBUG(chat->log, "Failed to send packet (type: 0x%02x, enc_len: %d)", packet_type, enc_len);
- free(packet);
+ mem_delete(chat->mem, packet);
return -2;
}
- free(packet);
+ mem_delete(chat->mem, packet);
return 0;
}
@@ -659,6 +666,11 @@ bool gcc_conn_is_direct(const Mono_Time *mono_time, const GC_Connection *gconn)
return GCC_UDP_DIRECT_TIMEOUT + gconn->last_received_direct_time > mono_time_get(mono_time);
}
+bool gcc_conn_should_try_direct(const Mono_Time *mono_time, const GC_Connection *gconn)
+{
+ return mono_time_is_timeout(mono_time, gconn->last_sent_direct_try_time, GCC_UDP_DIRECT_RETRY);
+}
+
bool gcc_direct_conn_is_possible(const GC_Chat *chat, const GC_Connection *gconn)
{
return !net_family_is_unspec(gconn->addr.ip_port.ip.family) && !net_family_is_unspec(net_family(chat->net));
@@ -686,15 +698,15 @@ void gcc_mark_for_deletion(GC_Connection *gconn, TCP_Connections *tcp_conn, Grou
}
}
-void gcc_peer_cleanup(GC_Connection *gconn)
+void gcc_peer_cleanup(const Memory *mem, GC_Connection *gconn)
{
for (size_t i = 0; i < GCC_BUFFER_SIZE; ++i) {
- free(gconn->send_array[i].data);
- free(gconn->recv_array[i].data);
+ mem_delete(mem, gconn->send_array[i].data);
+ mem_delete(mem, gconn->recv_array[i].data);
}
- free(gconn->recv_array);
- free(gconn->send_array);
+ mem_delete(mem, gconn->recv_array);
+ mem_delete(mem, gconn->send_array);
crypto_memunlock(gconn->session_secret_key, sizeof(gconn->session_secret_key));
crypto_memunlock(gconn->session_shared_key, sizeof(gconn->session_shared_key));
@@ -707,6 +719,6 @@ void gcc_cleanup(const GC_Chat *chat)
GC_Connection *gconn = get_gc_connection(chat, i);
assert(gconn != nullptr);
- gcc_peer_cleanup(gconn);
+ gcc_peer_cleanup(chat->mem, gconn);
}
}
diff --git a/protocols/Tox/libtox/src/toxcore/group_connection.h b/protocols/Tox/libtox/src/toxcore/group_connection.h
index 4a9ccad0b3..7122f7a12d 100644
--- a/protocols/Tox/libtox/src/toxcore/group_connection.h
+++ b/protocols/Tox/libtox/src/toxcore/group_connection.h
@@ -16,6 +16,7 @@
#include "crypto_core.h"
#include "group_common.h"
#include "logger.h"
+#include "mem.h"
#include "mono_time.h"
#include "network.h"
@@ -35,8 +36,8 @@ void gcc_mark_for_deletion(GC_Connection *gconn, TCP_Connections *tcp_conn, Grou
* Return 0 if message is a duplicate.
* Return -1 on failure
*/
-non_null(1, 2, 3) nullable(4)
-int gcc_handle_received_message(const Logger *log, const Mono_Time *mono_time, GC_Connection *gconn,
+non_null(1, 2, 3, 4) nullable(5)
+int gcc_handle_received_message(const Logger *log, const Memory *mem, const Mono_Time *mono_time, GC_Connection *gconn,
const uint8_t *data, uint16_t length, uint8_t packet_type, uint64_t message_id,
bool direct_conn);
@@ -63,7 +64,7 @@ uint16_t gcc_get_array_index(uint64_t message_id);
* Return true on success.
*/
non_null()
-bool gcc_handle_ack(const Logger *log, GC_Connection *gconn, uint64_t message_id);
+bool gcc_handle_ack(const Logger *log, const Memory *mem, GC_Connection *gconn, uint64_t message_id);
/** @brief Sets the send_message_id and send_array_start for `gconn` to `id`.
*
@@ -134,6 +135,10 @@ void gcc_make_session_shared_key(GC_Connection *gconn, const uint8_t *sender_pk)
non_null()
bool gcc_conn_is_direct(const Mono_Time *mono_time, const GC_Connection *gconn);
+/** @brief Return true if we can try a direct connection with `gconn` again. */
+non_null()
+bool gcc_conn_should_try_direct(const Mono_Time *mono_time, const GC_Connection *gconn);
+
/** @brief Return true if a direct UDP connection is possible with `gconn`. */
non_null()
bool gcc_direct_conn_is_possible(const GC_Chat *chat, const GC_Connection *gconn);
@@ -145,7 +150,7 @@ bool gcc_direct_conn_is_possible(const GC_Chat *chat, const GC_Connection *gconn
* Return true on success.
*/
non_null()
-bool gcc_send_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *packet, uint16_t length);
+bool gcc_send_packet(const GC_Chat *chat, GC_Connection *gconn, const uint8_t *packet, uint16_t length);
/** @brief Sends a lossless packet to `gconn` comprised of `data` of size `length`.
*
@@ -183,12 +188,12 @@ bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gcon
* Return -2 if the packet fails to send.
*/
non_null(1, 2) nullable(3)
-int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *data,
+int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, GC_Connection *gconn, const uint8_t *data,
uint16_t length, uint64_t message_id, uint8_t packet_type);
/** @brief Called when a peer leaves the group. */
non_null()
-void gcc_peer_cleanup(GC_Connection *gconn);
+void gcc_peer_cleanup(const Memory *mem, GC_Connection *gconn);
/** @brief Called on group exit. */
non_null()
diff --git a/protocols/Tox/libtox/src/toxcore/group_moderation.c b/protocols/Tox/libtox/src/toxcore/group_moderation.c
index 3cb69e9403..acc17bd570 100644
--- a/protocols/Tox/libtox/src/toxcore/group_moderation.c
+++ b/protocols/Tox/libtox/src/toxcore/group_moderation.c
@@ -11,7 +11,6 @@
#include <assert.h>
-#include <stdlib.h>
#include <string.h>
#include <time.h>
@@ -20,6 +19,7 @@
#include "ccompat.h"
#include "crypto_core.h"
#include "logger.h"
+#include "mem.h"
#include "network.h"
#include "util.h"
@@ -51,7 +51,7 @@ int mod_list_unpack(Moderation *moderation, const uint8_t *data, uint16_t length
return 0;
}
- uint8_t **tmp_list = (uint8_t **)calloc(num_mods, sizeof(uint8_t *));
+ uint8_t **tmp_list = (uint8_t **)mem_valloc(moderation->mem, num_mods, sizeof(uint8_t *));
if (tmp_list == nullptr) {
return -1;
@@ -60,7 +60,7 @@ int mod_list_unpack(Moderation *moderation, const uint8_t *data, uint16_t length
uint16_t unpacked_len = 0;
for (uint16_t i = 0; i < num_mods; ++i) {
- uint8_t *entry = (uint8_t *)malloc(MOD_LIST_ENTRY_SIZE);
+ uint8_t *entry = (uint8_t *)mem_balloc(moderation->mem, MOD_LIST_ENTRY_SIZE);
if (entry == nullptr) {
free_uint8_t_pointer_array(moderation->mem, tmp_list, i);
@@ -102,7 +102,7 @@ bool mod_list_make_hash(const Moderation *moderation, uint8_t *hash)
assert(data_buf_size > 0);
- uint8_t *data = (uint8_t *)malloc(data_buf_size);
+ uint8_t *data = (uint8_t *)mem_balloc(moderation->mem, data_buf_size);
if (data == nullptr) {
return false;
@@ -112,7 +112,7 @@ bool mod_list_make_hash(const Moderation *moderation, uint8_t *hash)
mod_list_get_data_hash(hash, data, data_buf_size);
- free(data);
+ mem_delete(moderation->mem, data);
return true;
}
@@ -166,10 +166,10 @@ bool mod_list_remove_index(Moderation *moderation, uint16_t index)
MOD_LIST_ENTRY_SIZE);
}
- free(moderation->mod_list[moderation->num_mods]);
+ mem_delete(moderation->mem, moderation->mod_list[moderation->num_mods]);
moderation->mod_list[moderation->num_mods] = nullptr;
- uint8_t **tmp_list = (uint8_t **)realloc(moderation->mod_list, moderation->num_mods * sizeof(uint8_t *));
+ uint8_t **tmp_list = (uint8_t **)mem_vrealloc(moderation->mem, moderation->mod_list, moderation->num_mods, sizeof(uint8_t *));
if (tmp_list == nullptr) {
return false;
@@ -203,7 +203,7 @@ bool mod_list_add_entry(Moderation *moderation, const uint8_t *mod_data)
return false;
}
- uint8_t **tmp_list = (uint8_t **)realloc(moderation->mod_list, (moderation->num_mods + 1) * sizeof(uint8_t *));
+ uint8_t **tmp_list = (uint8_t **)mem_vrealloc(moderation->mem, moderation->mod_list, moderation->num_mods + 1, sizeof(uint8_t *));
if (tmp_list == nullptr) {
return false;
@@ -211,7 +211,7 @@ bool mod_list_add_entry(Moderation *moderation, const uint8_t *mod_data)
moderation->mod_list = tmp_list;
- uint8_t *entry = (uint8_t *)malloc(MOD_LIST_ENTRY_SIZE);
+ uint8_t *entry = (uint8_t *)mem_balloc(moderation->mem, MOD_LIST_ENTRY_SIZE);
if (entry == nullptr) {
return false;
@@ -405,8 +405,8 @@ int sanctions_list_unpack(Mod_Sanction *sanctions, Mod_Sanction_Creds *creds, ui
*
* Return true on success.
*/
-non_null(4) nullable(1)
-static bool sanctions_list_make_hash(const Mod_Sanction *sanctions, uint32_t new_version, uint16_t num_sanctions,
+non_null(1, 5) nullable(2)
+static bool sanctions_list_make_hash(const Memory *mem, const Mod_Sanction *sanctions, uint32_t new_version, uint16_t num_sanctions,
uint8_t *hash)
{
if (num_sanctions == 0 || sanctions == nullptr) {
@@ -422,7 +422,7 @@ static bool sanctions_list_make_hash(const Mod_Sanction *sanctions, uint32_t new
return false;
}
- uint8_t *data = (uint8_t *)malloc(data_buf_size);
+ uint8_t *data = (uint8_t *)mem_balloc(mem, data_buf_size);
if (data == nullptr) {
return false;
@@ -435,7 +435,7 @@ static bool sanctions_list_make_hash(const Mod_Sanction *sanctions, uint32_t new
memcpy(&data[sig_data_size], &new_version, sizeof(uint32_t));
crypto_sha256(hash, data, data_buf_size);
- free(data);
+ mem_delete(mem, data);
return true;
}
@@ -492,7 +492,7 @@ bool sanctions_list_make_creds(Moderation *moderation)
uint8_t hash[MOD_SANCTION_HASH_SIZE];
- if (!sanctions_list_make_hash(moderation->sanctions, moderation->sanctions_creds.version,
+ if (!sanctions_list_make_hash(moderation->mem, moderation->sanctions, moderation->sanctions_creds.version,
moderation->num_sanctions, hash)) {
moderation->sanctions_creds = old_creds;
return false;
@@ -533,7 +533,7 @@ static bool sanctions_creds_validate(const Moderation *moderation, const Mod_San
uint8_t hash[MOD_SANCTION_HASH_SIZE];
- if (!sanctions_list_make_hash(sanctions, creds->version, num_sanctions, hash)) {
+ if (!sanctions_list_make_hash(moderation->mem, sanctions, creds->version, num_sanctions, hash)) {
return false;
}
@@ -612,9 +612,9 @@ static bool sanctions_apply_new(Moderation *moderation, Mod_Sanction *new_sancti
* memory returned by this function.
*/
non_null()
-static Mod_Sanction *sanctions_list_copy(const Mod_Sanction *sanctions, uint16_t num_sanctions)
+static Mod_Sanction *sanctions_list_copy(const Memory *mem, const Mod_Sanction *sanctions, uint16_t num_sanctions)
{
- Mod_Sanction *copy = (Mod_Sanction *)calloc(num_sanctions, sizeof(Mod_Sanction));
+ Mod_Sanction *copy = (Mod_Sanction *)mem_valloc(mem, num_sanctions, sizeof(Mod_Sanction));
if (copy == nullptr) {
return nullptr;
@@ -655,7 +655,7 @@ static bool sanctions_list_remove_index(Moderation *moderation, uint16_t index,
}
/* Operate on a copy of the list in case something goes wrong. */
- Mod_Sanction *sanctions_copy = sanctions_list_copy(moderation->sanctions, moderation->num_sanctions);
+ Mod_Sanction *sanctions_copy = sanctions_list_copy(moderation->mem, moderation->sanctions, moderation->num_sanctions);
if (sanctions_copy == nullptr) {
return false;
@@ -665,15 +665,15 @@ static bool sanctions_list_remove_index(Moderation *moderation, uint16_t index,
sanctions_copy[index] = sanctions_copy[new_num];
}
- Mod_Sanction *new_list = (Mod_Sanction *)realloc(sanctions_copy, new_num * sizeof(Mod_Sanction));
+ Mod_Sanction *new_list = (Mod_Sanction *)mem_vrealloc(moderation->mem, sanctions_copy, new_num, sizeof(Mod_Sanction));
if (new_list == nullptr) {
- free(sanctions_copy);
+ mem_delete(moderation->mem, sanctions_copy);
return false;
}
if (!sanctions_apply_new(moderation, new_list, creds, new_num)) {
- free(new_list);
+ mem_delete(moderation->mem, new_list);
return false;
}
@@ -753,7 +753,7 @@ bool sanctions_list_add_entry(Moderation *moderation, const Mod_Sanction *sancti
Mod_Sanction *sanctions_copy = nullptr;
if (moderation->num_sanctions > 0) {
- sanctions_copy = sanctions_list_copy(moderation->sanctions, moderation->num_sanctions);
+ sanctions_copy = sanctions_list_copy(moderation->mem, moderation->sanctions, moderation->num_sanctions);
if (sanctions_copy == nullptr) {
return false;
@@ -761,17 +761,17 @@ bool sanctions_list_add_entry(Moderation *moderation, const Mod_Sanction *sancti
}
const uint16_t index = moderation->num_sanctions;
- Mod_Sanction *new_list = (Mod_Sanction *)realloc(sanctions_copy, (index + 1) * sizeof(Mod_Sanction));
+ Mod_Sanction *new_list = (Mod_Sanction *)mem_vrealloc(moderation->mem, sanctions_copy, index + 1, sizeof(Mod_Sanction));
if (new_list == nullptr) {
- free(sanctions_copy);
+ mem_delete(moderation->mem, sanctions_copy);
return false;
}
new_list[index] = *sanction;
if (!sanctions_apply_new(moderation, new_list, creds, index + 1)) {
- free(new_list);
+ mem_delete(moderation->mem, new_list);
return false;
}
@@ -864,7 +864,7 @@ uint16_t sanctions_list_replace_sig(Moderation *moderation, const uint8_t *publi
void sanctions_list_cleanup(Moderation *moderation)
{
- free(moderation->sanctions);
+ mem_delete(moderation->mem, moderation->sanctions);
moderation->sanctions = nullptr;
moderation->num_sanctions = 0;
diff --git a/protocols/Tox/libtox/src/toxcore/group_onion_announce.c b/protocols/Tox/libtox/src/toxcore/group_onion_announce.c
index d05db09a07..5a19935c50 100644
--- a/protocols/Tox/libtox/src/toxcore/group_onion_announce.c
+++ b/protocols/Tox/libtox/src/toxcore/group_onion_announce.c
@@ -14,17 +14,22 @@
#include "crypto_core.h"
#include "group_announce.h"
#include "logger.h"
+#include "mem.h"
#include "mono_time.h"
#include "network.h"
#include "onion_announce.h"
#include "timed_auth.h"
+static_assert(TIMED_AUTH_SIZE <= ONION_ANNOUNCE_REQUEST_MAX_SIZE,
+ "Timed auth does not fit into the onion packet");
+static_assert(PACKED_NODE_SIZE_IP6 <= GCA_ANNOUNCE_MAX_SIZE,
+ "IP6 does not fit into the GC_Announce");
static_assert(GCA_ANNOUNCE_MAX_SIZE <= ONION_MAX_EXTRA_DATA_SIZE,
"GC_Announce does not fit into the onion packet extra data");
static pack_extra_data_cb pack_group_announces;
non_null()
-static int pack_group_announces(void *object, const Logger *logger, const Mono_Time *mono_time,
+static int pack_group_announces(void *object, const Logger *logger, const Memory *mem, const Mono_Time *mono_time,
uint8_t num_nodes, uint8_t *plain, uint16_t plain_size,
uint8_t *response, uint16_t response_size, uint16_t offset)
{
@@ -37,7 +42,7 @@ static int pack_group_announces(void *object, const Logger *logger, const Mono_T
return -1;
}
- const GC_Peer_Announce *new_announce = gca_add_announce(mono_time, gc_announces_list, &public_announce);
+ const GC_Peer_Announce *new_announce = gca_add_announce(mem, mono_time, gc_announces_list, &public_announce);
if (new_announce == nullptr) {
LOGGER_ERROR(logger, "Failed to add group announce");
@@ -76,7 +81,7 @@ void gca_onion_init(GC_Announces_List *group_announce, Onion_Announce *onion_a)
}
int create_gca_announce_request(
- const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
+ const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id,
const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data,
const uint8_t *gc_data, uint16_t gc_data_length)
@@ -108,7 +113,7 @@ int create_gca_announce_request(
random_nonce(rng, packet + 1);
memcpy(packet + 1 + CRYPTO_NONCE_SIZE, public_key, CRYPTO_PUBLIC_KEY_SIZE);
- const int len = encrypt_data(dest_client_id, secret_key, packet + 1, plain,
+ const int len = encrypt_data(mem, dest_client_id, secret_key, packet + 1, plain,
encrypted_size, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE);
const uint32_t full_length = (uint32_t)len + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE;
diff --git a/protocols/Tox/libtox/src/toxcore/group_onion_announce.h b/protocols/Tox/libtox/src/toxcore/group_onion_announce.h
index 5fbac02e0a..8abff63795 100644
--- a/protocols/Tox/libtox/src/toxcore/group_onion_announce.h
+++ b/protocols/Tox/libtox/src/toxcore/group_onion_announce.h
@@ -9,6 +9,7 @@
#include "attributes.h"
#include "crypto_core.h"
#include "group_announce.h"
+#include "mem.h"
#include "onion_announce.h"
non_null()
@@ -16,9 +17,9 @@ void gca_onion_init(GC_Announces_List *group_announce, Onion_Announce *onion_a);
non_null()
int create_gca_announce_request(
- const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
- const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id,
- const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data,
- const uint8_t *gc_data, uint16_t gc_data_length);
+ const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length,
+ const uint8_t *dest_client_id, const uint8_t *public_key, const uint8_t *secret_key,
+ const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key,
+ uint64_t sendback_data, const uint8_t *gc_data, uint16_t gc_data_length);
#endif /* C_TOXCORE_TOXCORE_GROUP_ONION_ANNOUNCE_H */
diff --git a/protocols/Tox/libtox/src/toxcore/group_pack.c b/protocols/Tox/libtox/src/toxcore/group_pack.c
index e3af82c67a..877df7409e 100644
--- a/protocols/Tox/libtox/src/toxcore/group_pack.c
+++ b/protocols/Tox/libtox/src/toxcore/group_pack.c
@@ -10,7 +10,6 @@
#include "group_pack.h"
#include <stdint.h>
-#include <stdlib.h>
#include <string.h>
#include "DHT.h"
@@ -23,49 +22,53 @@
#include "group_common.h"
#include "group_moderation.h"
#include "logger.h"
+#include "mem.h"
#include "network.h"
#include "util.h"
-bool group_privacy_state_from_int(uint8_t value, Group_Privacy_State *out)
+static_assert(GC_SAVED_PEER_SIZE >= sizeof(IP_Port),
+ "GC_SAVED_PEER_SIZE cannot contain IP_Port");
+
+bool group_privacy_state_from_int(uint8_t value, Group_Privacy_State *out_enum)
{
switch (value) {
case GI_PUBLIC: {
- *out = GI_PUBLIC;
+ *out_enum = GI_PUBLIC;
return true;
}
case GI_PRIVATE: {
- *out = GI_PRIVATE;
+ *out_enum = GI_PRIVATE;
return true;
}
default: {
- *out = GI_PUBLIC;
+ *out_enum = GI_PUBLIC;
return false;
}
}
}
-bool group_voice_state_from_int(uint8_t value, Group_Voice_State *out)
+bool group_voice_state_from_int(uint8_t value, Group_Voice_State *out_enum)
{
switch (value) {
case GV_ALL: {
- *out = GV_ALL;
+ *out_enum = GV_ALL;
return true;
}
case GV_MODS: {
- *out = GV_MODS;
+ *out_enum = GV_MODS;
return true;
}
case GV_FOUNDER: {
- *out = GV_FOUNDER;
+ *out_enum = GV_FOUNDER;
return true;
}
default: {
- *out = GV_ALL;
+ *out_enum = GV_ALL;
return false;
}
}
@@ -180,7 +183,7 @@ static bool load_unpack_mod_list(GC_Chat *chat, Bin_Unpack *bu)
chat->moderation.num_mods = MOD_MAX_NUM_MODERATORS;
}
- uint8_t *packed_mod_list = (uint8_t *)malloc(chat->moderation.num_mods * MOD_LIST_ENTRY_SIZE);
+ uint8_t *packed_mod_list = (uint8_t *)mem_balloc(chat->mem, chat->moderation.num_mods * MOD_LIST_ENTRY_SIZE);
if (packed_mod_list == nullptr) {
LOGGER_ERROR(chat->log, "Failed to allocate memory for packed mod list");
@@ -191,17 +194,17 @@ static bool load_unpack_mod_list(GC_Chat *chat, Bin_Unpack *bu)
if (!bin_unpack_bin_fixed(bu, packed_mod_list, packed_size)) {
LOGGER_ERROR(chat->log, "Failed to unpack mod list binary data");
- free(packed_mod_list);
+ mem_delete(chat->mem, packed_mod_list);
return false;
}
if (mod_list_unpack(&chat->moderation, packed_mod_list, packed_size, chat->moderation.num_mods) == -1) {
LOGGER_ERROR(chat->log, "Failed to unpack mod list info");
- free(packed_mod_list);
+ mem_delete(chat->mem, packed_mod_list);
return false;
}
- free(packed_mod_list);
+ mem_delete(chat->mem, packed_mod_list);
return true;
}
@@ -299,7 +302,7 @@ static bool load_unpack_saved_peers(GC_Chat *chat, Bin_Unpack *bu)
return true;
}
- uint8_t *saved_peers = (uint8_t *)malloc(saved_peers_size * GC_SAVED_PEER_SIZE);
+ uint8_t *saved_peers = (uint8_t *)mem_balloc(chat->mem, saved_peers_size * GC_SAVED_PEER_SIZE);
if (saved_peers == nullptr) {
LOGGER_ERROR(chat->log, "Failed to allocate memory for saved peer list");
@@ -308,7 +311,7 @@ static bool load_unpack_saved_peers(GC_Chat *chat, Bin_Unpack *bu)
if (!bin_unpack_bin_fixed(bu, saved_peers, saved_peers_size)) {
LOGGER_ERROR(chat->log, "Failed to unpack saved peers binary data");
- free(saved_peers);
+ mem_delete(chat->mem, saved_peers);
return false;
}
@@ -316,7 +319,7 @@ static bool load_unpack_saved_peers(GC_Chat *chat, Bin_Unpack *bu)
LOGGER_ERROR(chat->log, "Failed to unpack saved peers"); // recoverable error
}
- free(saved_peers);
+ mem_delete(chat->mem, saved_peers);
return true;
}
@@ -390,7 +393,7 @@ static void save_pack_mod_list(const GC_Chat *chat, Bin_Pack *bp)
return;
}
- uint8_t *packed_mod_list = (uint8_t *)malloc(num_mods * MOD_LIST_ENTRY_SIZE);
+ uint8_t *packed_mod_list = (uint8_t *)mem_balloc(chat->mem, num_mods * MOD_LIST_ENTRY_SIZE);
// we can still recover without the mod list
if (packed_mod_list == nullptr) {
@@ -408,7 +411,7 @@ static void save_pack_mod_list(const GC_Chat *chat, Bin_Pack *bp)
bin_pack_bin(bp, packed_mod_list, packed_size); // 2
- free(packed_mod_list);
+ mem_delete(chat->mem, packed_mod_list);
}
non_null()
@@ -445,7 +448,7 @@ static void save_pack_saved_peers(const GC_Chat *chat, Bin_Pack *bp)
{
bin_pack_array(bp, 2);
- uint8_t *saved_peers = (uint8_t *)malloc(GC_MAX_SAVED_PEERS * GC_SAVED_PEER_SIZE);
+ uint8_t *saved_peers = (uint8_t *)mem_balloc(chat->mem, GC_MAX_SAVED_PEERS * GC_SAVED_PEER_SIZE);
// we can still recover without the saved peers list
if (saved_peers == nullptr) {
@@ -466,13 +469,13 @@ static void save_pack_saved_peers(const GC_Chat *chat, Bin_Pack *bp)
if (packed_size == 0) {
bin_pack_nil(bp); // 2
- free(saved_peers);
+ mem_delete(chat->mem, saved_peers);
return;
}
bin_pack_bin(bp, saved_peers, packed_size); // 2
- free(saved_peers);
+ mem_delete(chat->mem, saved_peers);
}
void gc_save_pack_group(const GC_Chat *chat, Bin_Pack *bp)
diff --git a/protocols/Tox/libtox/src/toxcore/group_pack.h b/protocols/Tox/libtox/src/toxcore/group_pack.h
index 03252fb86d..4c999132db 100644
--- a/protocols/Tox/libtox/src/toxcore/group_pack.h
+++ b/protocols/Tox/libtox/src/toxcore/group_pack.h
@@ -34,8 +34,8 @@ non_null()
bool gc_load_unpack_group(GC_Chat *chat, Bin_Unpack *bu);
non_null()
-bool group_privacy_state_from_int(uint8_t value, Group_Privacy_State *out);
+bool group_privacy_state_from_int(uint8_t value, Group_Privacy_State *out_enum);
non_null()
-bool group_voice_state_from_int(uint8_t value, Group_Voice_State *out);
+bool group_voice_state_from_int(uint8_t value, Group_Voice_State *out_enum);
#endif /* C_TOXCORE_TOXCORE_GROUP_PACK_H */
diff --git a/protocols/Tox/libtox/src/toxcore/list.c b/protocols/Tox/libtox/src/toxcore/list.c
index bf3db247f1..689ad0a614 100644
--- a/protocols/Tox/libtox/src/toxcore/list.c
+++ b/protocols/Tox/libtox/src/toxcore/list.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2014 Tox project.
*/
@@ -12,11 +12,11 @@
#include <assert.h>
#include <stdbool.h>
-#include <stdlib.h>
#include <string.h>
#include "attributes.h"
#include "ccompat.h"
+#include "mem.h"
/**
* Basically, the elements in the list are placed in order so that they can be searched for easily
@@ -115,7 +115,7 @@ static bool resize(BS_List *list, uint32_t new_size)
return true;
}
- uint8_t *data = (uint8_t *)realloc(list->data, list->element_size * new_size);
+ uint8_t *data = (uint8_t *)mem_brealloc(list->mem, list->data, new_size * list->element_size);
if (data == nullptr) {
return false;
@@ -123,7 +123,7 @@ static bool resize(BS_List *list, uint32_t new_size)
list->data = data;
- int *ids = (int *)realloc(list->ids, new_size * sizeof(int));
+ int *ids = (int *)mem_vrealloc(list->mem, list->ids, new_size, sizeof(int));
if (ids == nullptr) {
return false;
@@ -134,8 +134,10 @@ static bool resize(BS_List *list, uint32_t new_size)
return true;
}
-int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity, bs_list_cmp_cb *cmp_callback)
+int bs_list_init(BS_List *list, const Memory *mem, uint32_t element_size, uint32_t initial_capacity, bs_list_cmp_cb *cmp_callback)
{
+ list->mem = mem;
+
// set initial values
list->n = 0;
list->element_size = element_size;
@@ -162,10 +164,10 @@ void bs_list_free(BS_List *list)
}
// free both arrays
- free(list->data);
+ mem_delete(list->mem, list->data);
list->data = nullptr;
- free(list->ids);
+ mem_delete(list->mem, list->ids);
list->ids = nullptr;
}
diff --git a/protocols/Tox/libtox/src/toxcore/list.h b/protocols/Tox/libtox/src/toxcore/list.h
index 1dc66d01a4..ae0ea32746 100644
--- a/protocols/Tox/libtox/src/toxcore/list.h
+++ b/protocols/Tox/libtox/src/toxcore/list.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2014 Tox project.
*/
@@ -16,6 +16,7 @@
#include <stdint.h>
#include "attributes.h"
+#include "mem.h"
#ifdef __cplusplus
extern "C" {
@@ -24,6 +25,8 @@ extern "C" {
typedef int bs_list_cmp_cb(const void *a, const void *b, size_t size);
typedef struct BS_List {
+ const Memory *mem;
+
uint32_t n; // number of elements
uint32_t capacity; // number of elements memory is allocated for
uint32_t element_size; // size of the elements
@@ -41,7 +44,7 @@ typedef struct BS_List {
* @retval 0 failure
*/
non_null()
-int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity, bs_list_cmp_cb *cmp_callback);
+int bs_list_init(BS_List *list, const Memory *mem, uint32_t element_size, uint32_t initial_capacity, bs_list_cmp_cb *cmp_callback);
/** Free a list initiated with list_init */
nullable(1)
diff --git a/protocols/Tox/libtox/src/toxcore/logger.c b/protocols/Tox/libtox/src/toxcore/logger.c
index 67fa52330b..b97ef8e184 100644
--- a/protocols/Tox/libtox/src/toxcore/logger.c
+++ b/protocols/Tox/libtox/src/toxcore/logger.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013-2015 Tox project.
*/
@@ -8,88 +8,62 @@
*/
#include "logger.h"
+#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "attributes.h"
#include "ccompat.h"
+#include "mem.h"
struct Logger {
+ const Memory *mem;
+
logger_cb *callback;
void *context;
void *userdata;
};
-#ifndef NDEBUG
-static const char *logger_level_name(Logger_Level level)
-{
- switch (level) {
- case LOGGER_LEVEL_TRACE:
- return "TRACE";
-
- case LOGGER_LEVEL_DEBUG:
- return "DEBUG";
-
- case LOGGER_LEVEL_INFO:
- return "INFO";
-
- case LOGGER_LEVEL_WARNING:
- return "WARNING";
-
- case LOGGER_LEVEL_ERROR:
- return "ERROR";
- }
-
- return "<unknown>";
-}
-#endif /* NDEBUG */
-
-non_null(1, 3, 5, 6) nullable(7)
-static void logger_stderr_handler(void *context, Logger_Level level, const char *file, int line, const char *func,
- const char *message, void *userdata)
-{
-#ifndef NDEBUG
- // GL stands for "global logger".
- fprintf(stderr, "[GL] %s %s:%d(%s): %s\n", logger_level_name(level), file, line, func, message);
- fprintf(stderr, "Default stderr logger triggered; aborting program\n");
- abort();
-#endif /* NDEBUG */
-}
-
-static const Logger logger_stderr = {
- logger_stderr_handler,
- nullptr,
- nullptr,
-};
-
/*
* Public Functions
*/
-Logger *logger_new(void)
+Logger *logger_new(const Memory *mem)
{
- return (Logger *)calloc(1, sizeof(Logger));
+ Logger *log = (Logger *)mem_alloc(mem, sizeof(Logger));
+
+ if (log == nullptr) {
+ return nullptr;
+ }
+
+ log->mem = mem;
+
+ return log;
}
void logger_kill(Logger *log)
{
- free(log);
+ if (log == nullptr) {
+ return;
+ }
+
+ mem_delete(log->mem, log);
}
void logger_callback_log(Logger *log, logger_cb *function, void *context, void *userdata)
{
+ assert(log != nullptr);
log->callback = function;
log->context = context;
log->userdata = userdata;
}
-void logger_write(const Logger *log, Logger_Level level, const char *file, int line, const char *func,
+void logger_write(const Logger *log, Logger_Level level, const char *file, uint32_t line, const char *func,
const char *format, ...)
{
if (log == nullptr) {
- log = &logger_stderr;
+ return;
}
if (log->callback == nullptr) {
diff --git a/protocols/Tox/libtox/src/toxcore/logger.h b/protocols/Tox/libtox/src/toxcore/logger.h
index 830db883aa..893c21fd10 100644
--- a/protocols/Tox/libtox/src/toxcore/logger.h
+++ b/protocols/Tox/libtox/src/toxcore/logger.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -12,6 +12,7 @@
#include <stdint.h>
#include "attributes.h"
+#include "mem.h"
#ifdef __cplusplus
extern "C" {
@@ -32,13 +33,14 @@ typedef enum Logger_Level {
typedef struct Logger Logger;
-typedef void logger_cb(void *context, Logger_Level level, const char *file, int line,
+typedef void logger_cb(void *context, Logger_Level level, const char *file, uint32_t line,
const char *func, const char *message, void *userdata);
/**
* Creates a new logger with logging disabled (callback is NULL) by default.
*/
-Logger *logger_new(void);
+non_null()
+Logger *logger_new(const Memory *mem);
/**
* Frees all resources associated with the logger.
@@ -64,7 +66,7 @@ void logger_callback_log(Logger *log, logger_cb *function, void *context, void *
*/
non_null(3, 5, 6) nullable(1) GNU_PRINTF(6, 7)
void logger_write(
- const Logger *log, Logger_Level level, const char *file, int line, const char *func,
+ const Logger *log, Logger_Level level, const char *file, uint32_t line, const char *func,
const char *format, ...);
/* @brief Terminate the program with a signal. */
diff --git a/protocols/Tox/libtox/src/toxcore/mem.c b/protocols/Tox/libtox/src/toxcore/mem.c
index bddc335b82..32e7eec07c 100644
--- a/protocols/Tox/libtox/src/toxcore/mem.c
+++ b/protocols/Tox/libtox/src/toxcore/mem.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -53,6 +53,12 @@ void *mem_balloc(const Memory *mem, uint32_t size)
return ptr;
}
+void *mem_brealloc(const Memory *mem, void *ptr, uint32_t size)
+{
+ void *const new_ptr = mem->funcs->realloc(mem->obj, ptr, size);
+ return new_ptr;
+}
+
void *mem_alloc(const Memory *mem, uint32_t size)
{
void *const ptr = mem->funcs->calloc(mem->obj, 1, size);
diff --git a/protocols/Tox/libtox/src/toxcore/mem.h b/protocols/Tox/libtox/src/toxcore/mem.h
index 7a96b6d358..6c36027ce7 100644
--- a/protocols/Tox/libtox/src/toxcore/mem.h
+++ b/protocols/Tox/libtox/src/toxcore/mem.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -46,6 +46,14 @@ const Memory *os_memory(void);
non_null() void *mem_balloc(const Memory *mem, uint32_t size);
/**
+ * @brief Resize an array of a given size for built-in types.
+ *
+ * If used for a type other than byte-sized types, `size` needs to be manually
+ * multiplied by the element size.
+ */
+non_null(1) nullable(2) void *mem_brealloc(const Memory *mem, void *ptr, uint32_t size);
+
+/**
* @brief Allocate a single object.
*
* Always use as `(T *)mem_alloc(mem, sizeof(T))`.
diff --git a/protocols/Tox/libtox/src/toxcore/mono_time.c b/protocols/Tox/libtox/src/toxcore/mono_time.c
index 124f94fc23..8a3044c6f0 100644
--- a/protocols/Tox/libtox/src/toxcore/mono_time.c
+++ b/protocols/Tox/libtox/src/toxcore/mono_time.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2023 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2014 Tox project.
*/
#ifndef _XOPEN_SOURCE
@@ -218,7 +218,7 @@ void mono_time_set_current_time_callback(Mono_Time *mono_time,
* The starting point is unspecified and in particular is likely not comparable
* to the return value of `mono_time_get_ms()`.
*/
-uint64_t current_time_monotonic(Mono_Time *mono_time)
+uint64_t current_time_monotonic(const Mono_Time *mono_time)
{
return mono_time->current_time_callback(mono_time->user_data);
}
diff --git a/protocols/Tox/libtox/src/toxcore/mono_time.h b/protocols/Tox/libtox/src/toxcore/mono_time.h
index d0f2b7a6d3..e23c1ba0df 100644
--- a/protocols/Tox/libtox/src/toxcore/mono_time.h
+++ b/protocols/Tox/libtox/src/toxcore/mono_time.h
@@ -87,7 +87,7 @@ bool mono_time_is_timeout(const Mono_Time *mono_time, uint64_t timestamp, uint64
* to the return value of `mono_time_get_ms()`.
*/
non_null()
-uint64_t current_time_monotonic(Mono_Time *mono_time);
+uint64_t current_time_monotonic(const Mono_Time *mono_time);
/**
* Override implementation of `current_time_monotonic()` (for tests).
diff --git a/protocols/Tox/libtox/src/toxcore/net_crypto.c b/protocols/Tox/libtox/src/toxcore/net_crypto.c
index 1680b078b7..bf9f1d595a 100644
--- a/protocols/Tox/libtox/src/toxcore/net_crypto.c
+++ b/protocols/Tox/libtox/src/toxcore/net_crypto.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -10,6 +10,7 @@
*/
#include "net_crypto.h"
+#include <pthread.h>
#include <string.h>
#include "DHT.h"
@@ -23,6 +24,7 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
+#include "net_profile.h"
#include "network.h"
#include "util.h"
@@ -122,9 +124,6 @@ typedef struct Crypto_Connection {
bool maximum_speed_reached;
- /* Must be a pointer, because the struct is moved in memory */
- pthread_mutex_t *mutex;
-
dht_pk_cb *dht_pk_callback;
void *dht_pk_callback_object;
uint32_t dht_pk_callback_number;
@@ -143,10 +142,6 @@ struct Net_Crypto {
TCP_Connections *tcp_c;
Crypto_Connection *crypto_connections;
- pthread_mutex_t tcp_mutex;
-
- pthread_mutex_t connections_mutex;
- unsigned int connection_use_counter;
uint32_t crypto_connections_length; /* Length of connections array. */
@@ -237,7 +232,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin
packet[0] = NET_PACKET_COOKIE_REQUEST;
memcpy(packet + 1, dht_get_self_public_key(c->dht), CRYPTO_PUBLIC_KEY_SIZE);
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE);
- const int len = encrypt_data_symmetric(shared_key, nonce, plain, sizeof(plain),
+ const int len = encrypt_data_symmetric(c->mem, shared_key, nonce, plain, sizeof(plain),
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
if (len != COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE) {
@@ -253,7 +248,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin
* @retval 0 on success.
*/
non_null()
-static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes,
+static int create_cookie(const Memory *mem, const Random *rng, const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes,
const uint8_t *encryption_key)
{
uint8_t contents[COOKIE_CONTENTS_LENGTH];
@@ -261,7 +256,7 @@ static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t
memcpy(contents, &temp_time, sizeof(temp_time));
memcpy(contents + sizeof(temp_time), bytes, COOKIE_DATA_LENGTH);
random_nonce(rng, cookie);
- const int len = encrypt_data_symmetric(encryption_key, cookie, contents, sizeof(contents), cookie + CRYPTO_NONCE_SIZE);
+ const int len = encrypt_data_symmetric(mem, encryption_key, cookie, contents, sizeof(contents), cookie + CRYPTO_NONCE_SIZE);
if (len != COOKIE_LENGTH - CRYPTO_NONCE_SIZE) {
return -1;
@@ -276,11 +271,11 @@ static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t
* @retval 0 on success.
*/
non_null()
-static int open_cookie(const Mono_Time *mono_time, uint8_t *bytes, const uint8_t *cookie,
+static int open_cookie(const Memory *mem, const Mono_Time *mono_time, uint8_t *bytes, const uint8_t *cookie,
const uint8_t *encryption_key)
{
uint8_t contents[COOKIE_CONTENTS_LENGTH];
- const int len = decrypt_data_symmetric(encryption_key, cookie, cookie + CRYPTO_NONCE_SIZE,
+ const int len = decrypt_data_symmetric(mem, encryption_key, cookie, cookie + CRYPTO_NONCE_SIZE,
COOKIE_LENGTH - CRYPTO_NONCE_SIZE, contents);
if (len != sizeof(contents)) {
@@ -315,14 +310,14 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui
memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE);
uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)];
- if (create_cookie(c->rng, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) {
+ if (create_cookie(c->mem, c->rng, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) {
return -1;
}
memcpy(plain + COOKIE_LENGTH, request_plain + COOKIE_DATA_LENGTH, sizeof(uint64_t));
packet[0] = NET_PACKET_COOKIE_RESPONSE;
random_nonce(c->rng, packet + 1);
- const int len = encrypt_data_symmetric(shared_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE);
+ const int len = encrypt_data_symmetric(c->mem, shared_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE);
if (len != COOKIE_RESPONSE_LENGTH - (1 + CRYPTO_NONCE_SIZE)) {
return -1;
@@ -349,7 +344,7 @@ static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, ui
memcpy(dht_public_key, packet + 1, CRYPTO_PUBLIC_KEY_SIZE);
const uint8_t *tmp_shared_key = dht_get_shared_key_sent(c->dht, dht_public_key);
memcpy(shared_key, tmp_shared_key, CRYPTO_SHARED_KEY_SIZE);
- const int len = decrypt_data_symmetric(shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
+ const int len = decrypt_data_symmetric(c->mem, shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE,
request_plain);
@@ -446,7 +441,7 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_c
* @retval COOKIE_LENGTH on success.
*/
non_null()
-static int handle_cookie_response(uint8_t *cookie, uint64_t *number,
+static int handle_cookie_response(const Memory *mem, uint8_t *cookie, uint64_t *number,
const uint8_t *packet, uint16_t length,
const uint8_t *shared_key)
{
@@ -455,7 +450,7 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number,
}
uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)];
- const int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
+ const int len = decrypt_data_symmetric(mem, shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
length - (1 + CRYPTO_NONCE_SIZE), plain);
if (len != sizeof(plain)) {
@@ -488,13 +483,13 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u
memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE);
- if (create_cookie(c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE,
+ if (create_cookie(c->mem, c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE,
cookie_plain, c->secret_symmetric_key) != 0) {
return -1;
}
random_nonce(c->rng, packet + 1 + COOKIE_LENGTH);
- const int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain),
+ const int len = encrypt_data(c->mem, peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain),
packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE);
if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) {
@@ -535,7 +530,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t
uint8_t cookie_plain[COOKIE_DATA_LENGTH];
- if (open_cookie(c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) {
+ if (open_cookie(c->mem, c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) {
return false;
}
@@ -547,7 +542,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t
crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH);
uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH];
- const int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH,
+ const int len = decrypt_data(c->mem, cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH,
packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE,
HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain);
@@ -680,7 +675,7 @@ static IP_Port return_ip_port_connection(const Net_Crypto *c, int crypt_connecti
* @retval 0 on success.
*/
non_null()
-static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length)
+static int send_packet_to(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length)
{
// TODO(irungentoo): TCP, etc...
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -691,7 +686,6 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
bool direct_send_attempt = false;
- pthread_mutex_lock(conn->mutex);
const IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id);
// TODO(irungentoo): on bad networks, direct connections might not last indefinitely.
@@ -703,11 +697,9 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
if (direct_connected) {
if ((uint32_t)sendpacket(dht_get_net(c->dht), &ip_port, data, length) == length) {
- pthread_mutex_unlock(conn->mutex);
return 0;
}
- pthread_mutex_unlock(conn->mutex);
LOGGER_WARNING(c->log, "sending packet of length %d failed", length);
return -1;
}
@@ -724,19 +716,12 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
}
}
- pthread_mutex_unlock(conn->mutex);
- pthread_mutex_lock(&c->tcp_mutex);
const int ret = send_packet_tcp_connection(c->tcp_c, conn->connection_number_tcp, data, length);
- pthread_mutex_unlock(&c->tcp_mutex);
-
- pthread_mutex_lock(conn->mutex);
if (ret == 0) {
conn->last_tcp_sent = current_time_monotonic(c->mono_time);
}
- pthread_mutex_unlock(conn->mutex);
-
if (direct_send_attempt) {
return 0;
}
@@ -998,7 +983,7 @@ static int generate_request_packet(uint8_t *data, uint16_t length, const Packets
* @return number of requested packets on success.
*/
non_null()
-static int handle_request_packet(const Memory *mem, Mono_Time *mono_time, Packets_Array *send_array,
+static int handle_request_packet(const Memory *mem, const Mono_Time *mono_time, Packets_Array *send_array,
const uint8_t *data, uint16_t length,
uint64_t *latest_send_time, uint64_t rtt_time)
{
@@ -1081,7 +1066,7 @@ static int handle_request_packet(const Memory *mem, Mono_Time *mono_time, Packet
* @retval 0 on success.
*/
non_null()
-static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length)
+static int send_data_packet(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length)
{
const uint16_t max_length = MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE);
@@ -1097,21 +1082,18 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_
return -1;
}
- pthread_mutex_lock(conn->mutex);
const uint16_t packet_size = 1 + sizeof(uint16_t) + length + CRYPTO_MAC_SIZE;
VLA(uint8_t, packet, packet_size);
packet[0] = NET_PACKET_CRYPTO_DATA;
memcpy(packet + 1, conn->sent_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t));
- const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t));
+ const int len = encrypt_data_symmetric(c->mem, conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t));
if (len + 1 + sizeof(uint16_t) != packet_size) {
LOGGER_ERROR(c->log, "encryption failed: %d", len);
- pthread_mutex_unlock(conn->mutex);
return -1;
}
increment_nonce(conn->sent_nonce);
- pthread_mutex_unlock(conn->mutex);
return send_packet_to(c, crypt_connection_id, packet, packet_size);
}
@@ -1122,7 +1104,7 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_
* @retval 0 on success.
*/
non_null()
-static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint32_t buffer_start, uint32_t num,
+static int send_data_packet_helper(const Net_Crypto *c, int crypt_connection_id, uint32_t buffer_start, uint32_t num,
const uint8_t *data, uint16_t length)
{
if (length == 0 || length > MAX_CRYPTO_DATA_SIZE) {
@@ -1144,7 +1126,7 @@ static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint3
}
non_null()
-static int reset_max_speed_reached(Net_Crypto *c, int crypt_connection_id)
+static int reset_max_speed_reached(const Net_Crypto *c, int crypt_connection_id)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1179,7 +1161,7 @@ static int reset_max_speed_reached(Net_Crypto *c, int crypt_connection_id)
* @return positive packet number if data was put into the queue.
*/
non_null()
-static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length,
+static int64_t send_lossless_packet(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length,
bool congestion_control)
{
if (length == 0 || length > MAX_CRYPTO_DATA_SIZE) {
@@ -1207,9 +1189,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons
dt.sent_time = 0;
dt.length = length;
memcpy(dt.data, data, length);
- pthread_mutex_lock(conn->mutex);
const int64_t packet_num = add_data_end_of_buffer(c->log, c->mem, &conn->send_array, &dt);
- pthread_mutex_unlock(conn->mutex);
if (packet_num == -1) {
return -1;
@@ -1277,7 +1257,7 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint
net_unpack_u16(packet + 1, &num);
const uint16_t diff = num - num_cur_nonce;
increment_nonce_number(nonce, diff);
- const int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t),
+ const int len = decrypt_data_symmetric(c->mem, conn->shared_key, nonce, packet + 1 + sizeof(uint16_t),
length - (1 + sizeof(uint16_t)), data);
if ((unsigned int)len != length - crypto_packet_overhead) {
@@ -1297,7 +1277,7 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint
* @retval 0 on success.
*/
non_null()
-static int send_request_packet(Net_Crypto *c, int crypt_connection_id)
+static int send_request_packet(const Net_Crypto *c, int crypt_connection_id)
{
const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1322,7 +1302,7 @@ static int send_request_packet(Net_Crypto *c, int crypt_connection_id)
* @return number of packets sent on success.
*/
non_null()
-static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint32_t max_num)
+static int send_requested_packets(const Net_Crypto *c, int crypt_connection_id, uint32_t max_num)
{
if (max_num == 0) {
return -1;
@@ -1436,7 +1416,7 @@ static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id)
* @retval 0 on success.
*/
non_null()
-static int send_temp_packet(Net_Crypto *c, int crypt_connection_id)
+static int send_temp_packet(const Net_Crypto *c, int crypt_connection_id)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1464,7 +1444,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id)
* @retval 0 on success.
*/
non_null()
-static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie,
+static int create_send_handshake(const Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie,
const uint8_t *dht_public_key)
{
const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1494,7 +1474,7 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u
* @retval 0 on success.
*/
non_null()
-static int send_kill_packet(Net_Crypto *c, int crypt_connection_id)
+static int send_kill_packet(const Net_Crypto *c, int crypt_connection_id)
{
const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1521,18 +1501,7 @@ static void connection_kill(Net_Crypto *c, int crypt_connection_id, void *userda
false, userdata);
}
- while (true) { /* TODO(irungentoo): is this really the best way to do this? */
- pthread_mutex_lock(&c->connections_mutex);
-
- if (c->connection_use_counter == 0) {
- break;
- }
-
- pthread_mutex_unlock(&c->connections_mutex);
- }
-
crypto_kill(c, crypt_connection_id);
- pthread_mutex_unlock(&c->connections_mutex);
}
/** @brief Handle a received data packet.
@@ -1635,9 +1604,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
}
while (true) {
- pthread_mutex_lock(conn->mutex);
const int ret = read_data_beg_buffer(c->mem, &conn->recv_array, &dt);
- pthread_mutex_unlock(conn->mutex);
if (ret == -1) {
break;
@@ -1682,7 +1649,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
}
non_null()
-static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length)
+static int handle_packet_cookie_response(const Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1697,7 +1664,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id,
uint8_t cookie[COOKIE_LENGTH];
uint64_t number;
- if (handle_cookie_response(cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) {
+ if (handle_cookie_response(c->mem, cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) {
return -1;
}
@@ -1714,7 +1681,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id,
}
non_null(1, 3) nullable(5)
-static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length,
+static int handle_packet_crypto_hs(const Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length,
void *userdata)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1835,16 +1802,6 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num)
non_null()
static int create_crypto_connection(Net_Crypto *c)
{
- while (true) { /* TODO(irungentoo): is this really the best way to do this? */
- pthread_mutex_lock(&c->connections_mutex);
-
- if (c->connection_use_counter == 0) {
- break;
- }
-
- pthread_mutex_unlock(&c->connections_mutex);
- }
-
int id = -1;
for (uint32_t i = 0; i < c->crypto_connections_length; ++i) {
@@ -1863,30 +1820,17 @@ static int create_crypto_connection(Net_Crypto *c)
}
if (id != -1) {
- pthread_mutex_t *mutex = (pthread_mutex_t *)mem_alloc(c->mem, sizeof(pthread_mutex_t));
-
- if (mutex == nullptr) {
- pthread_mutex_unlock(&c->connections_mutex);
- return -1;
- }
-
- if (pthread_mutex_init(mutex, nullptr) != 0) {
- mem_delete(c->mem, mutex);
- pthread_mutex_unlock(&c->connections_mutex);
- return -1;
- }
-
// Memsetting float/double to 0 is non-portable, so we explicitly set them to 0
c->crypto_connections[id].packet_recv_rate = 0.0;
c->crypto_connections[id].packet_send_rate = 0.0;
c->crypto_connections[id].last_packets_left_rem = 0.0;
c->crypto_connections[id].packet_send_rate_requested = 0.0;
c->crypto_connections[id].last_packets_left_requested_rem = 0.0;
- c->crypto_connections[id].mutex = mutex;
+
+ // TODO(Green-Sky): This enum is likely unneeded and the same as FREE.
c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION;
}
- pthread_mutex_unlock(&c->connections_mutex);
return id;
}
@@ -1914,8 +1858,6 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id)
uint32_t i;
- pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex);
- mem_delete(c->mem, c->crypto_connections[crypt_connection_id].mutex);
crypto_memzero(&c->crypto_connections[crypt_connection_id], sizeof(Crypto_Connection));
/* check if we can resize the connections array */
@@ -2098,9 +2040,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c)
return -1;
}
- pthread_mutex_lock(&c->tcp_mutex);
const int connection_number_tcp = new_tcp_connection_to(c->tcp_c, n_c->dht_public_key, crypt_connection_id);
- pthread_mutex_unlock(&c->tcp_mutex);
if (connection_number_tcp == -1) {
wipe_crypto_connection(c, crypt_connection_id);
@@ -2117,9 +2057,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c)
conn->status = CRYPTO_CONN_NOT_CONFIRMED;
if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) {
- pthread_mutex_lock(&c->tcp_mutex);
kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
- pthread_mutex_unlock(&c->tcp_mutex);
wipe_crypto_connection(c, crypt_connection_id);
return -1;
}
@@ -2155,9 +2093,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u
Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id];
- pthread_mutex_lock(&c->tcp_mutex);
const int connection_number_tcp = new_tcp_connection_to(c->tcp_c, dht_public_key, crypt_connection_id);
- pthread_mutex_unlock(&c->tcp_mutex);
if (connection_number_tcp == -1) {
wipe_crypto_connection(c, crypt_connection_id);
@@ -2181,9 +2117,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u
if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number,
conn->shared_key) != sizeof(cookie_request)
|| new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) {
- pthread_mutex_lock(&c->tcp_mutex);
kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
- pthread_mutex_unlock(&c->tcp_mutex);
wipe_crypto_connection(c, crypt_connection_id);
return -1;
}
@@ -2241,11 +2175,7 @@ static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_
return tcp_handle_cookie_request(c, conn->connection_number_tcp, packet, length);
}
- // This unlocks the mutex that at this point is locked by do_tcp before
- // calling do_tcp_connections.
- pthread_mutex_unlock(&c->tcp_mutex);
const int ret = handle_packet_connection(c, crypt_connection_id, packet, length, false, userdata);
- pthread_mutex_lock(&c->tcp_mutex);
if (ret != 0) {
return -1;
@@ -2295,10 +2225,7 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip
return -1;
}
- pthread_mutex_lock(&c->tcp_mutex);
- const int ret = add_tcp_relay_connection(c->tcp_c, conn->connection_number_tcp, ip_port, public_key);
- pthread_mutex_unlock(&c->tcp_mutex);
- return ret;
+ return add_tcp_relay_connection(c->tcp_c, conn->connection_number_tcp, ip_port, public_key);
}
/** @brief Add a tcp relay to the array.
@@ -2308,10 +2235,7 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip
*/
int add_tcp_relay(Net_Crypto *c, const IP_Port *ip_port, const uint8_t *public_key)
{
- pthread_mutex_lock(&c->tcp_mutex);
- const int ret = add_tcp_relay_global(c->tcp_c, ip_port, public_key);
- pthread_mutex_unlock(&c->tcp_mutex);
- return ret;
+ return add_tcp_relay_global(c->tcp_c, ip_port, public_key);
}
/** @brief Return a random TCP connection number for use in send_tcp_onion_request.
@@ -2322,13 +2246,9 @@ int add_tcp_relay(Net_Crypto *c, const IP_Port *ip_port, const uint8_t *public_k
* return TCP connection number on success.
* return -1 on failure.
*/
-int get_random_tcp_con_number(Net_Crypto *c)
+int get_random_tcp_con_number(const Net_Crypto *c)
{
- pthread_mutex_lock(&c->tcp_mutex);
- const int ret = get_random_tcp_onion_conn_number(c->tcp_c);
- pthread_mutex_unlock(&c->tcp_mutex);
-
- return ret;
+ return get_random_tcp_onion_conn_number(c->tcp_c);
}
/** @brief Put IP_Port of a random onion TCP connection in ip_port.
@@ -2336,13 +2256,9 @@ int get_random_tcp_con_number(Net_Crypto *c)
* return true on success.
* return false on failure.
*/
-bool get_random_tcp_conn_ip_port(Net_Crypto *c, IP_Port *ip_port)
+bool get_random_tcp_conn_ip_port(const Net_Crypto *c, IP_Port *ip_port)
{
- pthread_mutex_lock(&c->tcp_mutex);
- const bool ret = tcp_get_random_conn_ip_port(c->tcp_c, ip_port);
- pthread_mutex_unlock(&c->tcp_mutex);
-
- return ret;
+ return tcp_get_random_conn_ip_port(c->tcp_c, ip_port);
}
/** @brief Send an onion packet via the TCP relay corresponding to tcp_connections_number.
@@ -2352,11 +2268,7 @@ bool get_random_tcp_conn_ip_port(Net_Crypto *c, IP_Port *ip_port)
*/
int send_tcp_onion_request(Net_Crypto *c, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length)
{
- pthread_mutex_lock(&c->tcp_mutex);
- const int ret = tcp_send_onion_request(c->tcp_c, tcp_connections_number, data, length);
- pthread_mutex_unlock(&c->tcp_mutex);
-
- return ret;
+ return tcp_send_onion_request(c->tcp_c, tcp_connections_number, data, length);
}
/**
@@ -2371,12 +2283,8 @@ int send_tcp_forward_request(const Logger *logger, Net_Crypto *c, const IP_Port
const uint8_t *chain_keys, uint16_t chain_length,
const uint8_t *data, uint16_t data_length)
{
- pthread_mutex_lock(&c->tcp_mutex);
- const int ret = tcp_send_forward_request(logger, c->tcp_c, tcp_forwarder, dht_node,
- chain_keys, chain_length, data, data_length);
- pthread_mutex_unlock(&c->tcp_mutex);
-
- return ret;
+ return tcp_send_forward_request(logger, c->tcp_c, tcp_forwarder, dht_node,
+ chain_keys, chain_length, data, data_length);
}
/** @brief Copy a maximum of num random TCP relays we are connected to to tcp_relays.
@@ -2386,38 +2294,28 @@ int send_tcp_forward_request(const Logger *logger, Net_Crypto *c, const IP_Port
* return number of relays copied to tcp_relays on success.
* return 0 on failure.
*/
-unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num)
+unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num)
{
if (num == 0) {
return 0;
}
- pthread_mutex_lock(&c->tcp_mutex);
- const unsigned int ret = tcp_copy_connected_relays(c->tcp_c, tcp_relays, num);
- pthread_mutex_unlock(&c->tcp_mutex);
-
- return ret;
+ return tcp_copy_connected_relays(c->tcp_c, tcp_relays, num);
}
-uint32_t copy_connected_tcp_relays_index(Net_Crypto *c, Node_format *tcp_relays, uint16_t num, uint32_t idx)
+uint32_t copy_connected_tcp_relays_index(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num, uint32_t idx)
{
if (num == 0) {
return 0;
}
- pthread_mutex_lock(&c->tcp_mutex);
- const uint32_t ret = tcp_copy_connected_relays_index(c->tcp_c, tcp_relays, num, idx);
- pthread_mutex_unlock(&c->tcp_mutex);
-
- return ret;
+ return tcp_copy_connected_relays_index(c->tcp_c, tcp_relays, num, idx);
}
non_null()
static void do_tcp(Net_Crypto *c, void *userdata)
{
- pthread_mutex_lock(&c->tcp_mutex);
do_tcp_connections(c->log, c->tcp_c, userdata);
- pthread_mutex_unlock(&c->tcp_mutex);
for (uint32_t i = 0; i < c->crypto_connections_length; ++i) {
const Crypto_Connection *conn = get_crypto_connection(c, i);
@@ -2436,9 +2334,7 @@ static void do_tcp(Net_Crypto *c, void *userdata)
continue;
}
- pthread_mutex_lock(&c->tcp_mutex);
set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, !direct_connected);
- pthread_mutex_unlock(&c->tcp_mutex);
}
}
@@ -2593,15 +2489,12 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t
return -1;
}
- pthread_mutex_lock(conn->mutex);
-
if (net_family_is_ipv4(source->ip.family)) {
conn->direct_lastrecv_timev4 = mono_time_get(c->mono_time);
} else {
conn->direct_lastrecv_timev6 = mono_time_get(c->mono_time);
}
- pthread_mutex_unlock(conn->mutex);
return 0;
}
@@ -2866,7 +2759,7 @@ static void send_crypto_packets(Net_Crypto *c)
* @retval 1 if max speed was reached for this connection (no more data can be physically through the pipe).
* @retval 0 if it wasn't reached.
*/
-bool max_speed_reached(Net_Crypto *c, int crypt_connection_id)
+bool max_speed_reached(const Net_Crypto *c, int crypt_connection_id)
{
return reset_max_speed_reached(c, crypt_connection_id) != 0;
}
@@ -2901,7 +2794,7 @@ uint32_t crypto_num_free_sendqueue_slots(const Net_Crypto *c, int crypt_connecti
*
* congestion_control: should congestion control apply to this packet?
*/
-int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length,
+int64_t write_cryptpacket(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length,
bool congestion_control)
{
if (length == 0) {
@@ -2987,7 +2880,7 @@ int cryptpacket_received(const Net_Crypto *c, int crypt_connection_id, uint32_t
*
* The first byte of data must be in the PACKET_ID_RANGE_LOSSY.
*/
-int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length)
+int send_lossy_cryptpacket(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length)
{
if (length == 0 || length > MAX_CRYPTO_DATA_SIZE) {
return -1;
@@ -2997,26 +2890,16 @@ int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t
return -1;
}
- pthread_mutex_lock(&c->connections_mutex);
- ++c->connection_use_counter;
- pthread_mutex_unlock(&c->connections_mutex);
-
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
int ret = -1;
if (conn != nullptr) {
- pthread_mutex_lock(conn->mutex);
const uint32_t buffer_start = conn->recv_array.buffer_start;
const uint32_t buffer_end = conn->send_array.buffer_end;
- pthread_mutex_unlock(conn->mutex);
ret = send_data_packet_helper(c, crypt_connection_id, buffer_start, buffer_end, data, length);
}
- pthread_mutex_lock(&c->connections_mutex);
- --c->connection_use_counter;
- pthread_mutex_unlock(&c->connections_mutex);
-
return ret;
}
@@ -3036,9 +2919,7 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
send_kill_packet(c, crypt_connection_id);
}
- pthread_mutex_lock(&c->tcp_mutex);
kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
- pthread_mutex_unlock(&c->tcp_mutex);
bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv4, crypt_connection_id);
bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv6, crypt_connection_id);
@@ -3107,7 +2988,7 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk)
* Sets all the global connection variables to their default values.
*/
Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *rng, const Network *ns,
- Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info)
+ Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info, Net_Profile *tcp_np)
{
if (dht == nullptr) {
return nullptr;
@@ -3125,7 +3006,7 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r
temp->mono_time = mono_time;
temp->ns = ns;
- temp->tcp_c = new_tcp_connections(log, mem, rng, ns, mono_time, dht_get_self_secret_key(dht), proxy_info);
+ temp->tcp_c = new_tcp_connections(log, mem, rng, ns, mono_time, dht_get_self_secret_key(dht), proxy_info, tcp_np);
if (temp->tcp_c == nullptr) {
mem_delete(mem, temp);
@@ -3135,13 +3016,6 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r
set_packet_tcp_connection_callback(temp->tcp_c, &tcp_data_callback, temp);
set_oob_packet_tcp_connection_callback(temp->tcp_c, &tcp_oob_callback, temp);
- if (create_recursive_mutex(&temp->tcp_mutex) != 0 ||
- pthread_mutex_init(&temp->connections_mutex, nullptr) != 0) {
- kill_tcp_connections(temp->tcp_c);
- mem_delete(mem, temp);
- return nullptr;
- }
-
temp->dht = dht;
new_keys(temp);
@@ -3154,7 +3028,7 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r
networking_registerhandler(dht_get_net(dht), NET_PACKET_CRYPTO_HS, &udp_handle_packet, temp);
networking_registerhandler(dht_get_net(dht), NET_PACKET_CRYPTO_DATA, &udp_handle_packet, temp);
- bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8, ipport_cmp_handler);
+ bs_list_init(&temp->ip_port_list, mem, sizeof(IP_Port), 8, ipport_cmp_handler);
return temp;
}
@@ -3215,9 +3089,6 @@ void kill_net_crypto(Net_Crypto *c)
crypto_kill(c, i);
}
- pthread_mutex_destroy(&c->tcp_mutex);
- pthread_mutex_destroy(&c->connections_mutex);
-
kill_tcp_connections(c->tcp_c);
bs_list_free(&c->ip_port_list);
networking_registerhandler(dht_get_net(c->dht), NET_PACKET_COOKIE_REQUEST, nullptr, nullptr);
diff --git a/protocols/Tox/libtox/src/toxcore/net_crypto.h b/protocols/Tox/libtox/src/toxcore/net_crypto.h
index 0d817e4315..894707005b 100644
--- a/protocols/Tox/libtox/src/toxcore/net_crypto.h
+++ b/protocols/Tox/libtox/src/toxcore/net_crypto.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -9,10 +9,7 @@
#ifndef C_TOXCORE_TOXCORE_NET_CRYPTO_H
#define C_TOXCORE_TOXCORE_NET_CRYPTO_H
-#include <pthread.h>
-
#include "DHT.h"
-#include "LAN_discovery.h"
#include "TCP_client.h"
#include "TCP_connection.h"
#include "attributes.h"
@@ -20,8 +17,13 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
+#include "net_profile.h"
#include "network.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*** Crypto payloads. */
/*** Ranges. */
@@ -40,7 +42,6 @@
/** Packets in this range are reserved for AV use. */
#define PACKET_ID_RANGE_LOSSY_START 192
#define PACKET_ID_RANGE_LOSSY_AV_START 192
-#define PACKET_ID_RANGE_LOSSY_AV_SIZE 8
#define PACKET_ID_RANGE_LOSSY_AV_END 199
/** Packets in this range can be used for anything. */
#define PACKET_ID_RANGE_LOSSY_CUSTOM_START 200
@@ -243,7 +244,7 @@ uint32_t crypto_num_free_sendqueue_slots(const Net_Crypto *c, int crypt_connecti
* @retval 0 if it wasn't reached.
*/
non_null()
-bool max_speed_reached(Net_Crypto *c, int crypt_connection_id);
+bool max_speed_reached(const Net_Crypto *c, int crypt_connection_id);
/** @brief Sends a lossless cryptopacket.
*
@@ -255,7 +256,7 @@ bool max_speed_reached(Net_Crypto *c, int crypt_connection_id);
* congestion_control: should congestion control apply to this packet?
*/
non_null()
-int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id,
+int64_t write_cryptpacket(const Net_Crypto *c, int crypt_connection_id,
const uint8_t *data, uint16_t length, bool congestion_control);
/** @brief Check if packet_number was received by the other side.
@@ -283,7 +284,7 @@ int cryptpacket_received(const Net_Crypto *c, int crypt_connection_id, uint32_t
* The first byte of data must be in the PACKET_ID_RANGE_LOSSY.
*/
non_null()
-int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length);
+int send_lossy_cryptpacket(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length);
/** @brief Add a tcp relay, associating it to a crypt_connection_id.
*
@@ -311,7 +312,7 @@ int add_tcp_relay(Net_Crypto *c, const IP_Port *ip_port, const uint8_t *public_k
* return -1 on failure.
*/
non_null()
-int get_random_tcp_con_number(Net_Crypto *c);
+int get_random_tcp_con_number(const Net_Crypto *c);
/** @brief Put IP_Port of a random onion TCP connection in ip_port.
*
@@ -319,7 +320,7 @@ int get_random_tcp_con_number(Net_Crypto *c);
* return false on failure.
*/
non_null()
-bool get_random_tcp_conn_ip_port(Net_Crypto *c, IP_Port *ip_port);
+bool get_random_tcp_conn_ip_port(const Net_Crypto *c, IP_Port *ip_port);
/** @brief Send an onion packet via the TCP relay corresponding to tcp_connections_number.
*
@@ -351,7 +352,7 @@ int send_tcp_forward_request(const Logger *logger, Net_Crypto *c, const IP_Port
* return 0 on failure.
*/
non_null()
-unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num);
+unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num);
/**
* Copy a maximum of `max_num` TCP relays we are connected to starting at the index in the TCP relay array
@@ -360,7 +361,7 @@ unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, u
* Returns the number of relays successfully copied.
*/
non_null()
-uint32_t copy_connected_tcp_relays_index(Net_Crypto *c, Node_format *tcp_relays, uint16_t num, uint32_t idx);
+uint32_t copy_connected_tcp_relays_index(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num, uint32_t idx);
/** @brief Kill a crypto connection.
*
@@ -405,7 +406,7 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk);
*/
non_null()
Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *rng, const Network *ns,
- Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info);
+ Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info, Net_Profile *tcp_np);
/** return the optimal interval in ms for running do_net_crypto. */
non_null()
@@ -418,4 +419,8 @@ void do_net_crypto(Net_Crypto *c, void *userdata);
nullable(1)
void kill_net_crypto(Net_Crypto *c);
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
#endif /* C_TOXCORE_TOXCORE_NET_CRYPTO_H */
diff --git a/protocols/Tox/libtox/src/toxcore/net_profile.c b/protocols/Tox/libtox/src/toxcore/net_profile.c
new file mode 100644
index 0000000000..1d700bdb85
--- /dev/null
+++ b/protocols/Tox/libtox/src/toxcore/net_profile.c
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright © 2023-2025 The TokTok team.
+ */
+
+/**
+ * Functions for the network profile.
+ */
+
+#include "net_profile.h"
+
+#include <stdint.h>
+
+#include "attributes.h"
+#include "logger.h"
+#include "mem.h"
+
+#include "ccompat.h"
+
+#define NETPROF_TCP_DATA_PACKET_ID 0x10
+
+typedef struct Net_Profile {
+ uint64_t packets_recv[NET_PROF_MAX_PACKET_IDS];
+ uint64_t packets_sent[NET_PROF_MAX_PACKET_IDS];
+
+ uint64_t total_packets_recv;
+ uint64_t total_packets_sent;
+
+ uint64_t bytes_recv[NET_PROF_MAX_PACKET_IDS];
+ uint64_t bytes_sent[NET_PROF_MAX_PACKET_IDS];
+
+ uint64_t total_bytes_recv;
+ uint64_t total_bytes_sent;
+} Net_Profile;
+
+/** Returns the number of sent or received packets for all ID's between `start_id` and `end_id`. */
+nullable(1)
+static uint64_t netprof_get_packet_count_id_range(const Net_Profile *profile, uint8_t start_id, uint8_t end_id,
+ Packet_Direction dir)
+{
+ if (profile == nullptr) {
+ return 0;
+ }
+
+ const uint64_t *arr = dir == PACKET_DIRECTION_SEND ? profile->packets_sent : profile->packets_recv;
+ uint64_t count = 0;
+
+ for (size_t i = start_id; i <= end_id; ++i) {
+ count += arr[i];
+ }
+
+ return count;
+}
+
+/** Returns the number of sent or received bytes for all ID's between `start_id` and `end_id`. */
+nullable(1)
+static uint64_t netprof_get_bytes_id_range(const Net_Profile *profile, uint8_t start_id, uint8_t end_id,
+ Packet_Direction dir)
+{
+ if (profile == nullptr) {
+ return 0;
+ }
+
+ const uint64_t *arr = dir == PACKET_DIRECTION_SEND ? profile->bytes_sent : profile->bytes_recv;
+ uint64_t bytes = 0;
+
+ for (size_t i = start_id; i <= end_id; ++i) {
+ bytes += arr[i];
+ }
+
+ return bytes;
+}
+
+void netprof_record_packet(Net_Profile *profile, uint8_t id, size_t length, Packet_Direction dir)
+{
+ if (profile == nullptr) {
+ return;
+ }
+
+ if (dir == PACKET_DIRECTION_SEND) {
+ ++profile->total_packets_sent;
+ ++profile->packets_sent[id];
+
+ profile->total_bytes_sent += length;
+ profile->bytes_sent[id] += length;
+ } else {
+ ++profile->total_packets_recv;
+ ++profile->packets_recv[id];
+
+ profile->total_bytes_recv += length;
+ profile->bytes_recv[id] += length;
+ }
+}
+
+uint64_t netprof_get_packet_count_id(const Net_Profile *profile, uint8_t id, Packet_Direction dir)
+{
+ if (profile == nullptr) {
+ return 0;
+ }
+
+ // Special case - TCP data packets can have any ID between 0x10 and 0xff
+ if (id == NETPROF_TCP_DATA_PACKET_ID) {
+ return netprof_get_packet_count_id_range(profile, id, UINT8_MAX, dir);
+ }
+
+ return dir == PACKET_DIRECTION_SEND ? profile->packets_sent[id] : profile->packets_recv[id];
+}
+
+uint64_t netprof_get_packet_count_total(const Net_Profile *profile, Packet_Direction dir)
+{
+ if (profile == nullptr) {
+ return 0;
+ }
+
+ return dir == PACKET_DIRECTION_SEND ? profile->total_packets_sent : profile->total_packets_recv;
+}
+
+uint64_t netprof_get_bytes_id(const Net_Profile *profile, uint8_t id, Packet_Direction dir)
+{
+ if (profile == nullptr) {
+ return 0;
+ }
+
+ // Special case - TCP data packets can have any ID between 0x10 and 0xff
+ if (id == NETPROF_TCP_DATA_PACKET_ID) {
+ return netprof_get_bytes_id_range(profile, id, 0xff, dir);
+ }
+
+ return dir == PACKET_DIRECTION_SEND ? profile->bytes_sent[id] : profile->bytes_recv[id];
+}
+
+uint64_t netprof_get_bytes_total(const Net_Profile *profile, Packet_Direction dir)
+{
+ if (profile == nullptr) {
+ return 0;
+ }
+
+ return dir == PACKET_DIRECTION_SEND ? profile->total_bytes_sent : profile->total_bytes_recv;
+}
+
+Net_Profile *netprof_new(const Logger *log, const Memory *mem)
+{
+ Net_Profile *np = (Net_Profile *)mem_alloc(mem, sizeof(Net_Profile));
+
+ if (np == nullptr) {
+ LOGGER_ERROR(log, "failed to allocate memory for net profiler");
+ return nullptr;
+ }
+
+ return np;
+}
+
+void netprof_kill(const Memory *mem, Net_Profile *net_profile)
+{
+ if (net_profile != nullptr) {
+ mem_delete(mem, net_profile);
+ }
+}
diff --git a/protocols/Tox/libtox/src/toxcore/net_profile.h b/protocols/Tox/libtox/src/toxcore/net_profile.h
new file mode 100644
index 0000000000..be16f671de
--- /dev/null
+++ b/protocols/Tox/libtox/src/toxcore/net_profile.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright © 2023-2025 The TokTok team.
+ */
+
+/**
+ * Functions for the network profile.
+ */
+#ifndef C_TOXCORE_TOXCORE_NET_PROFILE_H
+#define C_TOXCORE_TOXCORE_NET_PROFILE_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "attributes.h"
+#include "logger.h"
+#include "mem.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The max number of packet ID's (must fit inside one byte) */
+#define NET_PROF_MAX_PACKET_IDS 256
+
+/* If passed to a netprof function as a nullptr the function will have no effect. */
+typedef struct Net_Profile Net_Profile;
+
+/** Specifies whether the query is for sent or received packets. */
+typedef enum Packet_Direction {
+ PACKET_DIRECTION_SEND,
+ PACKET_DIRECTION_RECV,
+} Packet_Direction;
+
+/**
+ * Records a sent or received packet of type `id` and size `length` to the given profile.
+ */
+nullable(1)
+void netprof_record_packet(Net_Profile *profile, uint8_t id, size_t length, Packet_Direction dir);
+
+/**
+ * Returns the number of sent or received packets of type `id` for the given profile.
+ */
+nullable(1)
+uint64_t netprof_get_packet_count_id(const Net_Profile *profile, uint8_t id, Packet_Direction dir);
+
+/**
+ * Returns the total number of sent or received packets for the given profile.
+ */
+nullable(1)
+uint64_t netprof_get_packet_count_total(const Net_Profile *profile, Packet_Direction dir);
+
+/**
+ * Returns the number of bytes sent or received of packet type `id` for the given profile.
+ */
+nullable(1)
+uint64_t netprof_get_bytes_id(const Net_Profile *profile, uint8_t id, Packet_Direction dir);
+
+/**
+ * Returns the total number of bytes sent or received for the given profile.
+ */
+nullable(1)
+uint64_t netprof_get_bytes_total(const Net_Profile *profile, Packet_Direction dir);
+
+/**
+ * Returns a new net_profile object. The caller is responsible for freeing the
+ * returned memory via `netprof_kill`.
+ */
+non_null()
+Net_Profile *netprof_new(const Logger *log, const Memory *mem);
+
+/**
+ * Kills a net_profile object and frees all associated memory.
+ */
+non_null(1) nullable(2)
+void netprof_kill(const Memory *mem, Net_Profile *net_profile);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* C_TOXCORE_TOXCORE_NET_PROFILE_H */
diff --git a/protocols/Tox/libtox/src/toxcore/network.c b/protocols/Tox/libtox/src/toxcore/network.c
index 55aa4e2818..bd6babf26e 100644
--- a/protocols/Tox/libtox/src/toxcore/network.c
+++ b/protocols/Tox/libtox/src/toxcore/network.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2023 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -86,6 +86,7 @@
#include "ccompat.h"
#include "logger.h"
#include "mem.h"
+#include "net_profile.h"
#include "util.h"
// Disable MSG_NOSIGNAL on systems not supporting it, e.g. Windows, FreeBSD
@@ -263,9 +264,11 @@ static int make_family(Family tox_family)
{
switch (tox_family.value) {
case TOX_AF_INET:
+ case TCP_INET:
return AF_INET;
case TOX_AF_INET6:
+ case TCP_INET6:
return AF_INET6;
case TOX_AF_UNSPEC:
@@ -514,6 +517,12 @@ static int sys_listen(void *obj, Socket sock, int backlog)
}
non_null()
+static int sys_connect(void *obj, Socket sock, const Network_Addr *addr)
+{
+ return connect(net_socket_to_native(sock), (const struct sockaddr *)&addr->addr, addr->size);
+}
+
+non_null()
static int sys_recvbuf(void *obj, Socket sock)
{
#ifdef OS_WIN32
@@ -583,7 +592,97 @@ static int sys_getsockopt(void *obj, Socket sock, int level, int optname, void *
non_null()
static int sys_setsockopt(void *obj, Socket sock, int level, int optname, const void *optval, size_t optlen)
{
+#ifdef EMSCRIPTEN
+ return 0;
+#else
return setsockopt(net_socket_to_native(sock), level, optname, (const char *)optval, optlen);
+#endif /* EMSCRIPTEN */
+}
+
+// sets and fills an array of addrs for address
+// returns the number of entries in addrs
+non_null()
+static int sys_getaddrinfo(void *obj, const Memory *mem, const char *address, int family, int sock_type, Network_Addr **addrs)
+{
+ assert(addrs != nullptr);
+
+ struct addrinfo hints = {0};
+ hints.ai_family = family;
+
+
+ // different platforms favour a different field
+ // hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses.
+ hints.ai_socktype = sock_type;
+ // hints.ai_protocol = protocol;
+
+ struct addrinfo *infos = nullptr;
+
+ const int rc = getaddrinfo(address, nullptr, &hints, &infos);
+
+ // Lookup failed.
+ if (rc != 0) {
+ // TODO(Green-Sky): log error
+ return 0;
+ }
+
+ const int32_t max_count = INT32_MAX / sizeof(Network_Addr);
+
+ // we count number of "valid" results
+ int result = 0;
+ for (struct addrinfo *walker = infos; walker != nullptr && result < max_count; walker = walker->ai_next) {
+ if (walker->ai_family == family || family == AF_UNSPEC) {
+ ++result;
+ }
+
+ // do we need to check socktype/protocol?
+ }
+
+ assert(max_count >= result);
+
+ Network_Addr *tmp_addrs = (Network_Addr *)mem_valloc(mem, result, sizeof(Network_Addr));
+ if (tmp_addrs == nullptr) {
+ freeaddrinfo(infos);
+ return 0;
+ }
+
+ // now we fill in
+ int i = 0;
+ for (struct addrinfo *walker = infos; walker != nullptr; walker = walker->ai_next) {
+ if (walker->ai_family == family || family == AF_UNSPEC) {
+ tmp_addrs[i].size = sizeof(struct sockaddr_storage);
+ tmp_addrs[i].addr.ss_family = walker->ai_family;
+
+ // according to spec, storage is supposed to be large enough (and source shows they are)
+ // storage is 128 bytes
+ assert(walker->ai_addrlen <= tmp_addrs[i].size);
+
+ memcpy(&tmp_addrs[i].addr, walker->ai_addr, walker->ai_addrlen);
+ tmp_addrs[i].size = walker->ai_addrlen;
+
+ ++i;
+ }
+ }
+
+ assert(i == result);
+
+ freeaddrinfo(infos);
+
+ *addrs = tmp_addrs;
+
+ // number of entries in addrs
+ return result;
+}
+
+non_null()
+static int sys_freeaddrinfo(void *obj, const Memory *mem, Network_Addr *addrs)
+{
+ if (addrs == nullptr) {
+ return 0;
+ }
+
+ mem_delete(mem, addrs);
+
+ return 0;
}
static const Network_Funcs os_network_funcs = {
@@ -591,6 +690,7 @@ static const Network_Funcs os_network_funcs = {
sys_accept,
sys_bind,
sys_listen,
+ sys_connect,
sys_recvbuf,
sys_recv,
sys_recvfrom,
@@ -600,8 +700,10 @@ static const Network_Funcs os_network_funcs = {
sys_socket_nonblock,
sys_getsockopt,
sys_setsockopt,
+ sys_getaddrinfo,
+ sys_freeaddrinfo,
};
-static const Network os_network_obj = {&os_network_funcs};
+static const Network os_network_obj = {&os_network_funcs, nullptr};
const Network *os_network(void)
{
@@ -674,11 +776,11 @@ static const char *net_packet_type_name(Net_Packet_Type type)
case NET_PACKET_PING_RESPONSE:
return "PING_RESPONSE";
- case NET_PACKET_GET_NODES:
- return "GET_NODES";
+ case NET_PACKET_NODES_REQUEST:
+ return "NODES_REQUEST";
- case NET_PACKET_SEND_NODES_IPV6:
- return "SEND_NODES_IPV6";
+ case NET_PACKET_NODES_RESPONSE:
+ return "NODES_RESPONSE";
case NET_PACKET_COOKIE_REQUEST:
return "COOKIE_REQUEST";
@@ -787,13 +889,12 @@ static void loglogdata(const Logger *log, const char *message, const uint8_t *bu
if (res < 0) { /* Windows doesn't necessarily know `%zu` */
Ip_Ntoa ip_str;
const int error = net_error();
- char *strerror = net_new_strerror(error);
+ Net_Strerror error_str;
LOGGER_TRACE(log, "[%02x = %-21s] %s %3u%c %s:%u (%u: %s) | %08x%08x...%02x",
buffer[0], net_packet_type_name((Net_Packet_Type)buffer[0]), message,
min_u16(buflen, 999), 'E',
net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), error,
- strerror, data_0(buflen, buffer), data_1(buflen, buffer), buffer[buflen - 1]);
- net_kill_strerror(strerror);
+ net_strerror(error, &error_str), data_0(buflen, buffer), data_1(buflen, buffer), buffer[buflen - 1]);
} else if ((res > 0) && ((size_t)res <= buflen)) {
Ip_Ntoa ip_str;
LOGGER_TRACE(log, "[%02x = %-21s] %s %3u%c %s:%u (%u: %s) | %08x%08x...%02x",
@@ -812,9 +913,14 @@ static void loglogdata(const Logger *log, const char *message, const uint8_t *bu
}
int net_send(const Network *ns, const Logger *log,
- Socket sock, const uint8_t *buf, size_t len, const IP_Port *ip_port)
+ Socket sock, const uint8_t *buf, size_t len, const IP_Port *ip_port, Net_Profile *net_profile)
{
const int res = ns->funcs->send(ns->obj, sock, buf, len);
+
+ if (res > 0) {
+ netprof_record_packet(net_profile, buf[0], res, PACKET_DIRECTION_SEND);
+ }
+
loglogdata(log, "T=>", buf, len, ip_port, res);
return res;
}
@@ -882,7 +988,11 @@ bool set_socket_nosigpipe(const Network *ns, Socket sock)
bool set_socket_reuseaddr(const Network *ns, Socket sock)
{
int set = 1;
+#if defined(OS_WIN32)
+ return net_setsockopt(ns, sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, &set, sizeof(set)) == 0;
+#else
return net_setsockopt(ns, sock, SOL_SOCKET, SO_REUSEADDR, &set, sizeof(set)) == 0;
+#endif /* OS_WIN32 */
}
bool set_socket_dualstack(const Network *ns, Socket sock)
@@ -914,6 +1024,8 @@ struct Networking_Core {
uint16_t port;
/* Our UDP socket. */
Socket sock;
+
+ Net_Profile *udp_net_profile;
};
Family net_family(const Networking_Core *net)
@@ -941,7 +1053,7 @@ int send_packet(const Networking_Core *net, const IP_Port *ip_port, Packet packe
if (net_family_is_unspec(net->family)) { /* Socket not initialized */
// TODO(iphydf): Make this an error. Currently, the onion client calls
- // this via DHT getnodes.
+ // this via DHT nodes requests.
LOGGER_WARNING(net->log, "attempted to send message of length %u on uninitialised socket", packet.length);
return -1;
}
@@ -999,6 +1111,11 @@ int send_packet(const Networking_Core *net, const IP_Port *ip_port, Packet packe
loglogdata(net->log, "O=>", packet.data, packet.length, ip_port, res);
assert(res <= INT_MAX);
+
+ if (res == packet.length && packet.data != nullptr) {
+ netprof_record_packet(net->udp_net_profile, packet.data[0], packet.length, PACKET_DIRECTION_SEND);
+ }
+
return (int)res;
}
@@ -1019,7 +1136,7 @@ int sendpacket(const Networking_Core *net, const IP_Port *ip_port, const uint8_t
* Packet length is put into length.
*/
non_null()
-static int receivepacket(const Network *ns, const Memory *mem, const Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length)
+static int receivepacket(const Network *ns, const Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length)
{
memset(ip_port, 0, sizeof(IP_Port));
Network_Addr addr = {{0}};
@@ -1032,9 +1149,8 @@ static int receivepacket(const Network *ns, const Memory *mem, const Logger *log
const int error = net_error();
if (!should_ignore_recv_error(error)) {
- char *strerror = net_new_strerror(error);
- LOGGER_ERROR(log, "unexpected error reading from socket: %u, %s", error, strerror);
- net_kill_strerror(strerror);
+ Net_Strerror error_str;
+ LOGGER_ERROR(log, "unexpected error reading from socket: %u, %s", error, net_strerror(error, &error_str));
}
return -1; /* Nothing received. */
@@ -1098,11 +1214,13 @@ void networking_poll(const Networking_Core *net, void *userdata)
uint8_t data[MAX_UDP_PACKET_SIZE] = {0};
uint32_t length;
- while (receivepacket(net->ns, net->mem, net->log, net->sock, &ip_port, data, &length) != -1) {
+ while (receivepacket(net->ns, net->log, net->sock, &ip_port, data, &length) != -1) {
if (length < 1) {
continue;
}
+ netprof_record_packet(net->udp_net_profile, data[0], length, PACKET_DIRECTION_RECV);
+
const Packet_Handler *const handler = &net->packethandlers[data[0]];
if (handler->function == nullptr) {
@@ -1163,6 +1281,14 @@ Networking_Core *new_networking_ex(
return nullptr;
}
+ Net_Profile *np = netprof_new(log, mem);
+
+ if (np == nullptr) {
+ free(temp);
+ return nullptr;
+ }
+
+ temp->udp_net_profile = np;
temp->ns = ns;
temp->log = log;
temp->mem = mem;
@@ -1176,9 +1302,9 @@ Networking_Core *new_networking_ex(
/* Check for socket error. */
if (!sock_valid(temp->sock)) {
const int neterror = net_error();
- char *strerror = net_new_strerror(neterror);
- LOGGER_ERROR(log, "failed to get a socket?! %d, %s", neterror, strerror);
- net_kill_strerror(strerror);
+ Net_Strerror error_str;
+ LOGGER_ERROR(log, "failed to get a socket?! %d, %s", neterror, net_strerror(neterror, &error_str));
+ netprof_kill(mem, temp->udp_net_profile);
mem_delete(mem, temp);
if (error != nullptr) {
@@ -1279,15 +1405,13 @@ Networking_Core *new_networking_ex(
const int res = net_setsockopt(ns, temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
const int neterror = net_error();
- char *strerror = net_new_strerror(neterror);
+ Net_Strerror error_str;
if (res < 0) {
- LOGGER_INFO(log, "Failed to activate local multicast membership in FF02::1. (%d, %s)", neterror, strerror);
+ LOGGER_INFO(log, "Failed to activate local multicast membership in FF02::1. (%d, %s)", neterror, net_strerror(neterror, &error_str));
} else {
- LOGGER_TRACE(log, "Local multicast group joined successfully. (%d, %s)", neterror, strerror);
+ LOGGER_TRACE(log, "Local multicast group joined successfully. (%d, %s)", neterror, net_strerror(neterror, &error_str));
}
-
- net_kill_strerror(strerror);
#endif /* ESP_PLATFORM */
}
@@ -1345,10 +1469,9 @@ Networking_Core *new_networking_ex(
Ip_Ntoa ip_str;
const int neterror = net_error();
- char *strerror = net_new_strerror(neterror);
+ Net_Strerror error_str;
LOGGER_ERROR(log, "failed to bind socket: %d, %s IP: %s port_from: %u port_to: %u",
- neterror, strerror, net_ip_ntoa(ip, &ip_str), port_from, port_to);
- net_kill_strerror(strerror);
+ neterror, net_strerror(neterror, &error_str), net_ip_ntoa(ip, &ip_str), port_from, port_to);
kill_networking(temp);
if (error != nullptr) {
@@ -1386,6 +1509,7 @@ void kill_networking(Networking_Core *net)
kill_sock(net->ns, net->sock);
}
+ netprof_kill(net->mem, net->udp_net_profile);
mem_delete(net->mem, net);
}
@@ -1754,14 +1878,14 @@ bool ip_parse_addr(const IP *ip, char *address, size_t length)
return false;
}
- if (net_family_is_ipv4(ip->family)) {
+ if (net_family_is_ipv4(ip->family) || net_family_is_tcp_ipv4(ip->family)) {
struct in_addr addr;
assert(make_family(ip->family) == AF_INET);
fill_addr4(&ip->ip.v4, &addr);
return inet_ntop4(&addr, address, length) != nullptr;
}
- if (net_family_is_ipv6(ip->family)) {
+ if (net_family_is_ipv6(ip->family) || net_family_is_tcp_ipv6(ip->family)) {
struct in6_addr addr;
assert(make_family(ip->family) == AF_INET6);
fill_addr6(&ip->ip.v6, &addr);
@@ -1815,37 +1939,34 @@ bool addr_parse_ip(const char *address, IP *to)
* prefers v6 if `ip.family` was TOX_AF_UNSPEC and both available
* Returns in `*extra` an IPv4 address, if family was TOX_AF_UNSPEC and `*to` is TOX_AF_INET6
*
- * @return 0 on failure, `TOX_ADDR_RESOLVE_*` on success.
+ * @return false on failure, true on success.
*/
-non_null(1, 2, 3) nullable(4)
-static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extra)
+non_null(1, 2, 3, 4) nullable(5)
+static bool addr_resolve(const Network *ns, const Memory *mem, const char *address, IP *to, IP *extra)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if ((true)) {
- return 0;
+ return false;
}
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
if (address == nullptr || to == nullptr) {
- return 0;
+ return false;
}
const Family tox_family = to->family;
const int family = make_family(tox_family);
- struct addrinfo hints = {0};
- hints.ai_family = family;
- hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses.
-
- struct addrinfo *server = nullptr;
+ Network_Addr *addrs = nullptr;
+ const int rc = ns->funcs->getaddrinfo(ns->obj, mem, address, family, 0, &addrs);
- const int rc = getaddrinfo(address, nullptr, &hints, &server);
-
- // Lookup failed.
- if (rc != 0) {
- return 0;
+ // Lookup failed / empty.
+ if (rc <= 0) {
+ return false;
}
+ assert(addrs != nullptr);
+
IP ip4;
ip_init(&ip4, false); // ipv6enabled = false
IP ip6;
@@ -1854,16 +1975,16 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr
int result = 0;
bool done = false;
- for (struct addrinfo *walker = server; walker != nullptr && !done; walker = walker->ai_next) {
- switch (walker->ai_family) {
+ for (int i = 0; i < rc && !done; ++i) {
+ switch (addrs[i].addr.ss_family) {
case AF_INET: {
- if (walker->ai_family == family) { /* AF_INET requested, done */
- const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)walker->ai_addr;
+ if (addrs[i].addr.ss_family == family) { /* AF_INET requested, done */
+ const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)&addrs[i].addr;
get_ip4(&to->ip.v4, &addr->sin_addr);
result = TOX_ADDR_RESOLVE_INET;
done = true;
} else if ((result & TOX_ADDR_RESOLVE_INET) == 0) { /* AF_UNSPEC requested, store away */
- const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)walker->ai_addr;
+ const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)&addrs[i].addr;
get_ip4(&ip4.ip.v4, &addr->sin_addr);
result |= TOX_ADDR_RESOLVE_INET;
}
@@ -1872,16 +1993,16 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr
}
case AF_INET6: {
- if (walker->ai_family == family) { /* AF_INET6 requested, done */
- if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
- const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(void *)walker->ai_addr;
+ if (addrs[i].addr.ss_family == family) { /* AF_INET6 requested, done */
+ if (addrs[i].size == sizeof(struct sockaddr_in6)) {
+ const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(void *)&addrs[i].addr;
get_ip6(&to->ip.v6, &addr->sin6_addr);
result = TOX_ADDR_RESOLVE_INET6;
done = true;
}
} else if ((result & TOX_ADDR_RESOLVE_INET6) == 0) { /* AF_UNSPEC requested, store away */
- if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
- const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(void *)walker->ai_addr;
+ if (addrs[i].size == sizeof(struct sockaddr_in6)) {
+ const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(void *)&addrs[i].addr;
get_ip6(&ip6.ip.v6, &addr->sin6_addr);
result |= TOX_ADDR_RESOLVE_INET6;
}
@@ -1906,37 +2027,48 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr
}
}
- freeaddrinfo(server);
- return result;
+ ns->funcs->freeaddrinfo(ns->obj, mem, addrs);
+ return result != 0;
}
-bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP *extra)
+bool addr_resolve_or_parse_ip(const Network *ns, const Memory *mem, const char *address, IP *to, IP *extra, bool dns_enabled)
{
- if (addr_resolve(ns, address, to, extra) == 0) {
- if (!addr_parse_ip(address, to)) {
- return false;
- }
+ if (dns_enabled && addr_resolve(ns, mem, address, to, extra)) {
+ return true;
}
- return true;
+ return addr_parse_ip(address, to);
+}
+
+const char *net_err_connect_to_string(Net_Err_Connect err)
+{
+ switch (err) {
+ case NET_ERR_CONNECT_OK:
+ return "NET_ERR_CONNECT_OK";
+ case NET_ERR_CONNECT_INVALID_FAMILY:
+ return "NET_ERR_CONNECT_INVALID_FAMILY";
+ case NET_ERR_CONNECT_FAILED:
+ return "NET_ERR_CONNECT_FAILED";
+ }
+
+ return "<invalid Net_Err_Connect>";
}
-bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port)
+bool net_connect(const Network *ns, const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port, Net_Err_Connect *err)
{
- struct sockaddr_storage addr = {0};
- size_t addrsize;
+ Network_Addr addr = {{0}};
if (net_family_is_ipv4(ip_port->ip.family)) {
- struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr;
+ struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr.addr;
- addrsize = sizeof(struct sockaddr_in);
+ addr.size = sizeof(struct sockaddr_in);
addr4->sin_family = AF_INET;
fill_addr4(&ip_port->ip.ip.v4, &addr4->sin_addr);
addr4->sin_port = ip_port->port;
} else if (net_family_is_ipv6(ip_port->ip.family)) {
- struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
+ struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr.addr;
- addrsize = sizeof(struct sockaddr_in6);
+ addr.size = sizeof(struct sockaddr_in6);
addr6->sin6_family = AF_INET6;
fill_addr6(&ip_port->ip.ip.v6, &addr6->sin6_addr);
addr6->sin6_port = ip_port->port;
@@ -1944,11 +2076,13 @@ bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Por
Ip_Ntoa ip_str;
LOGGER_ERROR(log, "cannot connect to %s:%d which is neither IPv4 nor IPv6",
net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port));
+ *err = NET_ERR_CONNECT_INVALID_FAMILY;
return false;
}
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if ((true)) {
+ *err = NET_ERR_CONNECT_OK;
return true;
}
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
@@ -1958,23 +2092,24 @@ bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Por
net_socket_to_native(sock), net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port));
errno = 0;
- if (connect(net_socket_to_native(sock), (struct sockaddr *)&addr, addrsize) == -1) {
+ if (ns->funcs->connect(ns->obj, sock, &addr) == -1) {
const int error = net_error();
// Non-blocking socket: "Operation in progress" means it's connecting.
if (!should_ignore_connect_error(error)) {
- char *net_strerror = net_new_strerror(error);
+ Net_Strerror error_str;
LOGGER_WARNING(log, "failed to connect to %s:%d: %d (%s)",
- net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), error, net_strerror);
- net_kill_strerror(net_strerror);
+ net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), error, net_strerror(error, &error_str));
+ *err = NET_ERR_CONNECT_FAILED;
return false;
}
}
+ *err = NET_ERR_CONNECT_OK;
return true;
}
-int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type)
+int32_t net_getipport(const Network *ns, const Memory *mem, const char *node, IP_Port **res, int tox_type, bool dns_enabled)
{
assert(node != nullptr);
@@ -1996,6 +2131,10 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to
return 1;
}
+ if (!dns_enabled) {
+ return -1;
+ }
+
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if ((true)) {
IP_Port *ip_port = (IP_Port *)mem_alloc(mem, sizeof(IP_Port));
@@ -2010,25 +2149,29 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to
}
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
+ int type = make_socktype(tox_type);
+ // ugly
+ if (tox_type == -1) {
+ type = 0;
+ }
+
// It's not an IP address, so now we try doing a DNS lookup.
- struct addrinfo *infos;
- const int ret = getaddrinfo(node, nullptr, nullptr, &infos);
+ Network_Addr *addrs = nullptr;
+ const int rc = ns->funcs->getaddrinfo(ns->obj, mem, node, AF_UNSPEC, type, &addrs);
- if (ret != 0) {
+ // Lookup failed / empty.
+ if (rc <= 0) {
return -1;
}
+ assert(addrs != nullptr);
+
// Used to avoid calloc parameter overflow
const size_t max_count = min_u64(SIZE_MAX, INT32_MAX) / sizeof(IP_Port);
- const int type = make_socktype(tox_type);
size_t count = 0;
- for (struct addrinfo *cur = infos; count < max_count && cur != nullptr; cur = cur->ai_next) {
- if (cur->ai_socktype != 0 && type > 0 && cur->ai_socktype != type) {
- continue;
- }
-
- if (cur->ai_family != AF_INET && cur->ai_family != AF_INET6) {
+ for (int i = 0; i < rc && count < max_count; ++i) {
+ if (addrs[i].addr.ss_family != AF_INET && addrs[i].addr.ss_family != AF_INET6) {
continue;
}
@@ -2038,40 +2181,36 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to
assert(count <= max_count);
if (count == 0) {
- freeaddrinfo(infos);
+ ns->funcs->freeaddrinfo(ns->obj, mem, addrs);
return 0;
}
IP_Port *ip_port = (IP_Port *)mem_valloc(mem, count, sizeof(IP_Port));
if (ip_port == nullptr) {
- freeaddrinfo(infos);
+ ns->funcs->freeaddrinfo(ns->obj, mem, addrs);
*res = nullptr;
return -1;
}
*res = ip_port;
- for (struct addrinfo *cur = infos; cur != nullptr; cur = cur->ai_next) {
- if (cur->ai_socktype != 0 && type > 0 && cur->ai_socktype != type) {
- continue;
- }
-
- if (cur->ai_family == AF_INET) {
- const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)cur->ai_addr;
+ for (int i = 0; i < rc && count < max_count; ++i) {
+ if (addrs[i].addr.ss_family == AF_INET) {
+ const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)&addrs[i].addr;
ip_port->ip.ip.v4.uint32 = addr->sin_addr.s_addr;
- } else if (cur->ai_family == AF_INET6) {
- const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(const void *)cur->ai_addr;
+ } else if (addrs[i].addr.ss_family == AF_INET6) {
+ const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(const void *)&addrs[i].addr;
memcpy(ip_port->ip.ip.v6.uint8, addr->sin6_addr.s6_addr, sizeof(IP6));
} else {
continue;
}
- const Family *const family = make_tox_family(cur->ai_family);
+ const Family *const family = make_tox_family(addrs[i].addr.ss_family);
assert(family != nullptr);
if (family == nullptr) {
- freeaddrinfo(infos);
+ ns->funcs->freeaddrinfo(ns->obj, mem, addrs);
return -1;
}
@@ -2080,7 +2219,7 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to
++ip_port;
}
- freeaddrinfo(infos);
+ ns->funcs->freeaddrinfo(ns->obj, mem, addrs);
return count;
}
@@ -2227,19 +2366,11 @@ int net_error(void)
}
#ifdef OS_WIN32
-char *net_new_strerror(int error)
-{
- char *str = nullptr;
- // Windows API is weird. The 5th function arg is of char* type, but we
- // have to pass char** so that it could assign new memory block to our
- // pointer, so we have to cast our char** to char* for the compilation
- // not to fail (otherwise it would fail to find a variant of this function
- // accepting char** as the 5th arg) and Windows inside casts it back
- // to char** to do the assignment. So no, this cast you see here, although
- // it looks weird, is not a mistake.
- FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
- error, 0, (char *)&str, 0, nullptr);
- return str;
+char *net_strerror(int error, Net_Strerror *buf)
+{
+ FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
+ error, 0, buf->data, NET_STRERROR_SIZE, nullptr);
+ return buf->data;
}
#else
#if defined(_GNU_SOURCE) && defined(__GLIBC__)
@@ -2267,32 +2398,24 @@ static const char *net_strerror_r(int error, char *tmp, size_t tmp_size)
return tmp;
}
#endif /* GNU */
-char *net_new_strerror(int error)
+char *net_strerror(int error, Net_Strerror *buf)
{
- char tmp[256];
-
errno = 0;
- const char *retstr = net_strerror_r(error, tmp, sizeof(tmp));
+ const char *retstr = net_strerror_r(error, buf->data, NET_STRERROR_SIZE);
const size_t retstr_len = strlen(retstr);
+ assert(retstr_len < NET_STRERROR_SIZE);
+ buf->size = (uint16_t)retstr_len;
- char *str = (char *)malloc(retstr_len + 1);
-
- if (str == nullptr) {
- return nullptr;
- }
-
- memcpy(str, retstr, retstr_len + 1);
-
- return str;
+ return buf->data;
}
#endif /* OS_WIN32 */
-void net_kill_strerror(char *strerror)
+const Net_Profile *net_get_net_profile(const Networking_Core *net)
{
-#ifdef OS_WIN32
- LocalFree((char *)strerror);
-#else
- free(strerror);
-#endif /* OS_WIN32 */
+ if (net == nullptr) {
+ return nullptr;
+ }
+
+ return net->udp_net_profile;
}
diff --git a/protocols/Tox/libtox/src/toxcore/network.h b/protocols/Tox/libtox/src/toxcore/network.h
index 06857b8917..a13c98bf6f 100644
--- a/protocols/Tox/libtox/src/toxcore/network.h
+++ b/protocols/Tox/libtox/src/toxcore/network.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -17,6 +17,7 @@
#include "bin_pack.h"
#include "logger.h"
#include "mem.h"
+#include "net_profile.h"
#ifdef __cplusplus
extern "C" {
@@ -39,6 +40,7 @@ typedef int net_close_cb(void *obj, Socket sock);
typedef Socket net_accept_cb(void *obj, Socket sock);
typedef int net_bind_cb(void *obj, Socket sock, const Network_Addr *addr);
typedef int net_listen_cb(void *obj, Socket sock, int backlog);
+typedef int net_connect_cb(void *obj, Socket sock, const Network_Addr *addr);
typedef int net_recvbuf_cb(void *obj, Socket sock);
typedef int net_recv_cb(void *obj, Socket sock, uint8_t *buf, size_t len);
typedef int net_recvfrom_cb(void *obj, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr);
@@ -48,8 +50,8 @@ typedef Socket net_socket_cb(void *obj, int domain, int type, int proto);
typedef int net_socket_nonblock_cb(void *obj, Socket sock, bool nonblock);
typedef int net_getsockopt_cb(void *obj, Socket sock, int level, int optname, void *optval, size_t *optlen);
typedef int net_setsockopt_cb(void *obj, Socket sock, int level, int optname, const void *optval, size_t optlen);
-typedef int net_getaddrinfo_cb(void *obj, int family, Network_Addr **addrs);
-typedef int net_freeaddrinfo_cb(void *obj, Network_Addr *addrs);
+typedef int net_getaddrinfo_cb(void *obj, const Memory *mem, const char *address, int family, int protocol, Network_Addr **addrs);
+typedef int net_freeaddrinfo_cb(void *obj, const Memory *mem, Network_Addr *addrs);
/** @brief Functions wrapping POSIX network functions.
*
@@ -61,6 +63,7 @@ typedef struct Network_Funcs {
net_accept_cb *accept;
net_bind_cb *bind;
net_listen_cb *listen;
+ net_connect_cb *connect;
net_recvbuf_cb *recvbuf;
net_recv_cb *recv;
net_recvfrom_cb *recvfrom;
@@ -110,8 +113,8 @@ Family net_family_tox_tcp_ipv6(void);
typedef enum Net_Packet_Type {
NET_PACKET_PING_REQUEST = 0x00, /* Ping request packet ID. */
NET_PACKET_PING_RESPONSE = 0x01, /* Ping response packet ID. */
- NET_PACKET_GET_NODES = 0x02, /* Get nodes request packet ID. */
- NET_PACKET_SEND_NODES_IPV6 = 0x04, /* Send nodes response packet ID for other addresses. */
+ NET_PACKET_NODES_REQUEST = 0x02, /* Nodes request packet ID. */
+ NET_PACKET_NODES_RESPONSE = 0x04, /* Nodes response packet ID. */
NET_PACKET_COOKIE_REQUEST = 0x18, /* Cookie request packet */
NET_PACKET_COOKIE_RESPONSE = 0x19, /* Cookie response packet */
NET_PACKET_CRYPTO_HS = 0x1a, /* Crypto handshake packet */
@@ -233,11 +236,27 @@ Socket net_invalid_socket(void);
/**
* Calls send(sockfd, buf, len, MSG_NOSIGNAL).
- */
-non_null()
-int net_send(const Network *ns, const Logger *log, Socket sock, const uint8_t *buf, size_t len, const IP_Port *ip_port);
+ *
+ * @param ns System network object.
+ * @param log Logger object.
+ * @param sock Socket to send data with.
+ * @param buf Data to send.
+ * @param len Length of data.
+ * @param ip_port IP and port to send data to.
+ * @param net_profile Network profile to record the packet.
+ */
+non_null(1, 2, 4, 6) nullable(7)
+int net_send(const Network *ns, const Logger *log, Socket sock, const uint8_t *buf, size_t len, const IP_Port *ip_port,
+ Net_Profile *net_profile);
/**
* Calls recv(sockfd, buf, len, MSG_NOSIGNAL).
+ *
+ * @param ns System network object.
+ * @param log Logger object.
+ * @param sock Socket to receive data with.
+ * @param buf Buffer to store received data.
+ * @param len Length of buffer.
+ * @param ip_port IP and port of the sender.
*/
non_null()
int net_recv(const Network *ns, const Logger *log, Socket sock, uint8_t *buf, size_t len, const IP_Port *ip_port);
@@ -396,21 +415,23 @@ non_null()
void ipport_copy(IP_Port *target, const IP_Port *source);
/**
- * Resolves string into an IP address
+ * @brief Resolves string into an IP address.
*
- * @param address a hostname (or something parseable to an IP address)
- * @param to to.family MUST be initialized, either set to a specific IP version
+ * @param[in,out] ns Network object.
+ * @param[in] address a hostname (or something parseable to an IP address).
+ * @param[in,out] to to.family MUST be initialized, either set to a specific IP version
* (TOX_AF_INET/TOX_AF_INET6) or to the unspecified TOX_AF_UNSPEC (0), if both
- * IP versions are acceptable
- * @param extra can be NULL and is only set in special circumstances, see returns
+ * IP versions are acceptable.
+ * @param[out] extra can be NULL and is only set in special circumstances, see returns.
+ * @param[in] dns_enabled if false, DNS resolution is skipped.
*
- * Returns in `*to` a matching address (IPv6 or IPv4)
- * Returns in `*extra`, if not NULL, an IPv4 address, if `to->family` was TOX_AF_UNSPEC
+ * Returns in `*to` a matching address (IPv6 or IPv4).
+ * Returns in `*extra`, if not NULL, an IPv4 address, if `to->family` was `TOX_AF_UNSPEC`.
*
* @return true on success, false on failure
*/
-non_null(1, 2, 3) nullable(4)
-bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP *extra);
+non_null(1, 2, 3, 4) nullable(5)
+bool addr_resolve_or_parse_ip(const Network *ns, const Memory *mem, const char *address, IP *to, IP *extra, bool dns_enabled);
/** @brief Function to receive data, ip and port of sender is put into ip_port.
* Packet data is put into data.
@@ -495,13 +516,22 @@ void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handl
non_null(1) nullable(2)
void networking_poll(const Networking_Core *net, void *userdata);
+typedef enum Net_Err_Connect {
+ NET_ERR_CONNECT_OK,
+ NET_ERR_CONNECT_INVALID_FAMILY,
+ NET_ERR_CONNECT_FAILED,
+} Net_Err_Connect;
+
+const char *net_err_connect_to_string(Net_Err_Connect err);
+
/** @brief Connect a socket to the address specified by the ip_port.
*
- * Return true on success.
- * Return false on failure.
+ * @param[out] err Set to NET_ERR_CONNECT_OK on success, otherwise an error code.
+ *
+ * @retval true on success, false on failure.
*/
non_null()
-bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port);
+bool net_connect(const Network *ns, const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port, Net_Err_Connect *err);
/** @brief High-level getaddrinfo implementation.
*
@@ -510,14 +540,21 @@ bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Por
* address that can be specified by calling `net_connect()`, the port is ignored.
*
* Skip all addresses with socktype != type (use type = -1 to get all addresses)
- * To correctly deallocate array memory use `net_freeipport()`
+ * To correctly deallocate array memory use `net_freeipport()`.
+ *
+ * @param ns Network object.
+ * @param mem Memory allocator.
+ * @param node The node parameter identifies the host or service on which to connect.
+ * @param[out] res An array of IP_Port structures will be allocated into this pointer.
+ * @param tox_type The type of socket to use (stream or datagram), only relevant for DNS lookups.
+ * @param dns_enabled If false, DNS resolution is skipped, when passed a hostname, this function will return an error.
*
* @return number of elements in res array.
* @retval 0 if res array empty.
* @retval -1 on error.
*/
non_null()
-int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type);
+int32_t net_getipport(const Network *ns, const Memory *mem, const char *node, IP_Port **res, int tox_type, bool dns_enabled);
/** Deallocates memory allocated by net_getipport */
non_null(1) nullable(2)
@@ -560,26 +597,32 @@ bool bind_to_port(const Network *ns, Socket sock, Family family, uint16_t port);
* Note that different platforms may return different codes for the same error,
* so you likely shouldn't be checking the value returned by this function
* unless you know what you are doing, you likely just want to use it in
- * combination with `net_new_strerror()` to print the error.
+ * combination with `net_strerror()` to print the error.
*
* return platform-dependent network error code, if any.
*/
int net_error(void);
-/** @brief Get a text explanation for the error code from `net_error()`.
+#define NET_STRERROR_SIZE 256
+
+/** @brief Contains a null terminated formatted error message.
*
- * return NULL on failure.
- * return pointer to a NULL-terminated string describing the error code on
- * success. The returned string must be freed using `net_kill_strerror()`.
+ * This struct should not contain more than at most the 2 fields.
*/
-char *net_new_strerror(int error);
+typedef struct Net_Strerror {
+ char data[NET_STRERROR_SIZE];
+ uint16_t size;
+} Net_Strerror;
-/** @brief Frees the string returned by `net_new_strerror()`.
- * It's valid to pass NULL as the argument, the function does nothing in this
- * case.
+/** @brief Get a text explanation for the error code from `net_error()`.
+ *
+ * @param error The error code to get a string for.
+ * @param buf The struct to store the error message in (usually on stack).
+ *
+ * @return pointer to a NULL-terminated string describing the error code.
*/
-nullable(1)
-void net_kill_strerror(char *strerror);
+non_null()
+char *net_strerror(int error, Net_Strerror *buf);
/** @brief Initialize networking.
* Bind to ip and port.
@@ -603,6 +646,13 @@ Networking_Core *new_networking_no_udp(const Logger *log, const Memory *mem, con
nullable(1)
void kill_networking(Networking_Core *net);
+/** @brief Returns a pointer to the network net_profile object associated with `net`.
+ *
+ * Returns null if `net` is null.
+ */
+non_null()
+const Net_Profile *net_get_net_profile(const Networking_Core *net);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/protocols/Tox/libtox/src/toxcore/onion.c b/protocols/Tox/libtox/src/toxcore/onion.c
index 9fab57af90..f948be52cb 100644
--- a/protocols/Tox/libtox/src/toxcore/onion.c
+++ b/protocols/Tox/libtox/src/toxcore/onion.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -180,7 +180,7 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_
* return -1 on failure.
* return length of created packet on success.
*/
-int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
+int create_onion_packet(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length,
const Onion_Path *path, const IP_Port *dest,
const uint8_t *data, uint16_t length)
{
@@ -202,7 +202,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_
ipport_pack(step2, &path->ip_port3);
memcpy(step2 + SIZE_IPPORT, path->public_key3, CRYPTO_PUBLIC_KEY_SIZE);
- int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, step1_size,
+ int len = encrypt_data_symmetric(mem, path->shared_key3, nonce, step1, step1_size,
step2 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE);
if (len != SIZE_IPPORT + length + CRYPTO_MAC_SIZE) {
@@ -213,7 +213,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_
VLA(uint8_t, step3, step3_size);
ipport_pack(step3, &path->ip_port2);
memcpy(step3 + SIZE_IPPORT, path->public_key2, CRYPTO_PUBLIC_KEY_SIZE);
- len = encrypt_data_symmetric(path->shared_key2, nonce, step2, step2_size,
+ len = encrypt_data_symmetric(mem, path->shared_key2, nonce, step2, step2_size,
step3 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE);
if (len != SIZE_IPPORT + SEND_BASE + length + CRYPTO_MAC_SIZE) {
@@ -224,7 +224,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_
memcpy(packet + 1, nonce, CRYPTO_NONCE_SIZE);
memcpy(packet + 1 + CRYPTO_NONCE_SIZE, path->public_key1, CRYPTO_PUBLIC_KEY_SIZE);
- len = encrypt_data_symmetric(path->shared_key1, nonce, step3, step3_size,
+ len = encrypt_data_symmetric(mem, path->shared_key1, nonce, step3, step3_size,
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE);
if (len != SIZE_IPPORT + SEND_BASE * 2 + length + CRYPTO_MAC_SIZE) {
@@ -243,7 +243,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_
* return -1 on failure.
* return length of created packet on success.
*/
-int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
+int create_onion_packet_tcp(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length,
const Onion_Path *path, const IP_Port *dest,
const uint8_t *data, uint16_t length)
{
@@ -265,7 +265,7 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac
ipport_pack(step2, &path->ip_port3);
memcpy(step2 + SIZE_IPPORT, path->public_key3, CRYPTO_PUBLIC_KEY_SIZE);
- int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, step1_size,
+ int len = encrypt_data_symmetric(mem, path->shared_key3, nonce, step1, step1_size,
step2 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE);
if (len != SIZE_IPPORT + length + CRYPTO_MAC_SIZE) {
@@ -274,7 +274,7 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac
ipport_pack(packet + CRYPTO_NONCE_SIZE, &path->ip_port2);
memcpy(packet + CRYPTO_NONCE_SIZE + SIZE_IPPORT, path->public_key2, CRYPTO_PUBLIC_KEY_SIZE);
- len = encrypt_data_symmetric(path->shared_key2, nonce, step2, step2_size,
+ len = encrypt_data_symmetric(mem, path->shared_key2, nonce, step2, step2_size,
packet + CRYPTO_NONCE_SIZE + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE);
if (len != SIZE_IPPORT + SEND_BASE + length + CRYPTO_MAC_SIZE) {
@@ -355,7 +355,7 @@ static int handle_send_initial(void *object, const IP_Port *source, const uint8_
}
const int len = decrypt_data_symmetric(
- shared_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_length, plain);
+ onion->mem, shared_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_length, plain);
if (len != plaintext_length) {
LOGGER_TRACE(onion->log, "decrypt failed: %d != %d", len, plaintext_length);
@@ -393,7 +393,7 @@ int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, const I
uint16_t data_len = 1 + CRYPTO_NONCE_SIZE + (len - SIZE_IPPORT);
uint8_t *ret_part = data + data_len;
random_nonce(onion->rng, ret_part);
- len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ip_port, SIZE_IPPORT,
+ len = encrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, ret_part, ip_port, SIZE_IPPORT,
ret_part + CRYPTO_NONCE_SIZE);
if (len != SIZE_IPPORT + CRYPTO_MAC_SIZE) {
@@ -436,7 +436,7 @@ static int handle_send_1(void *object, const IP_Port *source, const uint8_t *pac
return 1;
}
- int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
+ int len = decrypt_data_symmetric(onion->mem, shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_1), plain);
if (len != length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_1 + CRYPTO_MAC_SIZE)) {
@@ -459,7 +459,7 @@ static int handle_send_1(void *object, const IP_Port *source, const uint8_t *pac
uint8_t ret_data[RETURN_1 + SIZE_IPPORT];
ipport_pack(ret_data, source);
memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_1), RETURN_1);
- len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
+ len = encrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
ret_part + CRYPTO_NONCE_SIZE);
if (len != RETURN_2 - CRYPTO_NONCE_SIZE) {
@@ -502,7 +502,7 @@ static int handle_send_2(void *object, const IP_Port *source, const uint8_t *pac
return 1;
}
- int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
+ int len = decrypt_data_symmetric(onion->mem, shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_2), plain);
if (len != length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_2 + CRYPTO_MAC_SIZE)) {
@@ -532,7 +532,7 @@ static int handle_send_2(void *object, const IP_Port *source, const uint8_t *pac
uint8_t ret_data[RETURN_2 + SIZE_IPPORT];
ipport_pack(ret_data, source);
memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_2), RETURN_2);
- len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
+ len = encrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
ret_part + CRYPTO_NONCE_SIZE);
if (len != RETURN_3 - CRYPTO_NONCE_SIZE) {
@@ -574,7 +574,7 @@ static int handle_recv_3(void *object, const IP_Port *source, const uint8_t *pac
change_symmetric_key(onion);
uint8_t plain[SIZE_IPPORT + RETURN_2];
- const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
+ const int len = decrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
SIZE_IPPORT + RETURN_2 + CRYPTO_MAC_SIZE, plain);
if ((uint32_t)len != sizeof(plain)) {
@@ -627,7 +627,7 @@ static int handle_recv_2(void *object, const IP_Port *source, const uint8_t *pac
change_symmetric_key(onion);
uint8_t plain[SIZE_IPPORT + RETURN_1];
- const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
+ const int len = decrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
SIZE_IPPORT + RETURN_1 + CRYPTO_MAC_SIZE, plain);
if ((uint32_t)len != sizeof(plain)) {
@@ -679,7 +679,7 @@ static int handle_recv_1(void *object, const IP_Port *source, const uint8_t *pac
change_symmetric_key(onion);
uint8_t plain[SIZE_IPPORT];
- const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
+ const int len = decrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
SIZE_IPPORT + CRYPTO_MAC_SIZE, plain);
if ((uint32_t)len != SIZE_IPPORT) {
diff --git a/protocols/Tox/libtox/src/toxcore/onion.h b/protocols/Tox/libtox/src/toxcore/onion.h
index a5d3554e7b..bbc3f22435 100644
--- a/protocols/Tox/libtox/src/toxcore/onion.h
+++ b/protocols/Tox/libtox/src/toxcore/onion.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -105,7 +105,7 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_
* return length of created packet on success.
*/
non_null()
-int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
+int create_onion_packet(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length,
const Onion_Path *path, const IP_Port *dest,
const uint8_t *data, uint16_t length);
@@ -119,7 +119,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_
* return length of created packet on success.
*/
non_null()
-int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
+int create_onion_packet_tcp(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length,
const Onion_Path *path, const IP_Port *dest,
const uint8_t *data, uint16_t length);
diff --git a/protocols/Tox/libtox/src/toxcore/onion_announce.c b/protocols/Tox/libtox/src/toxcore/onion_announce.c
index 593d81aa2c..50e2e00aef 100644
--- a/protocols/Tox/libtox/src/toxcore/onion_announce.c
+++ b/protocols/Tox/libtox/src/toxcore/onion_announce.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -9,7 +9,6 @@
#include "onion_announce.h"
#include <assert.h>
-#include <stdlib.h>
#include <string.h>
#include "DHT.h"
@@ -23,7 +22,9 @@
#include "network.h"
#include "onion.h"
#include "shared_key_cache.h"
+#include "sort.h"
#include "timed_auth.h"
+#include "util.h"
#define PING_ID_TIMEOUT ONION_ANNOUNCE_TIMEOUT
@@ -103,7 +104,7 @@ void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint
* return -1 on failure.
* return packet length on success.
*/
-int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
+int create_announce_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id,
const uint8_t *data_public_key, uint64_t sendback_data)
{
@@ -122,7 +123,7 @@ int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_pac
packet[0] = NET_PACKET_ANNOUNCE_REQUEST_OLD;
random_nonce(rng, packet + 1);
- const int len = encrypt_data(dest_client_id, secret_key, packet + 1, plain, sizeof(plain),
+ const int len = encrypt_data(mem, dest_client_id, secret_key, packet + 1, plain, sizeof(plain),
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE);
if ((uint32_t)len + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE != ONION_ANNOUNCE_REQUEST_MIN_SIZE) {
@@ -146,7 +147,7 @@ int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_pac
* return -1 on failure.
* return 0 on success.
*/
-int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
+int create_data_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length)
{
if (DATA_REQUEST_MIN_SIZE + length > max_packet_length) {
@@ -167,7 +168,7 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, random_public_key, CRYPTO_PUBLIC_KEY_SIZE);
- const int len = encrypt_data(encrypt_public_key, random_secret_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length,
+ const int len = encrypt_data(mem, encrypt_public_key, random_secret_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE);
if (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + len != DATA_REQUEST_MIN_SIZE +
@@ -193,14 +194,14 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_
* return 0 on success.
*/
int send_announce_request(
- const Logger *log, const Networking_Core *net, const Random *rng,
+ const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng,
const Onion_Path *path, const Node_format *dest,
const uint8_t *public_key, const uint8_t *secret_key,
const uint8_t *ping_id, const uint8_t *client_id,
const uint8_t *data_public_key, uint64_t sendback_data)
{
uint8_t request[ONION_ANNOUNCE_REQUEST_MIN_SIZE];
- int len = create_announce_request(rng, request, sizeof(request), dest->public_key, public_key, secret_key, ping_id,
+ int len = create_announce_request(mem, rng, request, sizeof(request), dest->public_key, public_key, secret_key, ping_id,
client_id, data_public_key, sendback_data);
if (len != sizeof(request)) {
@@ -208,7 +209,7 @@ int send_announce_request(
}
uint8_t packet[ONION_MAX_PACKET_SIZE];
- len = create_onion_packet(rng, packet, sizeof(packet), path, &dest->ip_port, request, sizeof(request));
+ len = create_onion_packet(mem, rng, packet, sizeof(packet), path, &dest->ip_port, request, sizeof(request));
if (len == -1) {
return -1;
@@ -238,19 +239,19 @@ int send_announce_request(
* return 0 on success.
*/
int send_data_request(
- const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
+ const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce,
const uint8_t *data, uint16_t length)
{
uint8_t request[ONION_MAX_DATA_SIZE];
- int len = create_data_request(rng, request, sizeof(request), public_key, encrypt_public_key, nonce, data, length);
+ int len = create_data_request(mem, rng, request, sizeof(request), public_key, encrypt_public_key, nonce, data, length);
if (len == -1) {
return -1;
}
uint8_t packet[ONION_MAX_PACKET_SIZE];
- len = create_onion_packet(rng, packet, sizeof(packet), path, dest, request, len);
+ len = create_onion_packet(mem, rng, packet, sizeof(packet), path, dest, request, len);
if (len == -1) {
return -1;
@@ -281,23 +282,17 @@ static int in_entries(const Onion_Announce *onion_a, const uint8_t *public_key)
return -1;
}
-typedef struct Cmp_Data {
+typedef struct Onion_Announce_Entry_Cmp {
+ const Memory *mem;
const Mono_Time *mono_time;
- const uint8_t *base_public_key;
- Onion_Announce_Entry entry;
-} Cmp_Data;
+ const uint8_t *comp_public_key;
+} Onion_Announce_Entry_Cmp;
non_null()
-static int cmp_entry(const void *a, const void *b)
+static int onion_announce_entry_cmp(const Onion_Announce_Entry_Cmp *cmp, const Onion_Announce_Entry *entry1, const Onion_Announce_Entry *entry2)
{
- const Cmp_Data *cmp1 = (const Cmp_Data *)a;
- const Cmp_Data *cmp2 = (const Cmp_Data *)b;
- const Onion_Announce_Entry entry1 = cmp1->entry;
- const Onion_Announce_Entry entry2 = cmp2->entry;
- const uint8_t *cmp_public_key = cmp1->base_public_key;
-
- const bool t1 = mono_time_is_timeout(cmp1->mono_time, entry1.announce_time, ONION_ANNOUNCE_TIMEOUT);
- const bool t2 = mono_time_is_timeout(cmp1->mono_time, entry2.announce_time, ONION_ANNOUNCE_TIMEOUT);
+ const bool t1 = mono_time_is_timeout(cmp->mono_time, entry1->announce_time, ONION_ANNOUNCE_TIMEOUT);
+ const bool t2 = mono_time_is_timeout(cmp->mono_time, entry2->announce_time, ONION_ANNOUNCE_TIMEOUT);
if (t1 && t2) {
return 0;
@@ -311,7 +306,7 @@ static int cmp_entry(const void *a, const void *b)
return 1;
}
- const int closest = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
+ const int closest = id_closest(cmp->comp_public_key, entry1->public_key, entry2->public_key);
if (closest == 1) {
return 1;
@@ -325,31 +320,80 @@ static int cmp_entry(const void *a, const void *b)
}
non_null()
-static void sort_onion_announce_list(const Memory *mem, const Mono_Time *mono_time,
- Onion_Announce_Entry *list, unsigned int length,
- const uint8_t *comp_public_key)
+static bool onion_announce_entry_less_handler(const void *object, const void *a, const void *b)
{
- // Pass comp_public_key to qsort with each Client_data entry, so the
- // comparison function can use it as the base of comparison.
- Cmp_Data *cmp_list = (Cmp_Data *)mem_valloc(mem, length, sizeof(Cmp_Data));
+ const Onion_Announce_Entry_Cmp *cmp = (const Onion_Announce_Entry_Cmp *)object;
+ const Onion_Announce_Entry *entry1 = (const Onion_Announce_Entry *)a;
+ const Onion_Announce_Entry *entry2 = (const Onion_Announce_Entry *)b;
- if (cmp_list == nullptr) {
- return;
- }
+ return onion_announce_entry_cmp(cmp, entry1, entry2) < 0;
+}
- for (uint32_t i = 0; i < length; ++i) {
- cmp_list[i].mono_time = mono_time;
- cmp_list[i].base_public_key = comp_public_key;
- cmp_list[i].entry = list[i];
- }
+non_null()
+static const void *onion_announce_entry_get_handler(const void *arr, uint32_t index)
+{
+ const Onion_Announce_Entry *entries = (const Onion_Announce_Entry *)arr;
+ return &entries[index];
+}
- qsort(cmp_list, length, sizeof(Cmp_Data), cmp_entry);
+non_null()
+static void onion_announce_entry_set_handler(void *arr, uint32_t index, const void *val)
+{
+ Onion_Announce_Entry *entries = (Onion_Announce_Entry *)arr;
+ const Onion_Announce_Entry *entry = (const Onion_Announce_Entry *)val;
+ entries[index] = *entry;
+}
- for (uint32_t i = 0; i < length; ++i) {
- list[i] = cmp_list[i].entry;
+non_null()
+static void *onion_announce_entry_subarr_handler(void *arr, uint32_t index, uint32_t size)
+{
+ Onion_Announce_Entry *entries = (Onion_Announce_Entry *)arr;
+ return &entries[index];
+}
+
+non_null()
+static void *onion_announce_entry_alloc_handler(const void *object, uint32_t size)
+{
+ const Onion_Announce_Entry_Cmp *cmp = (const Onion_Announce_Entry_Cmp *)object;
+ Onion_Announce_Entry *tmp = (Onion_Announce_Entry *)mem_valloc(cmp->mem, size, sizeof(Onion_Announce_Entry));
+
+ if (tmp == nullptr) {
+ return nullptr;
}
- mem_delete(mem, cmp_list);
+ return tmp;
+}
+
+non_null()
+static void onion_announce_entry_delete_handler(const void *object, void *arr, uint32_t size)
+{
+ const Onion_Announce_Entry_Cmp *cmp = (const Onion_Announce_Entry_Cmp *)object;
+ mem_delete(cmp->mem, arr);
+}
+
+static const Sort_Funcs onion_announce_entry_cmp_funcs = {
+ onion_announce_entry_less_handler,
+ onion_announce_entry_get_handler,
+ onion_announce_entry_set_handler,
+ onion_announce_entry_subarr_handler,
+ onion_announce_entry_alloc_handler,
+ onion_announce_entry_delete_handler,
+};
+
+non_null()
+static void sort_onion_announce_list(const Memory *mem, const Mono_Time *mono_time,
+ Onion_Announce_Entry *list, unsigned int length,
+ const uint8_t *comp_public_key)
+{
+ // Pass comp_public_key to sort with each Onion_Announce_Entry entry, so the
+ // comparison function can use it as the base of comparison.
+ const Onion_Announce_Entry_Cmp cmp = {
+ mem,
+ mono_time,
+ comp_public_key,
+ };
+
+ merge_sort(list, length, &cmp, &onion_announce_entry_cmp_funcs);
}
/** @brief add entry to entries list
@@ -455,7 +499,7 @@ static int handle_announce_request_common(
return 1;
}
- const int decrypted_len = decrypt_data_symmetric(shared_key, packet + 1,
+ const int decrypted_len = decrypt_data_symmetric(onion_a->mem, shared_key, packet + 1,
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, plain_size + CRYPTO_MAC_SIZE, plain);
if ((uint32_t)decrypted_len != plain_size) {
@@ -463,11 +507,17 @@ static int handle_announce_request_common(
return 1;
}
- const uint16_t ping_id_data_len = CRYPTO_PUBLIC_KEY_SIZE + sizeof(*source);
- uint8_t ping_id_data[CRYPTO_PUBLIC_KEY_SIZE + sizeof(*source)];
+ const uint16_t ping_id_data_len = CRYPTO_PUBLIC_KEY_SIZE + SIZE_IPPORT;
+ uint8_t ping_id_data[CRYPTO_PUBLIC_KEY_SIZE + SIZE_IPPORT];
memcpy(ping_id_data, packet_public_key, CRYPTO_PUBLIC_KEY_SIZE);
- memcpy(ping_id_data + CRYPTO_PUBLIC_KEY_SIZE, source, sizeof(*source));
-
+ const int packed_len = pack_ip_port(onion_a->log, &ping_id_data[CRYPTO_PUBLIC_KEY_SIZE], SIZE_IPPORT, source);
+ if (packed_len < 0) {
+ LOGGER_ERROR(onion_a->log, "failed to pack IP/Port");
+ mem_delete(onion_a->mem, plain);
+ return 1;
+ }
+ assert(packed_len <= SIZE_IPPORT);
+ memzero(&ping_id_data[CRYPTO_PUBLIC_KEY_SIZE + packed_len], SIZE_IPPORT - packed_len);
const uint8_t *data_public_key = plain + ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE;
int index;
@@ -510,7 +560,7 @@ static int handle_announce_request_common(
int nodes_length = 0;
if (num_nodes != 0) {
- nodes_length = pack_nodes(onion_a->log, response + nodes_offset, sizeof(nodes_list), nodes_list,
+ nodes_length = pack_nodes(onion_a->log, &response[nodes_offset], num_nodes * PACKED_NODE_SIZE_IP6, nodes_list,
(uint16_t)num_nodes);
if (nodes_length <= 0) {
@@ -529,7 +579,7 @@ static int handle_announce_request_common(
const int extra_size = pack_extra_data_callback == nullptr ? 0
: pack_extra_data_callback(onion_a->extra_data_object,
- onion_a->log, onion_a->mono_time, num_nodes,
+ onion_a->log, onion_a->mem, onion_a->mono_time, num_nodes,
plain + ONION_MINIMAL_SIZE, length - ANNOUNCE_REQUEST_MIN_SIZE_RECV,
response, response_size, offset);
@@ -542,7 +592,7 @@ static int handle_announce_request_common(
offset += extra_size;
uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE];
- const int len = encrypt_data_symmetric(shared_key, nonce, response, offset,
+ const int len = encrypt_data_symmetric(onion_a->mem, shared_key, nonce, response, offset,
data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE);
if (len != offset + CRYPTO_MAC_SIZE) {
diff --git a/protocols/Tox/libtox/src/toxcore/onion_announce.h b/protocols/Tox/libtox/src/toxcore/onion_announce.h
index 1158093170..d8834395c0 100644
--- a/protocols/Tox/libtox/src/toxcore/onion_announce.h
+++ b/protocols/Tox/libtox/src/toxcore/onion_announce.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -65,7 +65,7 @@ void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint
* return packet length on success.
*/
non_null()
-int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
+int create_announce_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id,
const uint8_t *data_public_key, uint64_t sendback_data);
@@ -82,7 +82,7 @@ int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_pac
* return 0 on success.
*/
non_null()
-int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
+int create_data_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length);
/** @brief Create and send an onion announce request packet.
@@ -101,7 +101,7 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_
*/
non_null()
int send_announce_request(
- const Logger *log, const Networking_Core *net, const Random *rng,
+ const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng,
const Onion_Path *path, const Node_format *dest,
const uint8_t *public_key, const uint8_t *secret_key,
const uint8_t *ping_id, const uint8_t *client_id,
@@ -125,11 +125,11 @@ int send_announce_request(
*/
non_null()
int send_data_request(
- const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
+ const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce,
const uint8_t *data, uint16_t length);
-typedef int pack_extra_data_cb(void *object, const Logger *logger, const Mono_Time *mono_time,
+typedef int pack_extra_data_cb(void *object, const Logger *logger, const Memory *mem, const Mono_Time *mono_time,
uint8_t num_nodes, uint8_t *plain, uint16_t plain_size,
uint8_t *response, uint16_t response_size, uint16_t offset);
diff --git a/protocols/Tox/libtox/src/toxcore/onion_client.c b/protocols/Tox/libtox/src/toxcore/onion_client.c
index 9b0ac96102..e802d70298 100644
--- a/protocols/Tox/libtox/src/toxcore/onion_client.c
+++ b/protocols/Tox/libtox/src/toxcore/onion_client.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -10,7 +10,6 @@
#include "onion_client.h"
#include <assert.h>
-#include <stdlib.h>
#include <string.h>
#include "DHT.h"
@@ -29,6 +28,7 @@
#include "onion.h"
#include "onion_announce.h"
#include "ping_array.h"
+#include "sort.h"
#include "timed_auth.h"
#include "util.h"
@@ -470,6 +470,7 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa
onion_paths->paths[pathnum].path_num = path_num;
} else {
+ assert(0 <= n && n < NUMBER_ONION_PATHS);
pathnum = n;
}
}
@@ -528,7 +529,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa
{
if (net_family_is_ipv4(path->ip_port1.ip.family) || net_family_is_ipv6(path->ip_port1.ip.family)) {
uint8_t packet[ONION_MAX_PACKET_SIZE];
- const int len = create_onion_packet(onion_c->rng, packet, sizeof(packet), path, dest, data, length);
+ const int len = create_onion_packet(onion_c->mem, onion_c->rng, packet, sizeof(packet), path, dest, data, length);
if (len == -1) {
return -1;
@@ -545,7 +546,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa
if (ip_port_to_tcp_connections_number(&path->ip_port1, &tcp_connections_number)) {
uint8_t packet[ONION_MAX_PACKET_SIZE];
- const int len = create_onion_packet_tcp(onion_c->rng, packet, sizeof(packet), path, dest, data, length);
+ const int len = create_onion_packet_tcp(onion_c->mem, onion_c->rng, packet, sizeof(packet), path, dest, data, length);
if (len == -1) {
return -1;
@@ -576,11 +577,17 @@ non_null()
static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *public_key, const IP_Port *ip_port,
uint32_t path_num, uint64_t *sendback)
{
- uint8_t data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port) + sizeof(uint32_t)];
+ uint8_t data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + SIZE_IPPORT + sizeof(uint32_t)];
memcpy(data, &num, sizeof(uint32_t));
- memcpy(data + sizeof(uint32_t), public_key, CRYPTO_PUBLIC_KEY_SIZE);
- memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE, ip_port, sizeof(IP_Port));
- memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port), &path_num, sizeof(uint32_t));
+ memcpy(&data[sizeof(uint32_t)], public_key, CRYPTO_PUBLIC_KEY_SIZE);
+ const int packed_len = pack_ip_port(onion_c->logger, &data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE], SIZE_IPPORT, ip_port);
+ if (packed_len < 0) {
+ LOGGER_ERROR(onion_c->logger, "failed to pack IP/port");
+ return -1;
+ }
+ assert(packed_len <= SIZE_IPPORT);
+ memzero(&data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + packed_len], SIZE_IPPORT - packed_len);
+ memcpy(&data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + SIZE_IPPORT], &path_num, sizeof(uint32_t));
*sendback = ping_array_add(onion_c->announce_ping_array, onion_c->mono_time, onion_c->rng, data, sizeof(data));
if (*sendback == 0) {
@@ -607,15 +614,15 @@ static uint32_t check_sendback(Onion_Client *onion_c, const uint8_t *sendback, u
{
uint64_t sback;
memcpy(&sback, sendback, sizeof(uint64_t));
- uint8_t data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port) + sizeof(uint32_t)];
+ uint8_t data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + SIZE_IPPORT + sizeof(uint32_t)];
if (ping_array_check(onion_c->announce_ping_array, onion_c->mono_time, data, sizeof(data), sback) != sizeof(data)) {
return -1;
}
memcpy(ret_pubkey, data + sizeof(uint32_t), CRYPTO_PUBLIC_KEY_SIZE);
- memcpy(ret_ip_port, data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE, sizeof(IP_Port));
- memcpy(path_num, data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port), sizeof(uint32_t));
+ unpack_ip_port(ret_ip_port, data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE, SIZE_IPPORT, false);
+ memcpy(path_num, data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + SIZE_IPPORT, sizeof(uint32_t));
uint32_t num;
memcpy(&num, data, sizeof(uint32_t));
@@ -661,7 +668,7 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con
if (num == 0) {
len = create_announce_request(
- onion_c->rng, request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c),
+ onion_c->mem, onion_c->rng, request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c),
nc_get_self_secret_key(onion_c->c), ping_id, nc_get_self_public_key(onion_c->c),
onion_c->temp_public_key, sendback);
} else {
@@ -669,14 +676,14 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con
if (onion_friend->gc_data_length == 0) { // contact is a friend
len = create_announce_request(
- onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key,
+ onion_c->mem, onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key,
onion_friend->temp_secret_key, ping_id, onion_friend->real_public_key,
zero_ping_id, sendback);
} else { // contact is a gc
onion_friend->is_groupchat = true;
len = create_gca_announce_request(
- onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key,
+ onion_c->mem, onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key,
onion_friend->temp_secret_key, ping_id, onion_friend->real_public_key,
zero_ping_id, sendback, onion_friend->gc_data,
onion_friend->gc_data_length);
@@ -694,23 +701,17 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con
return send_onion_packet_tcp_udp(onion_c, &path, dest, request, len);
}
-typedef struct Onion_Client_Cmp_Data {
+typedef struct Onion_Node_Cmp {
+ const Memory *mem;
const Mono_Time *mono_time;
- const uint8_t *base_public_key;
- Onion_Node entry;
-} Onion_Client_Cmp_Data;
+ const uint8_t *comp_public_key;
+} Onion_Node_Cmp;
non_null()
-static int onion_client_cmp_entry(const void *a, const void *b)
+static int onion_node_cmp(const Onion_Node_Cmp *cmp, const Onion_Node *entry1, const Onion_Node *entry2)
{
- const Onion_Client_Cmp_Data *cmp1 = (const Onion_Client_Cmp_Data *)a;
- const Onion_Client_Cmp_Data *cmp2 = (const Onion_Client_Cmp_Data *)b;
- const Onion_Node entry1 = cmp1->entry;
- const Onion_Node entry2 = cmp2->entry;
- const uint8_t *cmp_public_key = cmp1->base_public_key;
-
- const bool t1 = onion_node_timed_out(&entry1, cmp1->mono_time);
- const bool t2 = onion_node_timed_out(&entry2, cmp2->mono_time);
+ const bool t1 = onion_node_timed_out(entry1, cmp->mono_time);
+ const bool t2 = onion_node_timed_out(entry2, cmp->mono_time);
if (t1 && t2) {
return 0;
@@ -724,7 +725,7 @@ static int onion_client_cmp_entry(const void *a, const void *b)
return 1;
}
- const int closest = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
+ const int closest = id_closest(cmp->comp_public_key, entry1->public_key, entry2->public_key);
if (closest == 1) {
return 1;
@@ -738,30 +739,79 @@ static int onion_client_cmp_entry(const void *a, const void *b)
}
non_null()
-static void sort_onion_node_list(const Memory *mem, const Mono_Time *mono_time,
- Onion_Node *list, unsigned int length, const uint8_t *comp_public_key)
+static bool onion_node_less_handler(const void *object, const void *a, const void *b)
{
- // Pass comp_public_key to qsort with each Client_data entry, so the
- // comparison function can use it as the base of comparison.
- Onion_Client_Cmp_Data *cmp_list = (Onion_Client_Cmp_Data *)mem_valloc(mem, length, sizeof(Onion_Client_Cmp_Data));
+ const Onion_Node_Cmp *cmp = (const Onion_Node_Cmp *)object;
+ const Onion_Node *entry1 = (const Onion_Node *)a;
+ const Onion_Node *entry2 = (const Onion_Node *)b;
- if (cmp_list == nullptr) {
- return;
- }
+ return onion_node_cmp(cmp, entry1, entry2) < 0;
+}
- for (uint32_t i = 0; i < length; ++i) {
- cmp_list[i].mono_time = mono_time;
- cmp_list[i].base_public_key = comp_public_key;
- cmp_list[i].entry = list[i];
- }
+non_null()
+static const void *onion_node_get_handler(const void *arr, uint32_t index)
+{
+ const Onion_Node *entries = (const Onion_Node *)arr;
+ return &entries[index];
+}
- qsort(cmp_list, length, sizeof(Onion_Client_Cmp_Data), onion_client_cmp_entry);
+non_null()
+static void onion_node_set_handler(void *arr, uint32_t index, const void *val)
+{
+ Onion_Node *entries = (Onion_Node *)arr;
+ const Onion_Node *entry = (const Onion_Node *)val;
+ entries[index] = *entry;
+}
- for (uint32_t i = 0; i < length; ++i) {
- list[i] = cmp_list[i].entry;
+non_null()
+static void *onion_node_subarr_handler(void *arr, uint32_t index, uint32_t size)
+{
+ Onion_Node *entries = (Onion_Node *)arr;
+ return &entries[index];
+}
+
+non_null()
+static void *onion_node_alloc_handler(const void *object, uint32_t size)
+{
+ const Onion_Node_Cmp *cmp = (const Onion_Node_Cmp *)object;
+ Onion_Node *tmp = (Onion_Node *)mem_valloc(cmp->mem, size, sizeof(Onion_Node));
+
+ if (tmp == nullptr) {
+ return nullptr;
}
- mem_delete(mem, cmp_list);
+ return tmp;
+}
+
+non_null()
+static void onion_node_delete_handler(const void *object, void *arr, uint32_t size)
+{
+ const Onion_Node_Cmp *cmp = (const Onion_Node_Cmp *)object;
+ mem_delete(cmp->mem, arr);
+}
+
+static const Sort_Funcs onion_node_cmp_funcs = {
+ onion_node_less_handler,
+ onion_node_get_handler,
+ onion_node_set_handler,
+ onion_node_subarr_handler,
+ onion_node_alloc_handler,
+ onion_node_delete_handler,
+};
+
+non_null()
+static void sort_onion_node_list(const Memory *mem, const Mono_Time *mono_time,
+ Onion_Node *list, unsigned int length, const uint8_t *comp_public_key)
+{
+ // Pass comp_public_key to sort with each Onion_Node entry, so the
+ // comparison function can use it as the base of comparison.
+ const Onion_Node_Cmp cmp = {
+ mem,
+ mono_time,
+ comp_public_key,
+ };
+
+ merge_sort(list, length, &cmp, &onion_node_cmp_funcs);
}
non_null()
@@ -955,14 +1005,14 @@ static int handle_announce_response(void *object, const IP_Port *source, const u
}
uint8_t plain[1 + ONION_PING_ID_SIZE + ONION_ANNOUNCE_RESPONSE_MAX_SIZE - ONION_ANNOUNCE_RESPONSE_MIN_SIZE];
- const int plain_size = 1 + ONION_PING_ID_SIZE + length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE;
+ const uint32_t plain_size = 1 + ONION_PING_ID_SIZE + length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE;
int len;
const uint16_t nonce_start = 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH;
const uint16_t ciphertext_start = nonce_start + CRYPTO_NONCE_SIZE;
const uint16_t ciphertext_size = length - ciphertext_start;
if (num == 0) {
- len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c),
+ len = decrypt_data(onion_c->mem, public_key, nc_get_self_secret_key(onion_c->c),
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
} else {
if (!onion_c->friends_list[num - 1].is_valid) {
@@ -970,7 +1020,7 @@ static int handle_announce_response(void *object, const IP_Port *source, const u
return 1;
}
- len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key,
+ len = decrypt_data(onion_c->mem, public_key, onion_c->friends_list[num - 1].temp_secret_key,
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
}
@@ -1066,7 +1116,7 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con
const uint16_t ciphertext_size = length - ciphertext_start;
if (num == 0) {
- len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c),
+ len = decrypt_data(onion_c->mem, public_key, nc_get_self_secret_key(onion_c->c),
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
} else {
if (!onion_c->friends_list[num - 1].is_valid) {
@@ -1074,7 +1124,7 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con
return 1;
}
- len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key,
+ len = decrypt_data(onion_c->mem, public_key, onion_c->friends_list[num - 1].temp_secret_key,
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
}
@@ -1136,7 +1186,7 @@ static int handle_data_response(void *object, const IP_Port *source, const uint8
const uint16_t temp_plain_size = length - ONION_DATA_RESPONSE_MIN_SIZE;
VLA(uint8_t, temp_plain, temp_plain_size);
- int len = decrypt_data(packet + 1 + CRYPTO_NONCE_SIZE, onion_c->temp_secret_key, packet + 1,
+ int len = decrypt_data(onion_c->mem, packet + 1 + CRYPTO_NONCE_SIZE, onion_c->temp_secret_key, packet + 1,
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE), temp_plain);
@@ -1146,7 +1196,7 @@ static int handle_data_response(void *object, const IP_Port *source, const uint8
const uint16_t plain_size = temp_plain_size - DATA_IN_RESPONSE_MIN_SIZE;
VLA(uint8_t, plain, plain_size);
- len = decrypt_data(temp_plain, nc_get_self_secret_key(onion_c->c),
+ len = decrypt_data(onion_c->mem, temp_plain, nc_get_self_secret_key(onion_c->c),
packet + 1, temp_plain + CRYPTO_PUBLIC_KEY_SIZE,
temp_plain_size - CRYPTO_PUBLIC_KEY_SIZE, plain);
@@ -1215,7 +1265,7 @@ static int handle_dhtpk_announce(void *object, const uint8_t *source_pubkey, con
const Family family = nodes[i].ip_port.ip.family;
if (net_family_is_ipv4(family) || net_family_is_ipv6(family)) {
- dht_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].public_key, onion_c->friends_list[friend_num].dht_public_key);
+ dht_send_nodes_request(onion_c->dht, &nodes[i].ip_port, nodes[i].public_key, onion_c->friends_list[friend_num].dht_public_key);
} else if (net_family_is_tcp_ipv4(family) || net_family_is_tcp_ipv6(family)) {
if (onion_c->friends_list[friend_num].tcp_relay_node_callback != nullptr) {
void *obj = onion_c->friends_list[friend_num].tcp_relay_node_callback_object;
@@ -1305,7 +1355,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data,
const uint16_t packet_size = DATA_IN_RESPONSE_MIN_SIZE + length;
VLA(uint8_t, packet, packet_size);
memcpy(packet, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE);
- int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key,
+ int len = encrypt_data(onion_c->mem, onion_c->friends_list[friend_num].real_public_key,
nc_get_self_secret_key(onion_c->c), nonce, data,
length, packet + CRYPTO_PUBLIC_KEY_SIZE);
@@ -1324,7 +1374,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data,
uint8_t o_packet[ONION_MAX_PACKET_SIZE];
len = create_data_request(
- onion_c->rng, o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key,
+ onion_c->mem, onion_c->rng, o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key,
node_list[good_nodes[i]].data_public_key, nonce, packet, packet_size);
if (len == -1) {
@@ -1364,7 +1414,7 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin
VLA(uint8_t, temp, temp_size);
memcpy(temp, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE);
memcpy(temp + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE);
- int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key,
+ int len = encrypt_data(onion_c->mem, onion_c->friends_list[friend_num].real_public_key,
nc_get_self_secret_key(onion_c->c), nonce, data,
length, temp + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
@@ -1374,7 +1424,7 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin
uint8_t packet_data[MAX_CRYPTO_REQUEST_SIZE];
len = create_request(
- onion_c->rng, dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data,
+ onion_c->mem, onion_c->rng, dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data,
onion_c->friends_list[friend_num].dht_public_key, temp, temp_size, CRYPTO_PACKET_DHTPK);
assert(len <= UINT16_MAX);
const Packet packet = {packet_data, (uint16_t)len};
@@ -1401,7 +1451,7 @@ static int handle_dht_dhtpk(void *object, const IP_Port *source, const uint8_t *
}
uint8_t plain[DHTPK_DATA_MAX_LENGTH];
- const int len = decrypt_data(packet, nc_get_self_secret_key(onion_c->c),
+ const int len = decrypt_data(onion_c->mem, packet, nc_get_self_secret_key(onion_c->c),
packet + CRYPTO_PUBLIC_KEY_SIZE,
packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
length - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), plain);
diff --git a/protocols/Tox/libtox/src/toxcore/onion_client.h b/protocols/Tox/libtox/src/toxcore/onion_client.h
index 61e4e6fd1c..5999f15c65 100644
--- a/protocols/Tox/libtox/src/toxcore/onion_client.h
+++ b/protocols/Tox/libtox/src/toxcore/onion_client.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -183,6 +183,8 @@ non_null()
unsigned int onion_getfriend_dht_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key);
#define ONION_DATA_IN_RESPONSE_MIN_SIZE (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE)
+
+// TODO(Jfreegman): This is not the correct value; data this large will be dropped by the onion client.
#define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE)
/** @brief Send data of length length to friendnum.
diff --git a/protocols/Tox/libtox/src/toxcore/ping.c b/protocols/Tox/libtox/src/toxcore/ping.c
index 303c418cea..bfb3c92cd3 100644
--- a/protocols/Tox/libtox/src/toxcore/ping.c
+++ b/protocols/Tox/libtox/src/toxcore/ping.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
* Copyright © 2013 plutooo
*/
@@ -31,6 +31,7 @@
struct Ping {
const Mono_Time *mono_time;
const Random *rng;
+ const Memory *mem;
DHT *dht;
Ping_Array *ping_array;
@@ -72,7 +73,7 @@ void ping_send_request(Ping *ping, const IP_Port *ipp, const uint8_t *public_key
pk_copy(pk + 1, dht_get_self_public_key(ping->dht)); // Our pubkey
random_nonce(ping->rng, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce
- rc = encrypt_data_symmetric(shared_key,
+ rc = encrypt_data_symmetric(ping->mem, shared_key,
pk + 1 + CRYPTO_PUBLIC_KEY_SIZE,
ping_plain, sizeof(ping_plain),
pk + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
@@ -104,7 +105,7 @@ static int ping_send_response(const Ping *ping, const IP_Port *ipp, const uint8_
random_nonce(ping->rng, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce
// Encrypt ping_id using recipient privkey
- const int rc = encrypt_data_symmetric(shared_encryption_key,
+ const int rc = encrypt_data_symmetric(ping->mem, shared_encryption_key,
pk + 1 + CRYPTO_PUBLIC_KEY_SIZE,
ping_plain, sizeof(ping_plain),
pk + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
@@ -137,7 +138,7 @@ static int handle_ping_request(void *object, const IP_Port *source, const uint8_
uint8_t ping_plain[PING_PLAIN_SIZE];
// Decrypt ping_id
- const int rc = decrypt_data_symmetric(shared_key,
+ const int rc = decrypt_data_symmetric(ping->mem, shared_key,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
PING_PLAIN_SIZE + CRYPTO_MAC_SIZE,
@@ -182,7 +183,7 @@ static int handle_ping_response(void *object, const IP_Port *source, const uint8
uint8_t ping_plain[PING_PLAIN_SIZE];
// Decrypt ping_id
- rc = decrypt_data_symmetric(shared_key,
+ rc = decrypt_data_symmetric(ping->mem, shared_key,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
PING_PLAIN_SIZE + CRYPTO_MAC_SIZE,
@@ -348,6 +349,7 @@ Ping *ping_new(const Memory *mem, const Mono_Time *mono_time, const Random *rng,
ping->mono_time = mono_time;
ping->rng = rng;
+ ping->mem = mem;
ping->dht = dht;
networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_REQUEST, &handle_ping_request, dht);
networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_RESPONSE, &handle_ping_response, dht);
diff --git a/protocols/Tox/libtox/src/toxcore/ping.h b/protocols/Tox/libtox/src/toxcore/ping.h
index b0339ec75d..98ae7bd754 100644
--- a/protocols/Tox/libtox/src/toxcore/ping.h
+++ b/protocols/Tox/libtox/src/toxcore/ping.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
* Copyright © 2013 plutooo
*/
diff --git a/protocols/Tox/libtox/src/toxcore/ping_array.c b/protocols/Tox/libtox/src/toxcore/ping_array.c
index c40215ea47..91b9064ecc 100644
--- a/protocols/Tox/libtox/src/toxcore/ping_array.c
+++ b/protocols/Tox/libtox/src/toxcore/ping_array.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2014 Tox project.
*/
diff --git a/protocols/Tox/libtox/src/toxcore/ping_array.h b/protocols/Tox/libtox/src/toxcore/ping_array.h
index 3e50e66876..2d1f9f5cc2 100644
--- a/protocols/Tox/libtox/src/toxcore/ping_array.h
+++ b/protocols/Tox/libtox/src/toxcore/ping_array.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
diff --git a/protocols/Tox/libtox/src/toxcore/shared_key_cache.c b/protocols/Tox/libtox/src/toxcore/shared_key_cache.c
index 80d74aecb4..64906b569c 100644
--- a/protocols/Tox/libtox/src/toxcore/shared_key_cache.c
+++ b/protocols/Tox/libtox/src/toxcore/shared_key_cache.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#include "shared_key_cache.h"
diff --git a/protocols/Tox/libtox/src/toxcore/shared_key_cache.h b/protocols/Tox/libtox/src/toxcore/shared_key_cache.h
index f6e84c3130..69295325d6 100644
--- a/protocols/Tox/libtox/src/toxcore/shared_key_cache.h
+++ b/protocols/Tox/libtox/src/toxcore/shared_key_cache.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_SHARED_KEY_CACHE_H
diff --git a/protocols/Tox/libtox/src/toxcore/sort.c b/protocols/Tox/libtox/src/toxcore/sort.c
new file mode 100644
index 0000000000..9bd83d6171
--- /dev/null
+++ b/protocols/Tox/libtox/src/toxcore/sort.c
@@ -0,0 +1,182 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright © 2023-2025 The TokTok team.
+ */
+
+#include "sort.h"
+
+#include <assert.h>
+
+#include "attributes.h"
+#include "ccompat.h"
+#include "util.h"
+
+/**
+ * @brief Threshold for when to switch to insertion sort.
+ *
+ * This is a trade-off between the complexity of insertion sort and the
+ * overhead of merge sort. The threshold is chosen to be the smallest value
+ * that gives a measurable speedup for insertion sort over merge sort. This is
+ * based on measurements done in sort_bench.cc. Starting from 32 elements,
+ * merge sort is faster than insertion sort in all our tests (both unsorted
+ * and mostly-sorted).
+ *
+ * Toxcore has a lot of small arrays it wants to sort, so this optimisation
+ * makes sense.
+ */
+#define SMALL_ARRAY_THRESHOLD 16
+
+non_null()
+static void merge_sort_merge_back(
+ void *arr,
+ const void *l_arr, uint32_t l_arr_size,
+ const void *r_arr, uint32_t r_arr_size,
+ uint32_t left_start,
+ const void *object, const Sort_Funcs *funcs)
+{
+ uint32_t li = 0;
+ uint32_t ri = 0;
+ uint32_t k = left_start;
+
+ while (li < l_arr_size && ri < r_arr_size) {
+ const void *l = funcs->get_callback(l_arr, li);
+ const void *r = funcs->get_callback(r_arr, ri);
+ // !(r < l) <=> (r >= l) <=> (l <= r)
+ if (!funcs->less_callback(object, r, l)) {
+ funcs->set_callback(arr, k, l);
+ ++li;
+ } else {
+ funcs->set_callback(arr, k, r);
+ ++ri;
+ }
+ ++k;
+ }
+
+ /* Copy the remaining elements of `l_arr[]`, if there are any. */
+ while (li < l_arr_size) {
+ funcs->set_callback(arr, k, funcs->get_callback(l_arr, li));
+ ++li;
+ ++k;
+ }
+
+ /* Copy the remaining elements of `r_arr[]`, if there are any. */
+ while (ri < r_arr_size) {
+ funcs->set_callback(arr, k, funcs->get_callback(r_arr, ri));
+ ++ri;
+ ++k;
+ }
+}
+
+/** Function to merge the two haves `arr[left_start..mid]` and `arr[mid+1..right_end]` of array `arr[]`. */
+non_null()
+static void merge_sort_merge(
+ void *arr, uint32_t left_start, uint32_t mid, uint32_t right_end, void *tmp,
+ const void *object, const Sort_Funcs *funcs)
+{
+ const uint32_t l_arr_size = mid - left_start + 1;
+ const uint32_t r_arr_size = right_end - mid;
+
+ /* Temporary arrays, using the tmp buffer created in `merge_sort` below. */
+ void *l_arr = funcs->subarr_callback(tmp, 0, l_arr_size);
+ void *r_arr = funcs->subarr_callback(tmp, l_arr_size, r_arr_size);
+
+ /* Copy data to temp arrays `l_arr[]` and `r_arr[]`.
+ *
+ * This is iterating and repeatedly calling `get` and `set`, which sounds
+ * slow, but is only marginally slower than having a `copy` callback. With
+ * a `copy` callback, we'd save 3-4% in time.
+ */
+ for (uint32_t i = 0; i < l_arr_size; ++i) {
+ funcs->set_callback(l_arr, i, funcs->get_callback(arr, left_start + i));
+ }
+ for (uint32_t i = 0; i < r_arr_size; ++i) {
+ funcs->set_callback(r_arr, i, funcs->get_callback(arr, mid + 1 + i));
+ }
+
+ /* Merge the temp arrays back into `arr[left_start..right_end]`. */
+ merge_sort_merge_back(arr, l_arr, l_arr_size, r_arr, r_arr_size, left_start, object, funcs);
+}
+
+non_null()
+static void insertion_sort_step(void *arr, void *tmp, uint32_t i, const void *object, const Sort_Funcs *funcs)
+{
+ funcs->set_callback(tmp, 0, funcs->get_callback(arr, i));
+ uint32_t j = i;
+
+ while (j > 0) {
+ if (!funcs->less_callback(object, tmp, funcs->get_callback(arr, j - 1))) {
+ break;
+ }
+ funcs->set_callback(arr, j, funcs->get_callback(arr, j - 1));
+ --j;
+ }
+
+ funcs->set_callback(arr, j, tmp);
+}
+
+non_null()
+static void insertion_sort_with_buf(void *arr, uint32_t arr_size, void *tmp, uint32_t tmp_size, const void *object, const Sort_Funcs *funcs)
+{
+ for (uint32_t i = 1; i < arr_size; ++i) {
+ insertion_sort_step(arr, tmp, i, object, funcs);
+ }
+}
+
+non_null()
+static bool insertion_sort(void *arr, uint32_t arr_size, const void *object, const Sort_Funcs *funcs)
+{
+ void *tmp = funcs->alloc_callback(object, 1);
+
+ if (tmp == nullptr) {
+ return false;
+ }
+
+ insertion_sort_with_buf(arr, arr_size, tmp, 1, object, funcs);
+
+ funcs->delete_callback(object, tmp, 1);
+ return true;
+}
+
+void merge_sort_with_buf(void *arr, uint32_t arr_size, void *tmp, uint32_t tmp_size, const void *object, const Sort_Funcs *funcs)
+{
+ assert(tmp_size >= arr_size);
+
+ if (arr_size <= SMALL_ARRAY_THRESHOLD) {
+ assert(tmp_size >= 1);
+ insertion_sort_with_buf(arr, arr_size, tmp, tmp_size, object, funcs);
+ return;
+ }
+
+ // Merge subarrays in bottom up manner. First merge subarrays of
+ // size 1 to create sorted subarrays of size 2, then merge subarrays
+ // of size 2 to create sorted subarrays of size 4, and so on.
+ for (uint32_t curr_size = 1; curr_size <= arr_size - 1; curr_size = 2 * curr_size) {
+ // Pick starting point of different subarrays of current size
+ for (uint32_t left_start = 0; left_start < arr_size - 1; left_start += 2 * curr_size) {
+ // Find ending point of left subarray. mid+1 is starting
+ // point of right
+ const uint32_t mid = min_u32(left_start + curr_size - 1, arr_size - 1);
+ const uint32_t right_end = min_u32(left_start + 2 * curr_size - 1, arr_size - 1);
+
+ // Merge Subarrays arr[left_start...mid] & arr[mid+1...right_end]
+ merge_sort_merge(arr, left_start, mid, right_end, tmp, object, funcs);
+ }
+ }
+}
+
+bool merge_sort(void *arr, uint32_t arr_size, const void *object, const Sort_Funcs *funcs)
+{
+ if (arr_size <= SMALL_ARRAY_THRESHOLD) {
+ return insertion_sort(arr, arr_size, object, funcs);
+ }
+
+ void *tmp = funcs->alloc_callback(object, arr_size);
+
+ if (tmp == nullptr) {
+ return false;
+ }
+
+ merge_sort_with_buf(arr, arr_size, tmp, arr_size, object, funcs);
+
+ funcs->delete_callback(object, tmp, arr_size);
+ return true;
+}
diff --git a/protocols/Tox/libtox/src/toxcore/sort.h b/protocols/Tox/libtox/src/toxcore/sort.h
new file mode 100644
index 0000000000..b95ca8be3c
--- /dev/null
+++ b/protocols/Tox/libtox/src/toxcore/sort.h
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright © 2023-2025 The TokTok team.
+ */
+
+#ifndef C_TOXCORE_TOXCORE_SORT_H
+#define C_TOXCORE_TOXCORE_SORT_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "attributes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Compare elements with a less-than ordering: `a < b`. */
+typedef bool sort_less_cb(const void *object, const void *a, const void *b);
+/** @brief Get element from array at index. */
+typedef const void *sort_get_cb(const void *arr, uint32_t index);
+/** @brief Set element in array at index to new value (perform copy). */
+typedef void sort_set_cb(void *arr, uint32_t index, const void *val);
+/** @brief Get a sub-array at an index of a given size (mutable pointer).
+ *
+ * Used to index in the temporary array allocated by `sort_alloc_cb` and get
+ * a sub-array for working memory.
+ */
+typedef void *sort_subarr_cb(void *arr, uint32_t index, uint32_t size);
+/** @brief Allocate a new array of the element type.
+ *
+ * @param size The array size in elements of type T (not byte size). This value
+ * is always exactly the input array size as passed to `merge_sort`.
+ */
+typedef void *sort_alloc_cb(const void *object, uint32_t size);
+/** @brief Free the element type array. */
+typedef void sort_delete_cb(const void *object, void *arr, uint32_t size);
+
+/** @brief Virtual function table for getting/setting elements in an array and
+ * comparing them.
+ *
+ * Only the `less`, `alloc`, and `delete` functions get a `this`-pointer. We
+ * assume that indexing in an array doesn't need any other information than the
+ * array itself.
+ *
+ * For now, the `this`-pointer is const, because we assume sorting doesn't need
+ * to mutate any state, but if necessary that can be changed in the future.
+ */
+typedef struct Sort_Funcs {
+ sort_less_cb *less_callback;
+ sort_get_cb *get_callback;
+ sort_set_cb *set_callback;
+ sort_subarr_cb *subarr_callback;
+ sort_alloc_cb *alloc_callback;
+ sort_delete_cb *delete_callback;
+} Sort_Funcs;
+
+/** @brief Non-recursive merge sort function to sort `arr[0...arr_size-1]`.
+ *
+ * Avoids `memcpy` and avoids treating elements as byte arrays. Instead, uses
+ * callbacks to index in arrays and copy elements. This makes it quite a bit
+ * slower than `qsort`, but works with elements that require special care when
+ * being copied (e.g. if they are part of a graph or other data structure that
+ * with pointers or other invariants).
+ *
+ * This function actually uses insertion sort for small arrays (up to 16
+ * elements), which is faster than merge sort for small arrays, especially
+ * when mostly sorted (a common use case in toxcore).
+ *
+ * Allocates a single temporary array with the provided alloc callback, and
+ * frees it at the end. This is significantly faster than an in-place
+ * implementation.
+ *
+ * Complexity:
+ * - Space: `O(n) where n = array_size`.
+ * - Time: `O(n * log n) where n = array_size`.
+ *
+ * Compared to `qsort`, this is about 60-70% slower for large arrays. For small
+ * arrays (up to 16 elements), it's about 50% faster than `qsort`.
+ *
+ * @param[in,out] arr An array of type T.
+ * @param arr_size Number of elements in @p arr (count, not byte size).
+ * @param[in] object Comparator object.
+ * @param[in] funcs Callback struct for elements of type T.
+ */
+non_null()
+bool merge_sort(void *arr, uint32_t arr_size, const void *object, const Sort_Funcs *funcs);
+
+/**
+ * @brief Merge sort like above but with a pre-allocated buffer.
+ *
+ * This function is the same as `merge_sort` but uses a pre-allocated buffer
+ * for temporary storage. This can be useful if the caller wants to avoid
+ * dynamic memory allocation.
+ *
+ * This function is 1-2% faster than `merge_sort` for small arrays up to 1000
+ * elements, and about 5-10% faster for large arrays (2000+ elements).
+ *
+ * The main upside is that `alloc` and `delete` callbacks don't need to be
+ * implemented, and the caller can use a stack-allocated buffer.
+ *
+ * @param[in,out] arr An array of type T.
+ * @param arr_size Number of elements in @p arr (count, not byte size).
+ * @param[in,out] tmp A buffer of size `tmp_size` for temporary storage.
+ * @param tmp_size Number of elements in @p tmp (count, not byte size). Must be
+ * at least as large as `arr_size`.
+ * @param[in] object Comparator object.
+ * @param[in] funcs Callback struct for elements of type T.
+ */
+non_null()
+void merge_sort_with_buf(void *arr, uint32_t arr_size, void *tmp, uint32_t tmp_size, const void *object, const Sort_Funcs *funcs);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* C_TOXCORE_TOXCORE_SORT_H */
diff --git a/protocols/Tox/libtox/src/toxcore/timed_auth.c b/protocols/Tox/libtox/src/toxcore/timed_auth.c
index 875003257b..45afe0704a 100644
--- a/protocols/Tox/libtox/src/toxcore/timed_auth.c
+++ b/protocols/Tox/libtox/src/toxcore/timed_auth.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2019-2021 The TokTok team.
+ * Copyright © 2019-2025 The TokTok team.
*/
#include "timed_auth.h"
diff --git a/protocols/Tox/libtox/src/toxcore/timed_auth.h b/protocols/Tox/libtox/src/toxcore/timed_auth.h
index bb19570872..ccef4b305e 100644
--- a/protocols/Tox/libtox/src/toxcore/timed_auth.h
+++ b/protocols/Tox/libtox/src/toxcore/timed_auth.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2019-2021 The TokTok team.
+ * Copyright © 2019-2025 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_TIMED_AUTH_H
#define C_TOXCORE_TOXCORE_TIMED_AUTH_H
diff --git a/protocols/Tox/libtox/src/toxcore/tox.c b/protocols/Tox/libtox/src/toxcore/tox.c
index 085fab2ec1..8e1b43903d 100644
--- a/protocols/Tox/libtox/src/toxcore/tox.c
+++ b/protocols/Tox/libtox/src/toxcore/tox.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -32,8 +32,10 @@
#include "network.h"
#include "onion_client.h"
#include "state.h"
+#include "tox_log_level.h"
+#include "tox_options.h"
#include "tox_private.h"
-#include "tox_struct.h"
+#include "tox_struct.h" // IWYU pragma: keep
#include "util.h"
#include "../toxencryptsave/defines.h"
@@ -79,7 +81,7 @@ struct Tox_Userdata {
static logger_cb tox_log_handler;
non_null(1, 3, 5, 6) nullable(7)
-static void tox_log_handler(void *context, Logger_Level level, const char *file, int line, const char *func,
+static void tox_log_handler(void *context, Logger_Level level, const char *file, uint32_t line, const char *func,
const char *message, void *userdata)
{
Tox *tox = (Tox *)context;
@@ -360,20 +362,22 @@ static void tox_conference_peer_list_changed_handler(Messenger *m, uint32_t conf
}
}
-static dht_get_nodes_response_cb tox_dht_get_nodes_response_handler;
+static dht_nodes_response_cb tox_dht_nodes_response_handler;
non_null(1, 2) nullable(3)
-static void tox_dht_get_nodes_response_handler(const DHT *dht, const Node_format *node, void *user_data)
+static void tox_dht_nodes_response_handler(const DHT *dht, const Node_format *node, void *user_data)
{
struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data;
- if (tox_data->tox->dht_get_nodes_response_callback == nullptr) {
+ if (tox_data->tox->dht_nodes_response_callback == nullptr) {
return;
}
Ip_Ntoa ip_str;
+ net_ip_ntoa(&node->ip_port.ip, &ip_str);
+
tox_unlock(tox_data->tox);
- tox_data->tox->dht_get_nodes_response_callback(
- tox_data->tox, node->public_key, net_ip_ntoa(&node->ip_port.ip, &ip_str), net_ntohs(node->ip_port.port),
+ tox_data->tox->dht_nodes_response_callback(
+ tox_data->tox, node->public_key, ip_str.buf, ip_str.length, net_ntohs(node->ip_port.port),
tox_data->user_data);
tox_lock(tox_data->tox);
}
@@ -524,7 +528,7 @@ static void tox_group_password_handler(const Messenger *m, uint32_t group_number
non_null(1, 5) nullable(8)
static void tox_group_message_handler(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id, unsigned int type,
- const uint8_t *message, size_t length, uint32_t message_id, void *user_data)
+ const uint8_t *message, size_t length, Tox_Group_Message_Id message_id, void *user_data)
{
struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data;
@@ -536,16 +540,16 @@ static void tox_group_message_handler(const Messenger *m, uint32_t group_number,
}
}
-non_null(1, 5) nullable(7)
+non_null(1, 5) nullable(8)
static void tox_group_private_message_handler(const Messenger *m, uint32_t group_number, GC_Peer_Id peer_id,
- unsigned int type, const uint8_t *message, size_t length, void *user_data)
+ unsigned int type, const uint8_t *message, size_t length, Tox_Group_Message_Id message_id, void *user_data)
{
struct Tox_Userdata *tox_data = (struct Tox_Userdata *)user_data;
if (tox_data->tox->group_private_message_callback != nullptr) {
tox_unlock(tox_data->tox);
tox_data->tox->group_private_message_callback(tox_data->tox, group_number, gc_peer_id_to_int(peer_id), (Tox_Message_Type)type, message,
- length, tox_data->user_data);
+ length, message_id, tox_data->user_data);
tox_lock(tox_data->tox);
}
}
@@ -712,7 +716,8 @@ static int tox_load(Tox *tox, const uint8_t *data, uint32_t length)
length - cookie_len, STATE_COOKIE_TYPE);
}
-Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
+nullable(1, 2, 3)
+static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error, const Tox_System *sys)
{
struct Tox_Options *default_options = nullptr;
@@ -736,7 +741,6 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
const struct Tox_Options *const opts = options != nullptr ? options : default_options;
assert(opts != nullptr);
- const Tox_System *sys = tox_options_get_operating_system(opts);
const Tox_System default_system = tox_default_system();
if (sys == nullptr) {
@@ -752,6 +756,8 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
Messenger_Options m_options = {false};
+ m_options.dns_enabled = !tox_options_get_experimental_disable_dns(opts);
+
bool load_savedata_sk = false;
bool load_savedata_tox = false;
@@ -855,9 +861,10 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
}
const char *const proxy_host = tox_options_get_proxy_host(opts);
+ const bool dns_enabled = !tox_options_get_experimental_disable_dns(opts);
if (proxy_host == nullptr
- || !addr_resolve_or_parse_ip(tox->sys.ns, proxy_host, &m_options.proxy_info.ip_port.ip, nullptr)) {
+ || !addr_resolve_or_parse_ip(tox->sys.ns, tox->sys.mem, proxy_host, &m_options.proxy_info.ip_port.ip, nullptr, dns_enabled)) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_HOST);
// TODO(irungentoo): TOX_ERR_NEW_PROXY_NOT_FOUND if domain.
mem_delete(sys->mem, tox);
@@ -926,7 +933,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
return nullptr;
}
- tox->m->conferences_object = new_groupchats(tox->mono_time, tox->m);
+ tox->m->conferences_object = new_groupchats(tox->mono_time, sys->mem, tox->m);
if (tox->m->conferences_object == nullptr) {
kill_messenger(tox->m);
@@ -983,7 +990,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
callback_file_reqchunk(tox->m, tox_file_chunk_request_handler);
callback_file_sendrequest(tox->m, tox_file_recv_handler);
callback_file_data(tox->m, tox_file_recv_chunk_handler);
- dht_callback_get_nodes_response(tox->m->dht, tox_dht_get_nodes_response_handler);
+ dht_callback_nodes_response(tox->m->dht, tox_dht_nodes_response_handler);
g_callback_group_invite(tox->m->conferences_object, tox_conference_invite_handler);
g_callback_group_connected(tox->m->conferences_object, tox_conference_connected_handler);
g_callback_group_message(tox->m->conferences_object, tox_conference_message_handler);
@@ -1020,6 +1027,37 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
return tox;
}
+Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
+{
+ return tox_new_system(options, error, nullptr);
+}
+
+Tox *tox_new_testing(const Tox_Options *options, Tox_Err_New *error, const Tox_Options_Testing *testing, Tox_Err_New_Testing *testing_error)
+{
+ if (testing == nullptr) {
+ SET_ERROR_PARAMETER(error, TOX_ERR_NEW_NULL);
+ SET_ERROR_PARAMETER(testing_error, TOX_ERR_NEW_TESTING_NULL);
+ return nullptr;
+ }
+
+ if (testing->operating_system == nullptr) {
+ SET_ERROR_PARAMETER(error, TOX_ERR_NEW_NULL);
+ SET_ERROR_PARAMETER(testing_error, TOX_ERR_NEW_TESTING_NULL);
+ return nullptr;
+ }
+
+ const Tox_System *sys = testing->operating_system;
+
+ if (sys->rng == nullptr || sys->ns == nullptr || sys->mem == nullptr) {
+ SET_ERROR_PARAMETER(error, TOX_ERR_NEW_NULL);
+ SET_ERROR_PARAMETER(testing_error, TOX_ERR_NEW_TESTING_NULL);
+ return nullptr;
+ }
+
+ SET_ERROR_PARAMETER(testing_error, TOX_ERR_NEW_TESTING_OK);
+ return tox_new_system(options, error, sys);
+}
+
void tox_kill(Tox *tox)
{
if (tox == nullptr) {
@@ -1027,7 +1065,7 @@ void tox_kill(Tox *tox)
}
tox_lock(tox);
- LOGGER_ASSERT(tox->m->log, tox->m->msi_packet == nullptr, "Attempted to kill tox while toxav is still alive");
+ LOGGER_ASSERT(tox->m->log, tox->toxav_object == nullptr, "Attempted to kill tox while toxav is still alive");
kill_groupchats(tox->m->conferences_object);
kill_messenger(tox->m);
mono_time_free(tox->sys.mem, tox->mono_time);
@@ -1108,7 +1146,7 @@ static int32_t resolve_bootstrap_node(Tox *tox, const char *host, uint16_t port,
return -1;
}
- const int32_t count = net_getipport(tox->sys.mem, host, root, TOX_SOCK_DGRAM);
+ const int32_t count = net_getipport(tox->sys.ns, tox->sys.mem, host, root, TOX_SOCK_DGRAM, tox->m->options.dns_enabled);
if (count < 1) {
LOGGER_DEBUG(tox->m->log, "could not resolve bootstrap node '%s'", host);
@@ -2520,6 +2558,12 @@ uint32_t tox_conference_join(Tox *tox, uint32_t friend_number, const uint8_t *co
Tox_Err_Conference_Join *error)
{
assert(tox != nullptr);
+
+ if (cookie == nullptr) {
+ SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_JOIN_NULL);
+ return UINT32_MAX;
+ }
+
tox_lock(tox);
const int ret = join_groupchat(tox->m->conferences_object, friend_number, GROUPCHAT_TYPE_TEXT, cookie, length);
tox_unlock(tox);
@@ -3209,7 +3253,7 @@ bool tox_group_reconnect(Tox *tox, uint32_t group_number, Tox_Err_Group_Reconnec
return false;
}
- const int ret = gc_rejoin_group(tox->m->group_handler, chat);
+ const int ret = gc_rejoin_group(tox->m->group_handler, chat, nullptr, 0);
tox_unlock(tox);
switch (ret) {
@@ -3688,7 +3732,7 @@ bool tox_group_set_topic(Tox *tox, uint32_t group_number, const uint8_t *topic,
return false;
}
-size_t tox_group_get_topic_size(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Queries *error)
+size_t tox_group_get_topic_size(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Query *error)
{
assert(tox != nullptr);
@@ -3696,12 +3740,12 @@ size_t tox_group_get_topic_size(const Tox *tox, uint32_t group_number, Tox_Err_G
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
if (chat == nullptr) {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND);
tox_unlock(tox);
return -1;
}
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK);
const size_t ret = gc_get_topic_size(chat);
tox_unlock(tox);
@@ -3709,7 +3753,7 @@ size_t tox_group_get_topic_size(const Tox *tox, uint32_t group_number, Tox_Err_G
return ret;
}
-bool tox_group_get_topic(const Tox *tox, uint32_t group_number, uint8_t *topic, Tox_Err_Group_State_Queries *error)
+bool tox_group_get_topic(const Tox *tox, uint32_t group_number, uint8_t *topic, Tox_Err_Group_State_Query *error)
{
assert(tox != nullptr);
@@ -3717,7 +3761,7 @@ bool tox_group_get_topic(const Tox *tox, uint32_t group_number, uint8_t *topic,
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
if (chat == nullptr) {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND);
tox_unlock(tox);
return false;
}
@@ -3725,11 +3769,11 @@ bool tox_group_get_topic(const Tox *tox, uint32_t group_number, uint8_t *topic,
gc_get_topic(chat, topic);
tox_unlock(tox);
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK);
return true;
}
-size_t tox_group_get_name_size(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Queries *error)
+size_t tox_group_get_name_size(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Query *error)
{
assert(tox != nullptr);
@@ -3737,12 +3781,12 @@ size_t tox_group_get_name_size(const Tox *tox, uint32_t group_number, Tox_Err_Gr
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
if (chat == nullptr) {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND);
tox_unlock(tox);
return -1;
}
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK);
const size_t ret = gc_get_group_name_size(chat);
tox_unlock(tox);
@@ -3750,7 +3794,7 @@ size_t tox_group_get_name_size(const Tox *tox, uint32_t group_number, Tox_Err_Gr
return ret;
}
-bool tox_group_get_name(const Tox *tox, uint32_t group_number, uint8_t *name, Tox_Err_Group_State_Queries *error)
+bool tox_group_get_name(const Tox *tox, uint32_t group_number, uint8_t *name, Tox_Err_Group_State_Query *error)
{
assert(tox != nullptr);
@@ -3758,7 +3802,7 @@ bool tox_group_get_name(const Tox *tox, uint32_t group_number, uint8_t *name, To
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
if (chat == nullptr) {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND);
tox_unlock(tox);
return false;
}
@@ -3766,12 +3810,12 @@ bool tox_group_get_name(const Tox *tox, uint32_t group_number, uint8_t *name, To
gc_get_group_name(chat, name);
tox_unlock(tox);
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK);
return true;
}
-bool tox_group_get_chat_id(const Tox *tox, uint32_t group_number, uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE], Tox_Err_Group_State_Queries *error)
+bool tox_group_get_chat_id(const Tox *tox, uint32_t group_number, uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE], Tox_Err_Group_State_Query *error)
{
assert(tox != nullptr);
@@ -3779,12 +3823,12 @@ bool tox_group_get_chat_id(const Tox *tox, uint32_t group_number, uint8_t chat_i
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
if (chat == nullptr) {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND);
tox_unlock(tox);
return false;
}
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK);
gc_get_chat_id(chat, chat_id);
tox_unlock(tox);
@@ -3803,7 +3847,7 @@ uint32_t tox_group_get_number_groups(const Tox *tox)
}
Tox_Group_Privacy_State tox_group_get_privacy_state(const Tox *tox, uint32_t group_number,
- Tox_Err_Group_State_Queries *error)
+ Tox_Err_Group_State_Query *error)
{
assert(tox != nullptr);
@@ -3811,12 +3855,12 @@ Tox_Group_Privacy_State tox_group_get_privacy_state(const Tox *tox, uint32_t gro
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
if (chat == nullptr) {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND);
tox_unlock(tox);
return (Tox_Group_Privacy_State) - 1;
}
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK);
const uint8_t state = gc_get_privacy_state(chat);
tox_unlock(tox);
@@ -3824,7 +3868,7 @@ Tox_Group_Privacy_State tox_group_get_privacy_state(const Tox *tox, uint32_t gro
return (Tox_Group_Privacy_State)state;
}
-Tox_Group_Topic_Lock tox_group_get_topic_lock(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Queries *error)
+Tox_Group_Topic_Lock tox_group_get_topic_lock(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Query *error)
{
assert(tox != nullptr);
@@ -3832,12 +3876,12 @@ Tox_Group_Topic_Lock tox_group_get_topic_lock(const Tox *tox, uint32_t group_num
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
if (chat == nullptr) {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND);
tox_unlock(tox);
return (Tox_Group_Topic_Lock) - 1;
}
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK);
const Group_Topic_Lock topic_lock = gc_get_topic_lock_state(chat);
tox_unlock(tox);
@@ -3846,7 +3890,7 @@ Tox_Group_Topic_Lock tox_group_get_topic_lock(const Tox *tox, uint32_t group_num
}
Tox_Group_Voice_State tox_group_get_voice_state(const Tox *tox, uint32_t group_number,
- Tox_Err_Group_State_Queries *error)
+ Tox_Err_Group_State_Query *error)
{
assert(tox != nullptr);
@@ -3854,12 +3898,12 @@ Tox_Group_Voice_State tox_group_get_voice_state(const Tox *tox, uint32_t group_n
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
if (chat == nullptr) {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND);
tox_unlock(tox);
return (Tox_Group_Voice_State) - 1;
}
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK);
const Group_Voice_State voice_state = gc_get_voice_state(chat);
tox_unlock(tox);
@@ -3867,7 +3911,7 @@ Tox_Group_Voice_State tox_group_get_voice_state(const Tox *tox, uint32_t group_n
return (Tox_Group_Voice_State)voice_state;
}
-uint16_t tox_group_get_peer_limit(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Queries *error)
+uint16_t tox_group_get_peer_limit(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Query *error)
{
assert(tox != nullptr);
@@ -3875,12 +3919,12 @@ uint16_t tox_group_get_peer_limit(const Tox *tox, uint32_t group_number, Tox_Err
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
if (chat == nullptr) {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND);
tox_unlock(tox);
return -1;
}
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK);
const uint16_t ret = gc_get_max_peers(chat);
tox_unlock(tox);
@@ -3888,7 +3932,7 @@ uint16_t tox_group_get_peer_limit(const Tox *tox, uint32_t group_number, Tox_Err
return ret;
}
-size_t tox_group_get_password_size(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Queries *error)
+size_t tox_group_get_password_size(const Tox *tox, uint32_t group_number, Tox_Err_Group_State_Query *error)
{
assert(tox != nullptr);
@@ -3896,12 +3940,12 @@ size_t tox_group_get_password_size(const Tox *tox, uint32_t group_number, Tox_Er
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
if (chat == nullptr) {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND);
tox_unlock(tox);
return -1;
}
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK);
const size_t ret = gc_get_password_size(chat);
tox_unlock(tox);
@@ -3910,7 +3954,7 @@ size_t tox_group_get_password_size(const Tox *tox, uint32_t group_number, Tox_Er
}
bool tox_group_get_password(const Tox *tox, uint32_t group_number, uint8_t *password,
- Tox_Err_Group_State_Queries *error)
+ Tox_Err_Group_State_Query *error)
{
assert(tox != nullptr);
@@ -3918,12 +3962,12 @@ bool tox_group_get_password(const Tox *tox, uint32_t group_number, uint8_t *pass
const GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
if (chat == nullptr) {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND);
tox_unlock(tox);
return false;
}
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERIES_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_STATE_QUERY_OK);
gc_get_password(chat, password);
tox_unlock(tox);
@@ -3932,7 +3976,7 @@ bool tox_group_get_password(const Tox *tox, uint32_t group_number, uint8_t *pass
}
Tox_Group_Message_Id tox_group_send_message(
- const Tox *tox, uint32_t group_number, Tox_Message_Type type, const uint8_t *message,
+ const Tox *tox, uint32_t group_number, Tox_Message_Type message_type, const uint8_t *message,
size_t length, Tox_Err_Group_Send_Message *error)
{
assert(tox != nullptr);
@@ -3953,7 +3997,7 @@ Tox_Group_Message_Id tox_group_send_message(
}
uint32_t message_id = 0;
- const int ret = gc_send_message(chat, message, length, type, &message_id);
+ const int ret = gc_send_message(chat, message, length, message_type, &message_id);
tox_unlock(tox);
switch (ret) {
@@ -3994,8 +4038,8 @@ Tox_Group_Message_Id tox_group_send_message(
return -1;
}
-bool tox_group_send_private_message(const Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Message_Type type,
- const uint8_t *message, size_t length, Tox_Err_Group_Send_Private_Message *error)
+Tox_Group_Message_Id tox_group_send_private_message(const Tox *tox, uint32_t group_number, uint32_t peer_id,
+ Tox_Message_Type message_type, const uint8_t *message, size_t length, Tox_Err_Group_Send_Private_Message *error)
{
assert(tox != nullptr);
@@ -4005,59 +4049,60 @@ bool tox_group_send_private_message(const Tox *tox, uint32_t group_number, uint3
if (chat == nullptr) {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_GROUP_NOT_FOUND);
tox_unlock(tox);
- return false;
+ return -1;
}
if (chat->connection_state == CS_DISCONNECTED) {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_DISCONNECTED);
tox_unlock(tox);
- return false;
+ return -1;
}
- const int ret = gc_send_private_message(chat, gc_peer_id_from_int(peer_id), type, message, length);
+ uint32_t message_id = 0;
+ const int ret = gc_send_private_message(chat, gc_peer_id_from_int(peer_id), message_type, message, length, &message_id);
tox_unlock(tox);
switch (ret) {
case 0: {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_OK);
- return true;
+ return message_id;
}
case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_TOO_LONG);
- return false;
+ return -1;
}
case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_EMPTY);
- return false;
+ return -1;
}
case -3: {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_PEER_NOT_FOUND);
- return false;
+ return -1;
}
case -4: {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_BAD_TYPE);
- return false;
+ return -1;
}
case -5: {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_PERMISSIONS);
- return false;
+ return -1;
}
case -6: {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_FAIL_SEND);
- return false;
+ return -1;
}
}
/* can't happen */
LOGGER_FATAL(tox->m->log, "impossible return value: %d", ret);
- return false;
+ return -1;
}
bool tox_group_send_custom_packet(const Tox *tox, uint32_t group_number, bool lossless, const uint8_t *data,
@@ -4100,11 +4145,6 @@ bool tox_group_send_custom_packet(const Tox *tox, uint32_t group_number, bool lo
}
case -3: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_CUSTOM_PACKET_PERMISSIONS);
- return false;
- }
-
- case -4: {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_CUSTOM_PACKET_FAIL_SEND);
return false;
}
@@ -4162,11 +4202,6 @@ bool tox_group_send_custom_private_packet(const Tox *tox, uint32_t group_number,
}
case -4: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_PERMISSIONS);
- return false;
- }
-
- case -5: {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_FAIL_SEND);
return false;
}
@@ -4241,6 +4276,11 @@ uint32_t tox_group_invite_accept(Tox *tox, uint32_t friend_number, const uint8_t
{
assert(tox != nullptr);
+ if (invite_data == nullptr || name == nullptr) {
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_INVITE_ACCEPT_NULL);
+ return UINT32_MAX;
+ }
+
tox_lock(tox);
const int ret = gc_accept_invite(tox->m->group_handler, friend_number, invite_data, length, name, name_length, password,
password_length);
@@ -4278,7 +4318,7 @@ uint32_t tox_group_invite_accept(Tox *tox, uint32_t friend_number, const uint8_t
}
case -6: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_INVITE_ACCEPT_CORE);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_INVITE_ACCEPT_FRIEND_NOT_FOUND);
return UINT32_MAX;
}
@@ -4294,8 +4334,8 @@ uint32_t tox_group_invite_accept(Tox *tox, uint32_t friend_number, const uint8_t
return UINT32_MAX;
}
-bool tox_group_founder_set_password(Tox *tox, uint32_t group_number, const uint8_t *password, size_t length,
- Tox_Err_Group_Founder_Set_Password *error)
+bool tox_group_set_password(Tox *tox, uint32_t group_number, const uint8_t *password, size_t length,
+ Tox_Err_Group_Set_Password *error)
{
assert(tox != nullptr);
@@ -4303,13 +4343,13 @@ bool tox_group_founder_set_password(Tox *tox, uint32_t group_number, const uint8
GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
if (chat == nullptr) {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PASSWORD_GROUP_NOT_FOUND);
tox_unlock(tox);
return false;
}
if (chat->connection_state == CS_DISCONNECTED) {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_DISCONNECTED);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PASSWORD_DISCONNECTED);
tox_unlock(tox);
return false;
}
@@ -4319,27 +4359,27 @@ bool tox_group_founder_set_password(Tox *tox, uint32_t group_number, const uint8
switch (ret) {
case 0: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PASSWORD_OK);
return true;
}
case -1: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_PERMISSIONS);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PASSWORD_PERMISSIONS);
return false;
}
case -2: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_TOO_LONG);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PASSWORD_TOO_LONG);
return false;
}
case -3: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_FAIL_SEND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PASSWORD_FAIL_SEND);
return false;
}
case -4: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_MALLOC);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PASSWORD_MALLOC);
return false;
}
}
@@ -4350,8 +4390,8 @@ bool tox_group_founder_set_password(Tox *tox, uint32_t group_number, const uint8
return false;
}
-bool tox_group_founder_set_privacy_state(Tox *tox, uint32_t group_number, Tox_Group_Privacy_State privacy_state,
- Tox_Err_Group_Founder_Set_Privacy_State *error)
+bool tox_group_set_privacy_state(Tox *tox, uint32_t group_number, Tox_Group_Privacy_State privacy_state,
+ Tox_Err_Group_Set_Privacy_State *error)
{
assert(tox != nullptr);
@@ -4361,32 +4401,32 @@ bool tox_group_founder_set_privacy_state(Tox *tox, uint32_t group_number, Tox_Gr
switch (ret) {
case 0: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PRIVACY_STATE_OK);
return true;
}
case -1: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PRIVACY_STATE_GROUP_NOT_FOUND);
return false;
}
case -2: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_PERMISSIONS);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PRIVACY_STATE_PERMISSIONS);
return false;
}
case -3: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_DISCONNECTED);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PRIVACY_STATE_DISCONNECTED);
return false;
}
case -4: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SET);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SET);
return false;
}
case -5: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SEND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SEND);
return false;
}
}
@@ -4397,8 +4437,8 @@ bool tox_group_founder_set_privacy_state(Tox *tox, uint32_t group_number, Tox_Gr
return false;
}
-bool tox_group_founder_set_topic_lock(Tox *tox, uint32_t group_number, Tox_Group_Topic_Lock topic_lock,
- Tox_Err_Group_Founder_Set_Topic_Lock *error)
+bool tox_group_set_topic_lock(Tox *tox, uint32_t group_number, Tox_Group_Topic_Lock topic_lock,
+ Tox_Err_Group_Set_Topic_Lock *error)
{
assert(tox != nullptr);
@@ -4408,37 +4448,37 @@ bool tox_group_founder_set_topic_lock(Tox *tox, uint32_t group_number, Tox_Group
switch (ret) {
case 0: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_TOPIC_LOCK_OK);
return true;
}
case -1: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_TOPIC_LOCK_GROUP_NOT_FOUND);
return false;
}
case -2: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_INVALID);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_TOPIC_LOCK_INVALID);
return false;
}
case -3: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_PERMISSIONS);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_TOPIC_LOCK_PERMISSIONS);
return false;
}
case -4: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_DISCONNECTED);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_TOPIC_LOCK_DISCONNECTED);
return false;
}
case -5: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SET);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SET);
return false;
}
case -6: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SEND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SEND);
return false;
}
}
@@ -4449,8 +4489,8 @@ bool tox_group_founder_set_topic_lock(Tox *tox, uint32_t group_number, Tox_Group
return false;
}
-bool tox_group_founder_set_voice_state(Tox *tox, uint32_t group_number, Tox_Group_Voice_State voice_state,
- Tox_Err_Group_Founder_Set_Voice_State *error)
+bool tox_group_set_voice_state(Tox *tox, uint32_t group_number, Tox_Group_Voice_State voice_state,
+ Tox_Err_Group_Set_Voice_State *error)
{
assert(tox != nullptr);
@@ -4460,32 +4500,32 @@ bool tox_group_founder_set_voice_state(Tox *tox, uint32_t group_number, Tox_Grou
switch (ret) {
case 0: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_VOICE_STATE_OK);
return true;
}
case -1: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_VOICE_STATE_GROUP_NOT_FOUND);
return false;
}
case -2: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_PERMISSIONS);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_VOICE_STATE_PERMISSIONS);
return false;
}
case -3: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_DISCONNECTED);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_VOICE_STATE_DISCONNECTED);
return false;
}
case -4: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SET);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SET);
return false;
}
case -5: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SEND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SEND);
return false;
}
}
@@ -4496,8 +4536,8 @@ bool tox_group_founder_set_voice_state(Tox *tox, uint32_t group_number, Tox_Grou
return false;
}
-bool tox_group_founder_set_peer_limit(Tox *tox, uint32_t group_number, uint16_t peer_limit,
- Tox_Err_Group_Founder_Set_Peer_Limit *error)
+bool tox_group_set_peer_limit(Tox *tox, uint32_t group_number, uint16_t peer_limit,
+ Tox_Err_Group_Set_Peer_Limit *error)
{
assert(tox != nullptr);
@@ -4505,13 +4545,13 @@ bool tox_group_founder_set_peer_limit(Tox *tox, uint32_t group_number, uint16_t
GC_Chat *chat = gc_get_group(tox->m->group_handler, group_number);
if (chat == nullptr) {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PEER_LIMIT_GROUP_NOT_FOUND);
tox_unlock(tox);
return false;
}
if (chat->connection_state == CS_DISCONNECTED) {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_DISCONNECTED);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PEER_LIMIT_DISCONNECTED);
tox_unlock(tox);
return false;
}
@@ -4521,22 +4561,22 @@ bool tox_group_founder_set_peer_limit(Tox *tox, uint32_t group_number, uint16_t
switch (ret) {
case 0: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PEER_LIMIT_OK);
return true;
}
case -1: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_PERMISSIONS);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PEER_LIMIT_PERMISSIONS);
return false;
}
case -2: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SET);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SET);
return false;
}
case -3: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SEND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SEND);
return false;
}
}
@@ -4587,8 +4627,8 @@ bool tox_group_set_ignore(Tox *tox, uint32_t group_number, uint32_t peer_id, boo
return false;
}
-bool tox_group_mod_set_role(Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Group_Role role,
- Tox_Err_Group_Mod_Set_Role *error)
+bool tox_group_set_role(Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Group_Role role,
+ Tox_Err_Group_Set_Role *error)
{
assert(tox != nullptr);
@@ -4598,37 +4638,37 @@ bool tox_group_mod_set_role(Tox *tox, uint32_t group_number, uint32_t peer_id, T
switch (ret) {
case 0: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_SET_ROLE_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_ROLE_OK);
return true;
}
case -1: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_SET_ROLE_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_ROLE_GROUP_NOT_FOUND);
return false;
}
case -2: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_ROLE_PEER_NOT_FOUND);
return false;
}
case -3: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_ROLE_PERMISSIONS);
return false;
}
case -4: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_SET_ROLE_ASSIGNMENT);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_ROLE_ASSIGNMENT);
return false;
}
case -5: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_SET_ROLE_FAIL_ACTION);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_ROLE_FAIL_ACTION);
return false;
}
case -6: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_SET_ROLE_SELF);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SET_ROLE_SELF);
return false;
}
}
@@ -4639,8 +4679,8 @@ bool tox_group_mod_set_role(Tox *tox, uint32_t group_number, uint32_t peer_id, T
return false;
}
-bool tox_group_mod_kick_peer(const Tox *tox, uint32_t group_number, uint32_t peer_id,
- Tox_Err_Group_Mod_Kick_Peer *error)
+bool tox_group_kick_peer(const Tox *tox, uint32_t group_number, uint32_t peer_id,
+ Tox_Err_Group_Kick_Peer *error)
{
assert(tox != nullptr);
@@ -4650,37 +4690,37 @@ bool tox_group_mod_kick_peer(const Tox *tox, uint32_t group_number, uint32_t pee
switch (ret) {
case 0: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_KICK_PEER_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_KICK_PEER_OK);
return true;
}
case -1: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_KICK_PEER_GROUP_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_KICK_PEER_GROUP_NOT_FOUND);
return false;
}
case -2: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_KICK_PEER_PEER_NOT_FOUND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_KICK_PEER_PEER_NOT_FOUND);
return false;
}
case -3: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_KICK_PEER_PERMISSIONS);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_KICK_PEER_PERMISSIONS);
return false;
}
case -4: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_ACTION);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_KICK_PEER_FAIL_ACTION);
return false;
}
case -5: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_SEND);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_KICK_PEER_FAIL_SEND);
return false;
}
case -6: {
- SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_MOD_KICK_PEER_SELF);
+ SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_KICK_PEER_SELF);
return false;
}
}
diff --git a/protocols/Tox/libtox/src/toxcore/tox.h b/protocols/Tox/libtox/src/toxcore/tox.h
index fa887fc779..f44b8201ac 100644
--- a/protocols/Tox/libtox/src/toxcore/tox.h
+++ b/protocols/Tox/libtox/src/toxcore/tox.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -25,9 +25,8 @@
* could not perform any operation, because one of the required parameters was
* NULL. Some functions operate correctly or are defined as effectless on NULL.
*
- * Some functions additionally return a value outside their
- * return type domain, or a bool containing true on success and false on
- * failure.
+ * Some functions additionally return a value outside their return type domain,
+ * or a bool containing true on success and false on failure.
*
* All functions that take a Tox instance pointer will cause undefined behaviour
* when passed a NULL Tox pointer.
@@ -52,17 +51,9 @@
* event listeners, it needs to implement the dispatch functionality itself.
*
* The last argument to a callback is the user data pointer. It is passed from
- * tox_iterate to each callback in sequence.
- *
- * The user data pointer is never stored or dereferenced by any library code, so
- * can be any pointer, including NULL. Callbacks must all operate on the same
- * object type. In the apidsl code (tox.in.h), this is denoted with `any`. The
- * `any` in tox_iterate must be the same `any` as in all callbacks. In C,
- * lacking parametric polymorphism, this is a pointer to void.
- *
- * Old style callbacks that are registered together with a user data pointer
- * receive that pointer as argument when they are called. They can each have
- * their own user data pointer of their own type.
+ * tox_iterate to each callback in sequence. The user data pointer is never
+ * stored or dereferenced by any library code, so can be any pointer, including
+ * NULL.
*
* @section threading Threading implications
*
@@ -96,6 +87,13 @@
* If any other thread calls tox_self_set_name while this thread is allocating
* memory, the length may have become invalid, and the call to
* tox_self_get_name may cause undefined behaviour.
+ *
+ * @section deprecations
+ *
+ * Some functions and types are deprecated. We recommend compiling with
+ * `-DTOX_HIDE_DEPRECATED` to hide them. They will be removed in the next major
+ * version of Tox (and since we're in major version 0, that means the next
+ * minor version).
*/
#ifndef C_TOXCORE_TOXCORE_TOX_H
#define C_TOXCORE_TOXCORE_TOX_H
@@ -104,14 +102,14 @@
#include <stddef.h>
#include <stdint.h>
+#include "tox_options.h" // IWYU pragma: export
+
#ifdef __cplusplus
extern "C" {
#endif
/** @{ @namespace tox */
-#ifndef TOX_DEFINED
-#define TOX_DEFINED
/**
* @brief The Tox instance type.
*
@@ -122,7 +120,6 @@ extern "C" {
* limiting factor is the number of usable ports on a device.
*/
typedef struct Tox Tox;
-#endif /* TOX_DEFINED */
/** @{
* @name API version
@@ -157,7 +154,7 @@ uint32_t tox_version_minor(void);
* Incremented when bugfixes are applied without changing any functionality or
* API or ABI.
*/
-#define TOX_VERSION_PATCH 18
+#define TOX_VERSION_PATCH 21
uint32_t tox_version_patch(void);
@@ -206,7 +203,7 @@ bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch);
*
* The values of these are not part of the ABI. Prefer to use the function
* versions of them for code that should remain compatible with future versions
- * of toxcore.
+ * of the Tox library.
*/
/**
@@ -283,7 +280,7 @@ uint32_t tox_max_status_message_length(void);
*
* @deprecated The macro will be removed in 0.3.0. Use the function instead.
*/
-#define TOX_MAX_FRIEND_REQUEST_LENGTH 1016
+#define TOX_MAX_FRIEND_REQUEST_LENGTH 921
uint32_t tox_max_friend_request_length(void);
@@ -396,431 +393,6 @@ const char *tox_message_type_to_string(Tox_Message_Type value);
/** @} */
/** @{
- * @name Startup options
- */
-
-/**
- * @brief Type of proxy used to connect to TCP relays.
- */
-typedef enum Tox_Proxy_Type {
-
- /**
- * Don't use a proxy.
- */
- TOX_PROXY_TYPE_NONE,
-
- /**
- * HTTP proxy using CONNECT.
- */
- TOX_PROXY_TYPE_HTTP,
-
- /**
- * SOCKS proxy for simple socket pipes.
- */
- TOX_PROXY_TYPE_SOCKS5,
-
-} Tox_Proxy_Type;
-
-const char *tox_proxy_type_to_string(Tox_Proxy_Type value);
-
-/**
- * @brief Type of savedata to create the Tox instance from.
- */
-typedef enum Tox_Savedata_Type {
-
- /**
- * No savedata.
- */
- TOX_SAVEDATA_TYPE_NONE,
-
- /**
- * Savedata is one that was obtained from tox_get_savedata.
- */
- TOX_SAVEDATA_TYPE_TOX_SAVE,
-
- /**
- * Savedata is a secret key of length TOX_SECRET_KEY_SIZE.
- */
- TOX_SAVEDATA_TYPE_SECRET_KEY,
-
-} Tox_Savedata_Type;
-
-const char *tox_savedata_type_to_string(Tox_Savedata_Type value);
-
-/**
- * @brief Severity level of log messages.
- */
-typedef enum Tox_Log_Level {
-
- /**
- * Very detailed traces including all network activity.
- */
- TOX_LOG_LEVEL_TRACE,
-
- /**
- * Debug messages such as which port we bind to.
- */
- TOX_LOG_LEVEL_DEBUG,
-
- /**
- * Informational log messages such as video call status changes.
- */
- TOX_LOG_LEVEL_INFO,
-
- /**
- * Warnings about events_alloc inconsistency or logic errors.
- */
- TOX_LOG_LEVEL_WARNING,
-
- /**
- * Severe unexpected errors caused by external or events_alloc inconsistency.
- */
- TOX_LOG_LEVEL_ERROR,
-
-} Tox_Log_Level;
-
-const char *tox_log_level_to_string(Tox_Log_Level value);
-
-/**
- * @brief This event is triggered when the toxcore library logs an events_alloc message.
- *
- * This is mostly useful for debugging. This callback can be called from any
- * function, not just tox_iterate. This means the user data lifetime must at
- * least extend between registering and unregistering it or tox_kill.
- *
- * Other toxcore modules such as toxav may concurrently call this callback at
- * any time. Thus, user code must make sure it is equipped to handle concurrent
- * execution, e.g. by employing appropriate mutex locking.
- *
- * When using the experimental_thread_safety option, no Tox API functions can
- * be called from within the log callback.
- *
- * @param level The severity of the log message.
- * @param file The source file from which the message originated.
- * @param line The source line from which the message originated.
- * @param func The function from which the message originated.
- * @param message The log message.
- * @param user_data The user data pointer passed to tox_new in options.
- */
-typedef void tox_log_cb(Tox *tox, Tox_Log_Level level, const char *file, uint32_t line, const char *func,
- const char *message, void *user_data);
-
-/**
- * @brief Operating system functions used by Tox.
- *
- * This struct is opaque and generally shouldn't be used in clients, but in
- * combination with tox_private.h, it allows tests to inject non-IO (hermetic)
- * versions of low level network, RNG, and time keeping functions.
- */
-typedef struct Tox_System Tox_System;
-
-/**
- * @brief This struct contains all the startup options for Tox.
- *
- * You must tox_options_new to allocate an object of this type.
- *
- * WARNING: Although this struct happens to be visible in the API, it is
- * effectively private. Do not allocate this yourself or access members
- * directly, as it *will* break binary compatibility frequently.
- *
- * @deprecated The memory layout of this struct (size, alignment, and field
- * order) is not part of the ABI. To remain compatible, prefer to use
- * tox_options_new to allocate the object and accessor functions to set the
- * members. The struct will become opaque (i.e. the definition will become
- * private) in v0.3.0.
- */
-typedef struct Tox_Options Tox_Options;
-struct Tox_Options {
-
- /**
- * The type of socket to create.
- *
- * If this is set to false, an IPv4 socket is created, which subsequently
- * only allows IPv4 communication.
- * If it is set to true, an IPv6 socket is created, allowing both IPv4 and
- * IPv6 communication.
- */
- bool ipv6_enabled;
-
- /**
- * Enable the use of UDP communication when available.
- *
- * Setting this to false will force Tox to use TCP only. Communications will
- * need to be relayed through a TCP relay node, potentially slowing them down.
- *
- * If a proxy is enabled, UDP will be disabled if either toxcore or the
- * proxy don't support proxying UDP messages.
- */
- bool udp_enabled;
-
- /**
- * Enable local network peer discovery.
- *
- * Disabling this will cause Tox to not look for peers on the local network.
- */
- bool local_discovery_enabled;
-
- /**
- * Enable storing DHT announcements and forwarding corresponding requests.
- *
- * Disabling this will cause Tox to ignore the relevant packets.
- */
- bool dht_announcements_enabled;
-
- /**
- * Pass communications through a proxy.
- */
- Tox_Proxy_Type proxy_type;
-
- /**
- * The IP address or DNS name of the proxy to be used.
- *
- * If used, this must be non-NULL and be a valid DNS name. The name must not
- * exceed TOX_MAX_HOSTNAME_LENGTH characters, and be in a NUL-terminated C string
- * format (TOX_MAX_HOSTNAME_LENGTH includes the NUL byte).
- *
- * This member is ignored (it can be NULL) if proxy_type is TOX_PROXY_TYPE_NONE.
- *
- * The data pointed at by this member is owned by the user, so must
- * outlive the options object.
- */
- const char *proxy_host;
-
- /**
- * The port to use to connect to the proxy server.
- *
- * Ports must be in the range (1, 65535). The value is ignored if
- * proxy_type is TOX_PROXY_TYPE_NONE.
- */
- uint16_t proxy_port;
-
- /**
- * The start port of the inclusive port range to attempt to use.
- *
- * If both start_port and end_port are 0, the default port range will be
- * used: `[33445, 33545]`.
- *
- * If either start_port or end_port is 0 while the other is non-zero, the
- * non-zero port will be the only port in the range.
- *
- * Having start_port > end_port will yield the same behavior as if start_port
- * and end_port were swapped.
- */
- uint16_t start_port;
-
- /**
- * The end port of the inclusive port range to attempt to use.
- */
- uint16_t end_port;
-
- /**
- * The port to use for the TCP server (relay). If 0, the TCP server is
- * disabled.
- *
- * Enabling it is not required for Tox to function properly.
- *
- * When enabled, your Tox instance can act as a TCP relay for other Tox
- * instance. This leads to increased traffic, thus when writing a client
- * it is recommended to enable TCP server only if the user has an option
- * to disable it.
- */
- uint16_t tcp_port;
-
- /**
- * Enables or disables UDP hole-punching in toxcore. (Default: enabled).
- */
- bool hole_punching_enabled;
-
- /**
- * The type of savedata to load from.
- */
- Tox_Savedata_Type savedata_type;
-
- /**
- * The savedata.
- *
- * The data pointed at by this member is owned by the user, so must
- * outlive the options object.
- */
- const uint8_t *savedata_data;
-
- /**
- * The length of the savedata.
- */
- size_t savedata_length;
-
- /**
- * Logging callback for the new tox instance.
- */
- tox_log_cb *log_callback;
-
- /**
- * User data pointer passed to the logging callback.
- */
- void *log_user_data;
-
- /**
- * These options are experimental, so avoid writing code that depends on
- * them. Options marked "experimental" may change their behaviour or go away
- * entirely in the future, or may be renamed to something non-experimental
- * if they become part of the supported API.
- */
- /**
- * Make public API functions thread-safe using a per-instance lock.
- *
- * Default: false.
- */
- bool experimental_thread_safety;
-
- /**
- * Low level operating system functionality such as send/recv, random
- * number generation, and memory allocation.
- */
- const Tox_System *operating_system;
-
- /**
- * Enable saving DHT-based group chats to Tox save data (via `tox_get_savedata`).
- * This format will change in the future, so don't rely on it.
- *
- * As an alternative, clients can save the group chat ID in client-owned
- * savedata. Then, when the client starts, it can use `tox_group_join`
- * with the saved chat ID to recreate the group chat.
- *
- * Default: false.
- */
- bool experimental_groups_persistence;
-};
-
-bool tox_options_get_ipv6_enabled(const Tox_Options *options);
-
-void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled);
-
-bool tox_options_get_udp_enabled(const Tox_Options *options);
-
-void tox_options_set_udp_enabled(Tox_Options *options, bool udp_enabled);
-
-bool tox_options_get_local_discovery_enabled(const Tox_Options *options);
-
-void tox_options_set_local_discovery_enabled(Tox_Options *options, bool local_discovery_enabled);
-
-bool tox_options_get_dht_announcements_enabled(const Tox_Options *options);
-
-void tox_options_set_dht_announcements_enabled(Tox_Options *options, bool dht_announcements_enabled);
-
-Tox_Proxy_Type tox_options_get_proxy_type(const Tox_Options *options);
-
-void tox_options_set_proxy_type(Tox_Options *options, Tox_Proxy_Type proxy_type);
-
-const char *tox_options_get_proxy_host(const Tox_Options *options);
-
-void tox_options_set_proxy_host(Tox_Options *options, const char *proxy_host);
-
-uint16_t tox_options_get_proxy_port(const Tox_Options *options);
-
-void tox_options_set_proxy_port(Tox_Options *options, uint16_t proxy_port);
-
-uint16_t tox_options_get_start_port(const Tox_Options *options);
-
-void tox_options_set_start_port(Tox_Options *options, uint16_t start_port);
-
-uint16_t tox_options_get_end_port(const Tox_Options *options);
-
-void tox_options_set_end_port(Tox_Options *options, uint16_t end_port);
-
-uint16_t tox_options_get_tcp_port(const Tox_Options *options);
-
-void tox_options_set_tcp_port(Tox_Options *options, uint16_t tcp_port);
-
-bool tox_options_get_hole_punching_enabled(const Tox_Options *options);
-
-void tox_options_set_hole_punching_enabled(Tox_Options *options, bool hole_punching_enabled);
-
-Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options *options);
-
-void tox_options_set_savedata_type(Tox_Options *options, Tox_Savedata_Type savedata_type);
-
-const uint8_t *tox_options_get_savedata_data(const Tox_Options *options);
-
-void tox_options_set_savedata_data(Tox_Options *options, const uint8_t savedata_data[], size_t length);
-
-size_t tox_options_get_savedata_length(const Tox_Options *options);
-
-void tox_options_set_savedata_length(Tox_Options *options, size_t savedata_length);
-
-tox_log_cb *tox_options_get_log_callback(const Tox_Options *options);
-
-void tox_options_set_log_callback(Tox_Options *options, tox_log_cb *log_callback);
-
-void *tox_options_get_log_user_data(const Tox_Options *options);
-
-void tox_options_set_log_user_data(Tox_Options *options, void *log_user_data);
-
-bool tox_options_get_experimental_thread_safety(const Tox_Options *options);
-
-void tox_options_set_experimental_thread_safety(Tox_Options *options, bool experimental_thread_safety);
-
-const Tox_System *tox_options_get_operating_system(const Tox_Options *options);
-
-void tox_options_set_operating_system(Tox_Options *options, const Tox_System *operating_system);
-
-bool tox_options_get_experimental_groups_persistence(const Tox_Options *options);
-
-void tox_options_set_experimental_groups_persistence(Tox_Options *options, bool experimental_groups_persistence);
-
-/**
- * @brief Initialises a Tox_Options object with the default options.
- *
- * The result of this function is independent of the original options. All
- * values will be overwritten, no values will be read (so it is permissible
- * to pass an uninitialised object).
- *
- * If options is NULL, this function has no effect.
- *
- * @param options An options object to be filled with default options.
- */
-void tox_options_default(Tox_Options *options);
-
-typedef enum Tox_Err_Options_New {
-
- /**
- * The function returned successfully.
- */
- TOX_ERR_OPTIONS_NEW_OK,
-
- /**
- * The function failed to allocate enough memory for the options struct.
- */
- TOX_ERR_OPTIONS_NEW_MALLOC,
-
-} Tox_Err_Options_New;
-
-const char *tox_err_options_new_to_string(Tox_Err_Options_New value);
-
-/**
- * @brief Allocates a new Tox_Options object and initialises it with the default
- * options.
- *
- * This function can be used to preserve long term ABI compatibility by
- * giving the responsibility of allocation and deallocation to the Tox library.
- *
- * Objects returned from this function must be freed using the tox_options_free
- * function.
- *
- * @return A new Tox_Options object with default options or NULL on failure.
- */
-Tox_Options *tox_options_new(Tox_Err_Options_New *error);
-
-/**
- * @brief Releases all resources associated with an options objects.
- *
- * Passing a pointer that was not returned by tox_options_new results in
- * undefined behaviour.
- */
-void tox_options_free(Tox_Options *options);
-
-/** @} */
-
-/** @{
* @name Creation and destruction
*/
@@ -837,15 +409,16 @@ typedef enum Tox_Err_New {
TOX_ERR_NEW_NULL,
/**
- * The function was unable to allocate enough memory to store the events_alloc
- * structures for the Tox object.
+ * The function was unable to allocate enough memory to store the
+ * internal structures for the Tox object.
*/
TOX_ERR_NEW_MALLOC,
/**
* The function was unable to bind to a port. This may mean that all ports
* have already been bound, e.g. by other Tox instances, or it may mean
- * a permission error. You may be able to gather more information from errno.
+ * a permission error. You may be able to gather more information from
+ * errno.
*/
TOX_ERR_NEW_PORT_ALLOC,
@@ -913,7 +486,7 @@ Tox *tox_new(const Tox_Options *options, Tox_Err_New *error);
void tox_kill(Tox *tox);
/**
- * @brief Calculates the number of bytes required to store the tox instance with
+ * @brief Calculates the number of bytes required to store the Tox instance with
* tox_get_savedata.
*
* This function cannot fail. The result is always greater than 0.
@@ -923,11 +496,12 @@ void tox_kill(Tox *tox);
size_t tox_get_savedata_size(const Tox *tox);
/**
- * @brief Store all information associated with the tox instance to a byte array.
+ * @brief Store all information associated with the Tox instance to a byte
+ * array.
*
- * @param savedata A memory region large enough to store the tox instance
- * data. Call tox_get_savedata_size to find the number of bytes required. If this parameter
- * is NULL, this function has no effect.
+ * @param savedata A memory region large enough to store the Tox instance
+ * data. Call tox_get_savedata_size to find the number of bytes required. If
+ * this parameter is NULL, this function has no effect.
*/
void tox_get_savedata(const Tox *tox, uint8_t savedata[]);
@@ -966,7 +540,7 @@ typedef enum Tox_Err_Bootstrap {
const char *tox_err_bootstrap_to_string(Tox_Err_Bootstrap value);
/**
- * @brief Sends a "get nodes" request to the given bootstrap node with IP, port,
+ * @brief Sends a "nodes request" to the given bootstrap node with IP, port,
* and public key to setup connections.
*
* This function will attempt to connect to the node using UDP. You must use
@@ -1065,14 +639,16 @@ typedef void tox_self_connection_status_cb(Tox *tox, Tox_Connection connection_s
void tox_callback_self_connection_status(Tox *tox, tox_self_connection_status_cb *callback);
/**
- * @brief Return the time in milliseconds before `tox_iterate()` should be called again
- * for optimal performance.
+ * @brief Return the time in milliseconds before `tox_iterate()` should be
+ * called again for optimal performance.
*/
uint32_t tox_iteration_interval(const Tox *tox);
/**
- * @brief The main loop that needs to be run in intervals of `tox_iteration_interval()`
- * milliseconds.
+ * @brief The main loop that needs to be run in intervals of
+ * `tox_iteration_interval()` milliseconds.
+ * @param user_data Any pointer a client wishes the Tox instance to pass into
+ * the event callbacks, including NULL.
*/
void tox_iterate(Tox *tox, void *user_data);
@@ -1172,7 +748,8 @@ const char *tox_err_set_info_to_string(Tox_Err_Set_Info value);
bool tox_self_set_name(Tox *tox, const uint8_t name[], size_t length, Tox_Err_Set_Info *error);
/**
- * @brief Return the length of the current nickname as passed to tox_self_set_name.
+ * @brief Return the length of the current nickname as passed to
+ * tox_self_set_name.
*
* If no nickname was set before calling this function, the name is empty,
* and this function returns 0.
@@ -1206,7 +783,8 @@ bool tox_self_set_status_message(
Tox *tox, const uint8_t status_message[], size_t length, Tox_Err_Set_Info *error);
/**
- * @brief Return the length of the current status message as passed to tox_self_set_status_message.
+ * @brief Return the length of the current status message as passed to
+ * tox_self_set_status_message.
*
* If no status message was set before calling this function, the status
* is empty, and this function returns 0.
@@ -1216,13 +794,14 @@ bool tox_self_set_status_message(
size_t tox_self_get_status_message_size(const Tox *tox);
/**
- * @brief Write the status message set by tox_self_set_status_message to a byte array.
+ * @brief Write the status message set by tox_self_set_status_message to a byte
+ * array.
*
* If no status message was set before calling this function, the status is
* empty, and this function has no effect.
*
- * Call tox_self_get_status_message_size to find out how much memory to allocate for
- * the result.
+ * Call tox_self_get_status_message_size to find out how much memory to allocate
+ * for the result.
*
* @param status_message A valid memory location large enough to hold the
* status message. If this parameter is NULL, the function has no effect.
@@ -1279,8 +858,8 @@ typedef enum Tox_Err_Friend_Add {
TOX_ERR_FRIEND_ADD_OWN_KEY,
/**
- * A friend request has already been sent, or the address belongs to a friend
- * that is already on the friend list.
+ * A friend request has already been sent, or the address belongs to a
+ * friend that is already on the friend list.
*/
TOX_ERR_FRIEND_ADD_ALREADY_SENT,
@@ -1360,7 +939,8 @@ typedef enum Tox_Err_Friend_Delete {
TOX_ERR_FRIEND_DELETE_OK,
/**
- * There was no friend with the given friend number. No friends were deleted.
+ * There was no friend with the given friend number. No friends were
+ * deleted.
*/
TOX_ERR_FRIEND_DELETE_FRIEND_NOT_FOUND,
@@ -1411,14 +991,15 @@ const char *tox_err_friend_by_public_key_to_string(Tox_Err_Friend_By_Public_Key
/**
* @brief Return the friend number associated with that Public Key.
*
- * @return the friend number on success, an unspecified value on failure.
* @param public_key A byte array containing the Public Key.
+ *
+ * @return the friend number on success, an unspecified value on failure.
*/
Tox_Friend_Number tox_friend_by_public_key(const Tox *tox, const uint8_t public_key[TOX_PUBLIC_KEY_SIZE], Tox_Err_Friend_By_Public_Key *error);
/**
- * @brief Checks if a friend with the given friend number exists and returns true if
- * it does.
+ * @brief Checks if a friend with the given friend number exists and returns
+ * true if it does.
*/
bool tox_friend_exists(const Tox *tox, Tox_Friend_Number friend_number);
@@ -1433,7 +1014,8 @@ size_t tox_self_get_friend_list_size(const Tox *tox);
/**
* @brief Copy a list of valid friend numbers into an array.
*
- * Call tox_self_get_friend_list_size to determine the number of elements to allocate.
+ * Call tox_self_get_friend_list_size to determine the number of elements to
+ * allocate.
*
* @param friend_list A memory region with enough space to hold the friend
* list. If this parameter is NULL, this function has no effect.
@@ -1457,7 +1039,8 @@ typedef enum Tox_Err_Friend_Get_Public_Key {
const char *tox_err_friend_get_public_key_to_string(Tox_Err_Friend_Get_Public_Key value);
/**
- * @brief Copies the Public Key associated with a given friend number to a byte array.
+ * @brief Copies the Public Key associated with a given friend number to a byte
+ * array.
*
* @param friend_number The friend number you want the Public Key of.
* @param public_key A memory region of at least TOX_PUBLIC_KEY_SIZE bytes. If
@@ -1486,8 +1069,8 @@ typedef enum Tox_Err_Friend_Get_Last_Online {
const char *tox_err_friend_get_last_online_to_string(Tox_Err_Friend_Get_Last_Online value);
/**
- * @brief Return a unix-time timestamp of the last time the friend associated with a given
- * friend number was seen online.
+ * @brief Return a unix-time timestamp of the last time the friend associated
+ * with a given friend number was seen online.
*
* This function will return UINT64_MAX on error.
*
@@ -1514,8 +1097,9 @@ typedef enum Tox_Err_Friend_Query {
/**
* The pointer parameter for storing the query result (name, message) was
- * NULL. Unlike the `_self_` variants of these functions, which have no effect
- * when a parameter is NULL, these functions return an error in that case.
+ * NULL. Unlike the `_self_` variants of these functions, which have no
+ * effect when a parameter is NULL, these functions return an error in that
+ * case.
*/
TOX_ERR_FRIEND_QUERY_NULL,
@@ -1540,8 +1124,8 @@ size_t tox_friend_get_name_size(
const Tox *tox, Tox_Friend_Number friend_number, Tox_Err_Friend_Query *error);
/**
- * @brief Write the name of the friend designated by the given friend number to a byte
- * array.
+ * @brief Write the name of the friend designated by the given friend number to
+ * a byte array.
*
* Call tox_friend_get_name_size to determine the allocation size for the `name`
* parameter.
@@ -1579,22 +1163,23 @@ void tox_callback_friend_name(Tox *tox, tox_friend_name_cb *callback);
/**
* @brief Return the length of the friend's status message.
*
- * If the friend number isinvalid, the return value is SIZE_MAX.
+ * If the friend number is invalid, the return value is SIZE_MAX.
*/
size_t tox_friend_get_status_message_size(
const Tox *tox, Tox_Friend_Number friend_number, Tox_Err_Friend_Query *error);
/**
- * @brief Write the status message of the friend designated by the given friend number to a byte
- * array.
+ * @brief Write the status message of the friend designated by the given friend
+ * number to a byte array.
*
- * Call tox_friend_get_status_message_size to determine the allocation size for the `status_message`
- * parameter.
+ * Call tox_friend_get_status_message_size to determine the allocation size for
+ * the `status_message` parameter.
*
- * The data written to `status_message` is equal to the data received by the last
- * `friend_status_message` callback.
+ * The data written to `status_message` is equal to the data received by the
+ * last `friend_status_message` callback.
*
- * @param status_message A valid memory region large enough to store the friend's status message.
+ * @param status_message A valid memory region large enough to store the
+ * friend's status message.
*/
bool tox_friend_get_status_message(
const Tox *tox, Tox_Friend_Number friend_number, uint8_t status_message[],
@@ -1604,7 +1189,8 @@ bool tox_friend_get_status_message(
* @param friend_number The friend number of the friend whose status message
* changed.
* @param message A byte array containing the same data as
- * tox_friend_get_status_message would write to its `status_message` parameter.
+ * tox_friend_get_status_message would write to its `status_message`
+ * parameter.
* @param length A value equal to the return value of
* tox_friend_get_status_message_size.
*/
@@ -1814,7 +1400,8 @@ typedef uint32_t Tox_Friend_Message_Id;
* then reassemble the fragments. Messages may not be empty.
*
* The return value of this function is the message ID. If a read receipt is
- * received, the triggered `friend_read_receipt` event will be passed this message ID.
+ * received, the triggered `friend_read_receipt` event will be passed this
+ * message ID.
*
* Message IDs are unique per friend. The first message ID is 0. Message IDs are
* incremented by 1 each time a message is sent. If UINT32_MAX messages were
@@ -1831,7 +1418,8 @@ Tox_Friend_Message_Id tox_friend_send_message(
const uint8_t message[], size_t length, Tox_Err_Friend_Send_Message *error);
/**
- * @param friend_number The friend number of the friend who received the message.
+ * @param friend_number The friend number of the friend who received the
+ * message.
* @param message_id The message ID as returned from tox_friend_send_message
* corresponding to the message sent.
*/
@@ -1875,6 +1463,7 @@ void tox_callback_friend_request(Tox *tox, tox_friend_request_cb *callback);
/**
* @param friend_number The friend number of the friend who sent the message.
+ * @param type The type of the message (normal, action, ...).
* @param message The message data they sent.
* @param length The size of the message byte array.
*/
@@ -1906,10 +1495,10 @@ typedef uint32_t Tox_File_Number;
* primarily for validating cached avatars. This use is highly recommended to
* avoid unnecessary avatar updates.
*
- * If hash is NULL or data is NULL while length is not 0 the function returns false,
- * otherwise it returns true.
+ * If hash is NULL or data is NULL while length is not 0 the function returns
+ * false, otherwise it returns true.
*
- * This function is a wrapper to events_alloc message-digest functions.
+ * This function is a wrapper to internal message-digest functions.
*
* @param hash A valid memory location the hash data. It must be at least
* TOX_HASH_LENGTH bytes in size.
@@ -1923,17 +1512,17 @@ bool tox_hash(uint8_t hash[TOX_HASH_LENGTH], const uint8_t data[], size_t length
/**
* @brief A list of pre-defined file kinds.
*
- * Toxcore itself does not behave differently for different file kinds. These
- * are a hint to the client telling it what use the sender intended for the
- * file. The `kind` parameter in the send function and recv callback are
+ * The Tox library itself does not behave differently for different file kinds.
+ * These are a hint to the client telling it what use the sender intended for
+ * the file. The `kind` parameter in the send function and recv callback are
* `uint32_t`, not Tox_File_Kind, because clients can invent their own file
* kind. Unknown file kinds should be treated as TOX_FILE_KIND_DATA.
*/
enum Tox_File_Kind {
/**
- * Arbitrary file data. Clients can choose to handle it based on the file name
- * or magic or any other way they choose.
+ * Arbitrary file data. Clients can choose to handle it based on the file
+ * name or magic or any other way they choose.
*/
TOX_FILE_KIND_DATA,
@@ -1941,21 +1530,21 @@ enum Tox_File_Kind {
* Avatar file_id. This consists of tox_hash(image).
* Avatar data. This consists of the image data.
*
- * Avatars can be sent at any time the client wishes. Generally, a client will
- * send the avatar to a friend when that friend comes online, and to all
- * friends when the avatar changed. A client can save some traffic by
- * remembering which friend received the updated avatar already and only send
- * it if the friend has an out of date avatar.
+ * Avatars can be sent at any time the client wishes. Generally, a client
+ * will send the avatar to a friend when that friend comes online, and to
+ * all friends when the avatar changed. A client can save some traffic by
+ * remembering which friend received the updated avatar already and only
+ * send it if the friend has an out of date avatar.
*
* Clients who receive avatar send requests can reject it (by sending
* TOX_FILE_CONTROL_CANCEL before any other controls), or accept it (by
- * sending TOX_FILE_CONTROL_RESUME). The file_id of length TOX_HASH_LENGTH bytes
- * (same length as TOX_FILE_ID_LENGTH) will contain the hash. A client can compare
- * this hash with a saved hash and send TOX_FILE_CONTROL_CANCEL to terminate the avatar
- * transfer if it matches.
+ * sending TOX_FILE_CONTROL_RESUME). The file_id of length TOX_HASH_LENGTH
+ * bytes (same length as TOX_FILE_ID_LENGTH) will contain the hash. A client
+ * can compare this hash with a saved hash and send TOX_FILE_CONTROL_CANCEL
+ * to terminate the avatar transfer if it matches.
*
- * When file_size is set to 0 in the transfer request it means that the client
- * has no avatar.
+ * When file_size is set to 0 in the transfer request it means that the
+ * client has no avatar.
*/
TOX_FILE_KIND_AVATAR,
@@ -1964,16 +1553,17 @@ enum Tox_File_Kind {
typedef enum Tox_File_Control {
/**
- * Sent by the receiving side to accept a file send request. Also sent after a
- * TOX_FILE_CONTROL_PAUSE command to continue sending or receiving.
+ * Sent by the receiving side to accept a file send request. Also sent after
+ * a TOX_FILE_CONTROL_PAUSE command to continue sending or receiving.
*/
TOX_FILE_CONTROL_RESUME,
/**
* Sent by clients to pause the file transfer. The initial state of a file
- * transfer is always paused on the receiving side and running on the sending
- * side. If both the sending and receiving side pause the transfer, then both
- * need to send TOX_FILE_CONTROL_RESUME for the transfer to resume.
+ * transfer is always paused on the receiving side and running on the
+ * sending side. If both the sending and receiving side pause the transfer,
+ * then both need to send TOX_FILE_CONTROL_RESUME for the transfer to
+ * resume.
*/
TOX_FILE_CONTROL_PAUSE,
@@ -2005,7 +1595,8 @@ typedef enum Tox_Err_File_Control {
TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED,
/**
- * No file transfer with the given file number was found for the given friend.
+ * No file transfer with the given file number was found for the given
+ * friend.
*/
TOX_ERR_FILE_CONTROL_NOT_FOUND,
@@ -2089,7 +1680,8 @@ typedef enum Tox_Err_File_Seek {
TOX_ERR_FILE_SEEK_FRIEND_NOT_CONNECTED,
/**
- * No file transfer with the given file number was found for the given friend.
+ * No file transfer with the given file number was found for the given
+ * friend.
*/
TOX_ERR_FILE_SEEK_NOT_FOUND,
@@ -2113,7 +1705,8 @@ typedef enum Tox_Err_File_Seek {
const char *tox_err_file_seek_to_string(Tox_Err_File_Seek value);
/**
- * @brief Sends a file seek control command to a friend for a given file transfer.
+ * @brief Sends a file seek control command to a friend for a given file
+ * transfer.
*
* This function can only be called to resume a file transfer right before
* TOX_FILE_CONTROL_RESUME is sent.
@@ -2144,7 +1737,8 @@ typedef enum Tox_Err_File_Get {
TOX_ERR_FILE_GET_FRIEND_NOT_FOUND,
/**
- * No file transfer with the given file number was found for the given friend.
+ * No file transfer with the given file number was found for the given
+ * friend.
*/
TOX_ERR_FILE_GET_NOT_FOUND,
@@ -2158,8 +1752,8 @@ const char *tox_err_file_get_to_string(Tox_Err_File_Get value);
* @param friend_number The friend number of the friend the file is being
* transferred to or received from.
* @param file_number The friend-specific identifier for the file transfer.
- * @param file_id A memory region of at least TOX_FILE_ID_LENGTH bytes. If
- * this parameter is NULL, this function has no effect.
+ * @param file_id A memory region of at least TOX_FILE_ID_LENGTH bytes. If this
+ * parameter is NULL, this function has no effect.
*
* @return true on success.
*/
@@ -2202,8 +1796,8 @@ typedef enum Tox_Err_File_Send {
TOX_ERR_FILE_SEND_NAME_TOO_LONG,
/**
- * Too many ongoing transfers. The maximum number of concurrent file transfers
- * is 256 per friend per direction (sending and receiving).
+ * Too many ongoing transfers. The maximum number of concurrent file
+ * transfers is 256 per friend per direction (sending and receiving).
*/
TOX_ERR_FILE_SEND_TOO_MANY,
@@ -2214,8 +1808,8 @@ const char *tox_err_file_send_to_string(Tox_Err_File_Send value);
/**
* @brief Send a file transmission request.
*
- * Maximum filename length is TOX_MAX_FILENAME_LENGTH bytes. The filename
- * should generally just be a file name, not a path with directory names.
+ * Maximum filename length is TOX_MAX_FILENAME_LENGTH bytes. The filename should
+ * generally just be a file name, not a path with directory names.
*
* If a non-UINT64_MAX file size is provided, it can be used by both sides to
* determine the sending progress. File size can be set to UINT64_MAX for
@@ -2224,8 +1818,8 @@ const char *tox_err_file_send_to_string(Tox_Err_File_Send value);
* File transmission occurs in chunks, which are requested through the
* `file_chunk_request` event.
*
- * When a friend goes offline, all file transfers associated with the friend are
- * purged from core.
+ * When a friend goes offline, all file transfers associated with the friend get
+ * purged.
*
* If the file contents change during a transfer, the behaviour is unspecified
* in general. What will actually happen depends on the mode in which the file
@@ -2234,15 +1828,16 @@ const char *tox_err_file_send_to_string(Tox_Err_File_Send value);
* - If the file size was increased
* - and sending mode was streaming (file_size = UINT64_MAX), the behaviour
* will be as expected.
- * - and sending mode was file (file_size != UINT64_MAX), the file_chunk_request
- * callback will receive length = 0 when Core thinks the file transfer has
- * finished. If the client remembers the file size as it was when sending the
- * request, it will terminate the transfer normally. If the client re-reads the
- * size, it will think the friend cancelled the transfer.
+ * - and sending mode was file (file_size != UINT64_MAX), the
+ * file_chunk_request callback will receive length = 0 when Tox thinks the
+ * file transfer has finished. If the client remembers the file size as it
+ * was when sending the request, it will terminate the transfer normally. If
+ * the client re-reads the size, it will think the friend cancelled the
+ * transfer.
* - If the file size was decreased
* - and sending mode was streaming, the behaviour is as expected.
* - and sending mode was file, the callback will return 0 at the new
- * (earlier) end-of-file, signalling to the friend that the transfer was
+ * (earlier) end-of-file, signaling to the friend that the transfer was
* cancelled.
* - If the file contents were modified
* - at a position before the current read, the two files (local and remote)
@@ -2255,19 +1850,20 @@ const char *tox_err_file_send_to_string(Tox_Err_File_Send value);
* @param friend_number The friend number of the friend the file send request
* should be sent to.
* @param kind The meaning of the file to be sent.
- * @param file_size Size in bytes of the file the client wants to send, UINT64_MAX if
- * unknown or streaming.
- * @param file_id A file identifier of length TOX_FILE_ID_LENGTH that can be used to
- * uniquely identify file transfers across core restarts. If NULL, a random one will
- * be generated by core. It can then be obtained by using `tox_file_get_file_id()`.
+ * @param file_size Size in bytes of the file the client wants to send,
+ * UINT64_MAX if unknown or streaming.
+ * @param file_id A file identifier of length TOX_FILE_ID_LENGTH that can be
+ * used to uniquely identify file transfers across Tox restarts. If NULL, a
+ * random one will be generated by the library. It can then be obtained by
+ * using `tox_file_get_file_id()`.
* @param filename Name of the file. Does not need to be the actual name. This
* name will be sent along with the file send request.
* @param filename_length Size in bytes of the filename.
*
* @return A file number used as an identifier in subsequent callbacks. This
* number is per friend. File numbers are reused after a transfer terminates.
- * On failure, this function returns an unspecified value. Any pattern in file numbers
- * should not be relied on.
+ * On failure, this function returns an unspecified value. Any pattern in file
+ * numbers should not be relied on.
*/
Tox_File_Number tox_file_send(
Tox *tox, Tox_Friend_Number friend_number, uint32_t kind, uint64_t file_size,
@@ -2297,20 +1893,23 @@ typedef enum Tox_Err_File_Send_Chunk {
TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_CONNECTED,
/**
- * No file transfer with the given file number was found for the given friend.
+ * No file transfer with the given file number was found for the given
+ * friend.
*/
TOX_ERR_FILE_SEND_CHUNK_NOT_FOUND,
/**
* File transfer was found but isn't in a transferring state: (paused, done,
- * broken, etc...) (happens only when not called from the request chunk callback).
+ * broken, etc...) (happens only when not called from the request chunk
+ * callback).
*/
TOX_ERR_FILE_SEND_CHUNK_NOT_TRANSFERRING,
/**
- * Attempted to send more or less data than requested. The requested data size is
- * adjusted according to maximum transmission unit and the expected end of
- * the file. Trying to send less or more than requested will return this error.
+ * Attempted to send more or less data than requested. The requested data
+ * size is adjusted according to maximum transmission unit and the expected
+ * end of the file. Trying to send less or more than requested will return
+ * this error.
*/
TOX_ERR_FILE_SEND_CHUNK_INVALID_LENGTH,
@@ -2334,10 +1933,11 @@ const char *tox_err_file_send_chunk_to_string(Tox_Err_File_Send_Chunk value);
* This function is called in response to the `file_chunk_request` callback. The
* length parameter should be equal to the one received though the callback.
* If it is zero, the transfer is assumed complete. For files with known size,
- * Core will know that the transfer is complete after the last byte has been
+ * Tox will know that the transfer is complete after the last byte has been
* received, so it is not necessary (though not harmful) to send a zero-length
- * chunk to terminate. For streams, core will know that the transfer is finished
- * if a chunk with length less than the length requested in the callback is sent.
+ * chunk to terminate. For streams, Tox will know that the transfer is finished
+ * if a chunk with length less than the length requested in the callback is
+ * sent.
*
* @param friend_number The friend number of the receiving friend for this file.
* @param file_number The file transfer identifier returned by tox_file_send.
@@ -2379,7 +1979,7 @@ typedef void tox_file_chunk_request_cb(
*
* Pass NULL to unset.
*
- * This event is triggered when Core is ready to send more file data.
+ * This event is triggered when Tox is ready to send more file data.
*/
void tox_callback_file_chunk_request(Tox *tox, tox_file_chunk_request_cb *callback);
@@ -2458,6 +2058,7 @@ void tox_callback_file_recv_chunk(Tox *tox, tox_file_recv_chunk_cb *callback);
typedef uint32_t Tox_Conference_Number;
typedef uint32_t Tox_Conference_Peer_Number;
+typedef uint32_t Tox_Conference_Offline_Peer_Number;
/**
* @brief Conference types for the conference_invite event.
@@ -2465,7 +2066,8 @@ typedef uint32_t Tox_Conference_Peer_Number;
typedef enum Tox_Conference_Type {
/**
- * Text-only conferences that must be accepted with the tox_conference_join function.
+ * Text-only conferences that must be accepted with the tox_conference_join
+ * function.
*/
TOX_CONFERENCE_TYPE_TEXT,
@@ -2502,7 +2104,8 @@ typedef void tox_conference_invite_cb(
void tox_callback_conference_invite(Tox *tox, tox_conference_invite_cb *callback);
/**
- * @param conference_number The conference number of the conference to which we have connected.
+ * @param conference_number The conference number of the conference to which we
+ * have connected.
*/
typedef void tox_conference_connected_cb(Tox *tox, Tox_Conference_Number conference_number, void *user_data);
@@ -2555,7 +2158,8 @@ typedef void tox_conference_title_cb(
*
* This event is triggered when a peer changes the conference title.
*
- * If peer_number == UINT32_MAX, then author is unknown (e.g. initial joining the conference).
+ * If peer_number == UINT32_MAX, then author is unknown (e.g. initial joining
+ * the conference).
*/
void tox_callback_conference_title(Tox *tox, tox_conference_title_cb *callback);
@@ -2640,7 +2244,8 @@ const char *tox_err_conference_delete_to_string(Tox_Err_Conference_Delete value)
/**
* @brief This function deletes a conference.
*
- * @param conference_number The conference number of the conference to be deleted.
+ * @param conference_number The conference number of the conference to be
+ * deleted.
*
* @return true on success.
*/
@@ -2682,7 +2287,7 @@ const char *tox_err_conference_peer_query_to_string(Tox_Err_Conference_Peer_Quer
* peer_number for the functions querying these peers. Return value is
* unspecified on failure.
*/
-Tox_Conference_Peer_Number tox_conference_peer_count(
+uint32_t tox_conference_peer_count(
const Tox *tox, Tox_Conference_Number conference_number, Tox_Err_Conference_Peer_Query *error);
/**
@@ -2697,7 +2302,8 @@ size_t tox_conference_peer_get_name_size(
/**
* @brief Copy the name of peer_number who is in conference_number to name.
*
- * Call tox_conference_peer_get_name_size to determine the allocation size for the `name` parameter.
+ * Call tox_conference_peer_get_name_size to determine the allocation size for
+ * the `name` parameter.
*
* @param name A valid memory region large enough to store the peer's name.
*
@@ -2708,7 +2314,8 @@ bool tox_conference_peer_get_name(
uint8_t name[], Tox_Err_Conference_Peer_Query *error);
/**
- * @brief Copy the public key of peer_number who is in conference_number to public_key.
+ * @brief Copy the public key of peer_number who is in conference_number to
+ * public_key.
*
* public_key must be TOX_PUBLIC_KEY_SIZE long.
*
@@ -2744,10 +2351,11 @@ uint32_t tox_conference_offline_peer_count(
*/
size_t tox_conference_offline_peer_get_name_size(
const Tox *tox, Tox_Conference_Number conference_number,
- Tox_Conference_Peer_Number offline_peer_number, Tox_Err_Conference_Peer_Query *error);
+ Tox_Conference_Offline_Peer_Number offline_peer_number, Tox_Err_Conference_Peer_Query *error);
/**
- * @brief Copy the name of offline_peer_number who is in conference_number to name.
+ * @brief Copy the name of offline_peer_number who is in conference_number to
+ * name.
*
* Call tox_conference_offline_peer_get_name_size to determine the allocation
* size for the `name` parameter.
@@ -2757,11 +2365,12 @@ size_t tox_conference_offline_peer_get_name_size(
* @return true on success.
*/
bool tox_conference_offline_peer_get_name(
- const Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Peer_Number offline_peer_number,
+ const Tox *tox, Tox_Conference_Number conference_number, Tox_Conference_Offline_Peer_Number offline_peer_number,
uint8_t name[], Tox_Err_Conference_Peer_Query *error);
/**
- * @brief Copy the public key of offline_peer_number who is in conference_number to public_key.
+ * @brief Copy the public key of offline_peer_number who is in conference_number
+ * to public_key.
*
* public_key must be TOX_PUBLIC_KEY_SIZE long.
*
@@ -2769,14 +2378,15 @@ bool tox_conference_offline_peer_get_name(
*/
bool tox_conference_offline_peer_get_public_key(
const Tox *tox, Tox_Conference_Number conference_number,
- Tox_Conference_Peer_Number offline_peer_number, uint8_t public_key[TOX_PUBLIC_KEY_SIZE], Tox_Err_Conference_Peer_Query *error);
+ Tox_Conference_Offline_Peer_Number offline_peer_number, uint8_t public_key[TOX_PUBLIC_KEY_SIZE], Tox_Err_Conference_Peer_Query *error);
/**
- * @brief Return a unix-time timestamp of the last time offline_peer_number was seen to be active.
+ * @brief Return a unix-time timestamp of the last time offline_peer_number was
+ * seen to be active.
*/
uint64_t tox_conference_offline_peer_get_last_active(
const Tox *tox, Tox_Conference_Number conference_number,
- Tox_Conference_Peer_Number offline_peer_number, Tox_Err_Conference_Peer_Query *error);
+ Tox_Conference_Offline_Peer_Number offline_peer_number, Tox_Err_Conference_Peer_Query *error);
typedef enum Tox_Err_Conference_Set_Max_Offline {
@@ -2831,7 +2441,8 @@ const char *tox_err_conference_invite_to_string(Tox_Err_Conference_Invite value)
* @brief Invites a friend to a conference.
*
* @param friend_number The friend number of the friend we want to invite.
- * @param conference_number The conference number of the conference we want to invite the friend to.
+ * @param conference_number The conference number of the conference we want to
+ * invite the friend to.
*
* @return true on success.
*/
@@ -2852,7 +2463,8 @@ typedef enum Tox_Err_Conference_Join {
TOX_ERR_CONFERENCE_JOIN_INVALID_LENGTH,
/**
- * The conference is not the expected type. This indicates an invalid cookie.
+ * The conference is not the expected type. This indicates an invalid
+ * cookie.
*/
TOX_ERR_CONFERENCE_JOIN_WRONG_TYPE,
@@ -2876,6 +2488,11 @@ typedef enum Tox_Err_Conference_Join {
*/
TOX_ERR_CONFERENCE_JOIN_FAIL_SEND,
+ /**
+ * The cookie passed was NULL.
+ */
+ TOX_ERR_CONFERENCE_JOIN_NULL,
+
} Tox_Err_Conference_Join;
const char *tox_err_conference_join_to_string(Tox_Err_Conference_Join value);
@@ -2887,7 +2504,7 @@ const char *tox_err_conference_join_to_string(Tox_Err_Conference_Join value);
* to it until a handshaking procedure has been completed. A
* `conference_connected` event will then occur for the conference. The client
* will then remain connected to the conference until the conference is deleted,
- * even across core restarts. Many operations on a conference will fail with a
+ * even across Tox restarts. Many operations on a conference will fail with a
* corresponding error if attempted on a conference to which the client is not
* yet connected.
*
@@ -2995,9 +2612,11 @@ size_t tox_conference_get_title_size(
const Tox *tox, Tox_Conference_Number conference_number, Tox_Err_Conference_Title *error);
/**
- * @brief Write the title designated by the given conference number to a byte array.
+ * @brief Write the title designated by the given conference number to a byte
+ * array.
*
- * Call tox_conference_get_title_size to determine the allocation size for the `title` parameter.
+ * Call tox_conference_get_title_size to determine the allocation size for the
+ * `title` parameter.
*
* The data written to `title` is equal to the data received by the last
* `conference_title` callback.
@@ -3013,7 +2632,8 @@ bool tox_conference_get_title(
Tox_Err_Conference_Title *error);
/**
- * @brief Set the conference title and broadcast it to the rest of the conference.
+ * @brief Set the conference title and broadcast it to the rest of the
+ * conference.
*
* Title length cannot be longer than TOX_MAX_NAME_LENGTH.
*
@@ -3027,7 +2647,8 @@ bool tox_conference_set_title(
/**
* @brief Return the number of conferences in the Tox instance.
*
- * This should be used to determine how much memory to allocate for `tox_conference_get_chatlist`.
+ * This should be used to determine how much memory to allocate for
+ * `tox_conference_get_chatlist`.
*/
size_t tox_conference_get_chatlist_size(const Tox *tox);
@@ -3037,8 +2658,8 @@ size_t tox_conference_get_chatlist_size(const Tox *tox);
* Determine how much space to allocate for the array with the
* `tox_conference_get_chatlist_size` function.
*
- * Note that `tox_get_savedata` saves all connected conferences;
- * when toxcore is created from savedata in which conferences were saved, those
+ * Note that `tox_get_savedata` saves all connected conferences; when a Tox
+ * instance is created from savedata in which conferences were saved, those
* conferences will be connected at startup, and will be listed by
* `tox_conference_get_chatlist`.
*
@@ -3048,7 +2669,8 @@ size_t tox_conference_get_chatlist_size(const Tox *tox);
void tox_conference_get_chatlist(const Tox *tox, Tox_Conference_Number chatlist[]);
/**
- * @brief Returns the type of conference (Tox_Conference_Type) that conference_number is.
+ * @brief Returns the type of conference (Tox_Conference_Type) that
+ * conference_number is.
*
* Return value is unspecified on failure.
*/
@@ -3118,18 +2740,22 @@ const char *tox_err_conference_by_id_to_string(Tox_Err_Conference_By_Id value);
Tox_Conference_Number tox_conference_by_id(
const Tox *tox, const uint8_t id[TOX_CONFERENCE_ID_SIZE], Tox_Err_Conference_By_Id *error);
+#ifndef TOX_HIDE_DEPRECATED
/**
* @brief Get the conference unique ID.
*
* If uid is NULL, this function has no effect.
*
- * @param uid A memory region large enough to store TOX_CONFERENCE_UID_SIZE bytes.
+ * @param uid A memory region large enough to store TOX_CONFERENCE_UID_SIZE
+ * bytes.
*
* @return true on success.
- * @deprecated use tox_conference_get_id instead (exactly the same function, just renamed).
+ * @deprecated use tox_conference_get_id instead (exactly the same function,
+ * just renamed).
*/
bool tox_conference_get_uid(
const Tox *tox, Tox_Conference_Number conference_number, uint8_t uid[TOX_CONFERENCE_UID_SIZE]);
+#endif /* TOX_HIDE_DEPRECATED */
typedef enum Tox_Err_Conference_By_Uid {
@@ -3152,16 +2778,20 @@ typedef enum Tox_Err_Conference_By_Uid {
const char *tox_err_conference_by_uid_to_string(Tox_Err_Conference_By_Uid value);
+#ifndef TOX_HIDE_DEPRECATED
/**
* @brief Return the conference number associated with the specified uid.
*
- * @param uid A byte array containing the conference id (TOX_CONFERENCE_UID_SIZE).
+ * @param uid A byte array containing the conference id
+ * (TOX_CONFERENCE_UID_SIZE).
*
* @return the conference number on success, an unspecified value on failure.
- * @deprecated use tox_conference_by_id instead (exactly the same function, just renamed).
+ * @deprecated use tox_conference_by_id instead (exactly the same function,
+ * just renamed).
*/
Tox_Conference_Number tox_conference_by_uid(
const Tox *tox, const uint8_t uid[TOX_CONFERENCE_UID_SIZE], Tox_Err_Conference_By_Uid *error);
+#endif /* TOX_HIDE_DEPRECATED */
/** @} */
@@ -3192,8 +2822,9 @@ typedef enum Tox_Err_Friend_Custom_Packet {
TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_CONNECTED,
/**
- * The first byte of data was not in the specified range for the packet type.
- * This range is 192-254 for lossy, and 69, 160-191 for lossless packets.
+ * The first byte of data was not one of the permitted values;
+ * for lossy packets the first byte must be in the range 192-254,
+ * and for lossless packets it must be either 69 or in the range 160-191.
*/
TOX_ERR_FRIEND_CUSTOM_PACKET_INVALID,
@@ -3244,7 +2875,7 @@ bool tox_friend_send_lossy_packet(
/**
* @brief Send a custom lossless packet to a friend.
*
- * The first byte of data must be in the range 69, 160-191. Maximum length of a
+ * The first byte of data must be either 69 or in the range 160-191. Maximum length of a
* custom packet is TOX_MAX_CUSTOM_PACKET_SIZE.
*
* Lossless packet behaviour is comparable to TCP (reliability, arrive in order)
@@ -3263,6 +2894,9 @@ bool tox_friend_send_lossless_packet(
Tox_Err_Friend_Custom_Packet *error);
/**
+ * tox_callback_friend_lossy_packet is the compatibility function to
+ * set the callback for all packet IDs except those reserved for ToxAV.
+ *
* @param friend_number The friend number of the friend who sent a lossy packet.
* @param data A byte array containing the received packet data.
* @param length The length of the packet data byte array.
@@ -3322,7 +2956,8 @@ const char *tox_err_get_port_to_string(Tox_Err_Get_Port value);
* @brief Writes the temporary DHT public key of this instance to a byte array.
*
* This can be used in combination with an externally accessible IP address and
- * the bound port (from tox_self_get_udp_port) to run a temporary bootstrap node.
+ * the bound port (from tox_self_get_udp_port) to run a temporary bootstrap
+ * node.
*
* Be aware that every time a new instance is created, the DHT public key
* changes, meaning this cannot be used to run a permanent bootstrap node.
@@ -3435,22 +3070,24 @@ uint32_t tox_group_peer_public_key_size(void);
typedef enum Tox_Group_Privacy_State {
/**
- * The group is considered to be public. Anyone may join the group using the Chat ID.
+ * The group is considered to be public. Anyone may join the group using
+ * the Chat ID.
*
- * If the group is in this state, even if the Chat ID is never explicitly shared
- * with someone outside of the group, information including the Chat ID, IP addresses,
- * and peer ID's (but not Tox ID's) is visible to anyone with access to a node
- * storing a DHT entry for the given group.
+ * If the group is in this state, even if the Chat ID is never explicitly
+ * shared with someone outside of the group, information including the Chat
+ * ID, IP addresses, and peer ID's (but not Tox ID's) is visible to anyone
+ * with access to a node storing a DHT entry for the given group.
*/
TOX_GROUP_PRIVACY_STATE_PUBLIC,
/**
- * The group is considered to be private. The only way to join the group is by having
- * someone in your contact list send you an invite.
+ * The group is considered to be private. The only way to join the group is
+ * by having someone in your contact list send you an invite.
*
- * If the group is in this state, no group information (mentioned above) is present in the DHT;
- * the DHT is not used for any purpose at all. If a public group is set to private,
- * all DHT information related to the group will expire shortly.
+ * If the group is in this state, no group information (mentioned above) is
+ * present in the DHT; the DHT is not used for any purpose at all. If a
+ * public group is set to private, all DHT information related to the group
+ * will expire shortly.
*/
TOX_GROUP_PRIVACY_STATE_PRIVATE,
@@ -3460,16 +3097,20 @@ const char *tox_group_privacy_state_to_string(Tox_Group_Privacy_State value);
/**
* Represents the state of the group topic lock.
+ *
+ * The default is enabled.
*/
typedef enum Tox_Group_Topic_Lock {
/**
- * The topic lock is enabled. Only peers with the founder and moderator roles may set the topic.
+ * The topic lock is enabled. Only peers with the founder and moderator
+ * roles may set the topic.
*/
TOX_GROUP_TOPIC_LOCK_ENABLED,
/**
- * The topic lock is disabled. All peers except those with the observer role may set the topic.
+ * The topic lock is disabled. All peers except those with the observer role
+ * may set the topic.
*/
TOX_GROUP_TOPIC_LOCK_DISABLED,
@@ -3478,8 +3119,9 @@ typedef enum Tox_Group_Topic_Lock {
const char *tox_group_topic_lock_to_string(Tox_Group_Topic_Lock value);
/**
- * Represents the group voice state, which determines which Group Roles have permission to speak
- * in the group chat. The voice state does not have any effect private messages or topic setting.
+ * Represents the group voice state, which determines which Group Roles have
+ * permission to speak in the group chat. The voice state does not have any
+ * effect private messages or topic setting.
*/
typedef enum Tox_Group_Voice_State {
/**
@@ -3503,14 +3145,15 @@ const char *tox_group_voice_state_to_string(Tox_Group_Voice_State value);
/**
* Represents group roles.
*
- * Roles are hierarchical in that each role has a set of privileges plus all the privileges
- * of the roles below it.
+ * Roles are hierarchical in that each role has a set of privileges plus all the
+ * privileges of the roles below it.
*/
typedef enum Tox_Group_Role {
/**
- * May kick all other peers as well as set their role to anything (except founder).
- * Founders may also set the group password, toggle the privacy state, and set the peer limit.
+ * May kick all other peers as well as set their role to anything (except
+ * founder). Founders may also set the group password, toggle the privacy
+ * state, and set the peer limit.
*/
TOX_GROUP_ROLE_FOUNDER,
@@ -3526,7 +3169,8 @@ typedef enum Tox_Group_Role {
TOX_GROUP_ROLE_USER,
/**
- * May observe the group and ignore peers; may not communicate with other peers or with the group.
+ * May observe the group and ignore peers; may not communicate with other
+ * peers or with the group.
*/
TOX_GROUP_ROLE_OBSERVER,
@@ -3548,7 +3192,8 @@ typedef enum Tox_Err_Group_New {
TOX_ERR_GROUP_NEW_OK,
/**
- * name exceeds TOX_MAX_NAME_LENGTH or group_name exceeded TOX_GROUP_MAX_GROUP_NAME_LENGTH.
+ * name exceeds TOX_MAX_NAME_LENGTH or group_name exceeded
+ * TOX_GROUP_MAX_GROUP_NAME_LENGTH.
*/
TOX_ERR_GROUP_NEW_TOO_LONG,
@@ -3563,13 +3208,14 @@ typedef enum Tox_Err_Group_New {
TOX_ERR_GROUP_NEW_INIT,
/**
- * The group state failed to initialize. This usually indicates that something went wrong
- * related to cryptographic signing.
+ * The group state failed to initialize. This usually indicates that
+ * something went wrong related to cryptographic signing.
*/
TOX_ERR_GROUP_NEW_STATE,
/**
- * The group failed to announce to the DHT. This indicates a network related error.
+ * The group failed to announce to the DHT. This indicates a network related
+ * error.
*/
TOX_ERR_GROUP_NEW_ANNOUNCE,
@@ -3584,18 +3230,19 @@ const char *tox_err_group_new_to_string(Tox_Err_Group_New value);
*
* The caller of this function has Founder role privileges.
*
- * The client should initiate its peer list with self info after calling this function, as
- * the peer_join callback will not be triggered.
+ * The client should initiate its peer list with self info after calling this
+ * function, as the peer_join callback will not be triggered.
*
- * @param privacy_state The privacy state of the group. If this is set to TOX_GROUP_PRIVACY_STATE_PUBLIC,
- * the group will attempt to announce itself to the DHT and anyone with the Chat ID may join.
- * Otherwise a friend invite will be required to join the group.
+ * @param privacy_state The privacy state of the group. If this is set to
+ * TOX_GROUP_PRIVACY_STATE_PUBLIC, the group will attempt to announce itself
+ * to the DHT and anyone with the Chat ID may join. Otherwise a friend invite
+ * will be required to join the group.
* @param group_name The name of the group. The name must be non-NULL.
- * @param group_name_length The length of the group name. This must be greater than zero and no larger than
- * TOX_GROUP_MAX_GROUP_NAME_LENGTH.
+ * @param group_name_length The length of the group name. This must be greater
+ * than zero and no larger than TOX_GROUP_MAX_GROUP_NAME_LENGTH.
* @param name The name of the peer creating the group.
- * @param name_length The length of the peer's name. This must be greater than zero and no larger
- * than TOX_MAX_NAME_LENGTH.
+ * @param name_length The length of the peer's name. This must be greater than
+ * zero and no larger than TOX_MAX_NAME_LENGTH.
*
* @return group_number on success, UINT32_MAX on failure.
*/
@@ -3617,8 +3264,7 @@ typedef enum Tox_Err_Group_Join {
TOX_ERR_GROUP_JOIN_INIT,
/**
- * The chat_id pointer is set to NULL or a group with chat_id already exists. This usually
- * happens if the client attempts to create multiple sessions for the same group.
+ * The chat_id pointer is set to NULL.
*/
TOX_ERR_GROUP_JOIN_BAD_CHAT_ID,
@@ -3633,7 +3279,8 @@ typedef enum Tox_Err_Group_Join {
TOX_ERR_GROUP_JOIN_TOO_LONG,
/**
- * Failed to set password. This usually occurs if the password exceeds TOX_GROUP_MAX_PASSWORD_SIZE.
+ * Failed to set password. This usually occurs if the password exceeds
+ * TOX_GROUP_MAX_PASSWORD_SIZE.
*/
TOX_ERR_GROUP_JOIN_PASSWORD,
@@ -3647,19 +3294,25 @@ typedef enum Tox_Err_Group_Join {
const char *tox_err_group_join_to_string(Tox_Err_Group_Join value);
/**
- * Joins a group chat with specified Chat ID.
+ * Joins a group chat with specified Chat ID or reconnects to an existing group.
*
- * This function creates a new group chat object, adds it to the chats array, and sends
- * a DHT announcement to find peers in the group associated with chat_id. Once a peer has been
- * found a join attempt will be initiated.
+ * This function creates a new group chat object, adds it to the chats array,
+ * and sends a DHT announcement to find peers in the group associated with
+ * chat_id. Once a peer has been found a join attempt will be initiated.
*
- * @param chat_id The Chat ID of the group you wish to join. This must be TOX_GROUP_CHAT_ID_SIZE bytes.
- * @param password The password required to join the group. Set to NULL if no password is required.
- * @param password_length The length of the password. If length is equal to zero,
- * the password parameter is ignored. length must be no larger than TOX_GROUP_MAX_PASSWORD_SIZE.
+ * If a group with the specified Chat ID already exists, this function will attempt
+ * to reconnect to the group.
+ *
+ * @param chat_id The Chat ID of the group you wish to join. This must be
+ * TOX_GROUP_CHAT_ID_SIZE bytes.
+ * @param password The password required to join the group. Set to NULL if no
+ * password is required.
+ * @param password_length The length of the password. If length is equal to
+ * zero, the password parameter is ignored. length must be no larger than
+ * TOX_GROUP_MAX_PASSWORD_SIZE.
* @param name The name of the peer joining the group.
- * @param name_length The length of the peer's name. This must be greater than zero and no larger
- * than TOX_MAX_NAME_LENGTH.
+ * @param name_length The length of the peer's name. This must be greater than
+ * zero and no larger than TOX_MAX_NAME_LENGTH.
*
* @return group_number on success, UINT32_MAX on failure.
*/
@@ -3686,8 +3339,8 @@ typedef enum Tox_Err_Group_Is_Connected {
const char *tox_err_group_is_connected_to_string(Tox_Err_Group_Is_Connected value);
/**
- * Returns true if the group chat is currently connected or attempting to connect to other peers
- * in the group.
+ * Returns true if the group chat is currently connected or attempting to
+ * connect to other peers in the group.
*
* @param group_number The group number of the designated group.
*/
@@ -3714,7 +3367,8 @@ typedef enum Tox_Err_Group_Disconnect {
const char *tox_err_group_disconnect_to_string(Tox_Err_Group_Disconnect value);
/**
- * Disconnects from a group chat while retaining the group state and credentials.
+ * Disconnects from a group chat while retaining the group state and
+ * credentials.
*
* Returns true if we successfully disconnect from the group.
*
@@ -3743,17 +3397,22 @@ typedef enum Tox_Err_Group_Reconnect {
const char *tox_err_group_reconnect_to_string(Tox_Err_Group_Reconnect value);
+#ifndef TOX_HIDE_DEPRECATED
/**
* Reconnects to a group.
*
- * This function disconnects from all peers in the group, then attempts to reconnect with the group.
- * The caller's state is not changed (i.e. name, status, role, chat public key etc.).
+ * This function disconnects from all peers in the group, then attempts to
+ * reconnect with the group. The caller's state is not changed (i.e. name,
+ * status, role, chat public key etc.).
*
* @param group_number The group number of the group we wish to reconnect to.
*
* @return true on success.
+ *
+ * @deprecated Use `tox_group_join` instead.
*/
bool tox_group_reconnect(Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_Reconnect *error);
+#endif /* TOX_HIDE_DEPRECATED */
typedef enum Tox_Err_Group_Leave {
@@ -3783,14 +3442,16 @@ const char *tox_err_group_leave_to_string(Tox_Err_Group_Leave value);
/**
* Leaves a group.
*
- * This function sends a parting packet containing a custom (non-obligatory) message to all
- * peers in a group, and deletes the group from the chat array. All group state information is permanently
- * lost, including keys and role credentials.
+ * This function sends a parting packet containing a custom (non-obligatory)
+ * message to all peers in a group, and deletes the group from the chat array.
+ * All group state information is permanently lost, including keys and role
+ * credentials.
*
* @param group_number The group number of the group we wish to leave.
- * @param part_message The parting message to be sent to all the peers. Set to NULL if we do not wish to
- * send a parting message.
- * @param length The length of the parting message. Set to 0 if we do not wish to send a parting message.
+ * @param part_message The parting message to be sent to all the peers. Set to
+ * NULL if we do not wish to send a parting message.
+ * @param length The length of the parting message. Set to 0 if we do not wish
+ * to send a parting message.
*
* @return true if the group chat instance is successfully deleted.
*/
@@ -3859,10 +3520,11 @@ typedef enum Tox_Err_Group_Self_Name_Set {
const char *tox_err_group_self_name_set_to_string(Tox_Err_Group_Self_Name_Set value);
/**
- * Set the client's nickname for the group instance designated by the given group number.
+ * Set the client's nickname for the group instance designated by the given
+ * group number.
*
- * Nickname length cannot exceed TOX_MAX_NAME_LENGTH. If length is equal to zero or name is a NULL
- * pointer, the function call will fail.
+ * Nickname length cannot exceed TOX_MAX_NAME_LENGTH. If length is equal to
+ * zero or name is a NULL pointer, the function call will fail.
*
* @param name A byte array containing the new nickname.
* @param length The size of the name byte array.
@@ -3875,8 +3537,8 @@ bool tox_group_self_set_name(
Tox_Err_Group_Self_Name_Set *error);
/**
- * Return the length of the client's current nickname for the group instance designated
- * by group_number as passed to tox_group_self_set_name.
+ * Return the length of the client's current nickname for the group instance
+ * designated by group_number as passed to tox_group_self_set_name.
*
* If no nickname was set before calling this function, the name is empty,
* and this function returns 0.
@@ -3891,7 +3553,8 @@ size_t tox_group_self_get_name_size(const Tox *tox, Tox_Group_Number group_numbe
* If no nickname was set before calling this function, the name is empty,
* and this function has no effect.
*
- * Call tox_group_self_get_name_size to find out how much memory to allocate for the result.
+ * Call tox_group_self_get_name_size to find out how much memory to allocate for
+ * the result.
*
* @param name A valid memory location large enough to hold the nickname.
* If this parameter is NULL, the function has no effect.
@@ -3927,7 +3590,8 @@ typedef enum Tox_Err_Group_Self_Status_Set {
const char *tox_err_group_self_status_set_to_string(Tox_Err_Group_Self_Status_Set value);
/**
- * Set the client's status for the group instance. Status must be a Tox_User_Status.
+ * Set the client's status for the group instance. Status must be a
+ * Tox_User_Status.
*
* @return true on success.
*/
@@ -3953,13 +3617,16 @@ Tox_Group_Role tox_group_self_get_role(const Tox *tox, Tox_Group_Number group_nu
Tox_Group_Peer_Number tox_group_self_get_peer_id(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_Self_Query *error);
/**
- * Write the client's group public key designated by the given group number to a byte array.
+ * Write the client's group public key designated by the given group number to
+ * a byte array.
*
- * This key will be permanently tied to the client's identity for this particular group until
- * the client explicitly leaves the group. This key is the only way for other peers to reliably
- * identify the client across client restarts.
+ * This key will be permanently tied to the client's identity for this
+ * particular group until the client explicitly leaves the group. This key is
+ * the only way for other peers to reliably identify the client across client
+ * restarts.
*
- * `public_key` should have room for at least TOX_GROUP_PEER_PUBLIC_KEY_SIZE bytes.
+ * `public_key` should have room for at least TOX_GROUP_PEER_PUBLIC_KEY_SIZE
+ * bytes.
*
* @param public_key A valid memory region large enough to store the public key.
* If this parameter is NULL, this function call has no effect.
@@ -4000,8 +3667,8 @@ typedef enum Tox_Err_Group_Peer_Query {
const char *tox_err_group_peer_query_to_string(Tox_Err_Group_Peer_Query value);
/**
- * Return the length of the peer's name. If the group number or ID is invalid, the
- * return value is unspecified.
+ * Return the length of the peer's name. If the group number or ID is invalid,
+ * the return value is unspecified.
*
* @param group_number The group number of the group we wish to query.
* @param peer_id The ID of the peer whose name length we want to retrieve.
@@ -4016,7 +3683,8 @@ size_t tox_group_peer_get_name_size(const Tox *tox, Tox_Group_Number group_numbe
* Write the name of the peer designated by the given ID to a byte
* array.
*
- * Call tox_group_peer_get_name_size to determine the allocation size for the `name` parameter.
+ * Call tox_group_peer_get_name_size to determine the allocation size for the
+ * `name` parameter.
*
* The data written to `name` is equal to the data received by the last
* `group_peer_name` callback.
@@ -4045,8 +3713,8 @@ Tox_User_Status tox_group_peer_get_status(const Tox *tox, Tox_Group_Number group
Tox_Err_Group_Peer_Query *error);
/**
- * Return the peer's role (user/moderator/founder...). If the ID or group number is
- * invalid, the return value is unspecified.
+ * Return the peer's role (user/moderator/founder...). If the ID or group number
+ * is invalid, the return value is unspecified.
*
* @param group_number The group number of the group we wish to query.
* @param peer_id The ID of the peer whose role we wish to query.
@@ -4060,8 +3728,9 @@ Tox_Group_Role tox_group_peer_get_role(const Tox *tox, Tox_Group_Number group_nu
/**
* Return the type of connection we have established with a peer.
*
- * If `peer_id` designates ourself, the return value indicates whether we're capable
- * of making UDP connections with other peers, or are limited to TCP connections.
+ * If `peer_id` designates ourself, the return value indicates whether we're
+ * capable of making UDP connections with other peers, or are limited to TCP
+ * connections.
*
* @param group_number The group number of the group we wish to query.
* @param peer_id The ID of the peer whose connection status we wish to query.
@@ -4070,13 +3739,15 @@ Tox_Connection tox_group_peer_get_connection_status(const Tox *tox, Tox_Group_Nu
Tox_Err_Group_Peer_Query *error);
/**
- * Write the group public key with the designated peer_id for the designated group number to public_key.
+ * Write the group public key with the designated peer_id for the designated
+ * group number to public_key.
*
- * This key will be permanently tied to a particular peer until they explicitly leave the group and is
- * the only way to reliably identify the same peer across client restarts.
+ * This key will be permanently tied to a particular peer until they explicitly
+ * leave the group and is the only way to reliably identify the same peer across
+ * client restarts.
*
- * `public_key` should have room for at least TOX_GROUP_PEER_PUBLIC_KEY_SIZE bytes. If `public_key` is null
- * this function has no effect.
+ * `public_key` should have room for at least TOX_GROUP_PEER_PUBLIC_KEY_SIZE
+ * bytes. If `public_key` is NULL this function has no effect.
*
* @param group_number The group number of the group we wish to query.
* @param peer_id The ID of the peer whose public key we wish to retrieve.
@@ -4090,14 +3761,15 @@ bool tox_group_peer_get_public_key(
uint8_t public_key[TOX_PUBLIC_KEY_SIZE], Tox_Err_Group_Peer_Query *error);
/**
- * @param group_number The group number of the group the name change is intended for.
+ * @param group_number The group number of the group the name change is intended
+ * for.
* @param peer_id The ID of the peer who has changed their name.
* @param name The name data.
- * @param length The length of the name.
+ * @param name_length The length of the name.
*/
typedef void tox_group_peer_name_cb(
Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id,
- const uint8_t name[], size_t length, void *user_data);
+ const uint8_t name[], size_t name_length, void *user_data);
/**
* Set the callback for the `group_peer_name` event. Pass NULL to unset.
@@ -4107,7 +3779,8 @@ typedef void tox_group_peer_name_cb(
void tox_callback_group_peer_name(Tox *tox, tox_group_peer_name_cb *callback);
/**
- * @param group_number The group number of the group the status change is intended for.
+ * @param group_number The group number of the group the status change is
+ * intended for.
* @param peer_id The ID of the peer who has changed their status.
* @param status The new status of the peer.
*/
@@ -4130,21 +3803,21 @@ void tox_callback_group_peer_status(Tox *tox, tox_group_peer_status_cb *callback
/**
* General error codes for group state get and size functions.
*/
-typedef enum Tox_Err_Group_State_Queries {
+typedef enum Tox_Err_Group_State_Query {
/**
* The function returned successfully.
*/
- TOX_ERR_GROUP_STATE_QUERIES_OK,
+ TOX_ERR_GROUP_STATE_QUERY_OK,
/**
* The group number passed did not designate a valid group.
*/
- TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND,
+ TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND,
-} Tox_Err_Group_State_Queries;
+} Tox_Err_Group_State_Query;
-const char *tox_err_group_state_queries_to_string(Tox_Err_Group_State_Queries value);
+const char *tox_err_group_state_query_to_string(Tox_Err_Group_State_Query value);
/**
* Error codes for group topic setting.
@@ -4172,7 +3845,8 @@ typedef enum Tox_Err_Group_Topic_Set {
TOX_ERR_GROUP_TOPIC_SET_PERMISSIONS,
/**
- * The packet could not be created. This error is usually related to cryptographic signing.
+ * The packet could not be created. This error is usually related to
+ * cryptographic signing.
*/
TOX_ERR_GROUP_TOPIC_SET_FAIL_CREATE,
@@ -4193,8 +3867,8 @@ const char *tox_err_group_topic_set_to_string(Tox_Err_Group_Topic_Set value);
/**
* Set the group topic and broadcast it to the rest of the group.
*
- * topic length cannot be longer than TOX_GROUP_MAX_TOPIC_LENGTH. If length is equal to zero or
- * topic is set to NULL, the topic will be unset.
+ * Topic length cannot be longer than TOX_GROUP_MAX_TOPIC_LENGTH. If the length
+ * is equal to zero or topic is set to NULL, the topic will be unset.
*
* @return true on success.
*/
@@ -4210,12 +3884,13 @@ bool tox_group_set_topic(
* The return value is equal to the `length` argument received by the last
* `group_topic` callback.
*/
-size_t tox_group_get_topic_size(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Queries *error);
+size_t tox_group_get_topic_size(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Query *error);
/**
* Write the topic designated by the given group number to a byte array.
*
- * Call tox_group_get_topic_size to determine the allocation size for the `topic` parameter.
+ * Call tox_group_get_topic_size to determine the allocation size for the
+ * `topic` parameter.
*
* The data written to `topic` is equal to the data received by the last
* `group_topic` callback.
@@ -4227,18 +3902,19 @@ size_t tox_group_get_topic_size(const Tox *tox, Tox_Group_Number group_number, T
*/
bool tox_group_get_topic(
const Tox *tox, Tox_Group_Number group_number,
- uint8_t topic[], Tox_Err_Group_State_Queries *error);
+ uint8_t topic[], Tox_Err_Group_State_Query *error);
/**
- * @param group_number The group number of the group the topic change is intended for.
- * @param peer_id The ID of the peer who changed the topic. If the peer who set the topic
- * is not present in our peer list this value will be set to 0.
+ * @param group_number The group number of the group the topic change is
+ * intended for.
+ * @param peer_id The ID of the peer who changed the topic. If the peer who set
+ * the topic is not present in our peer list this value will be set to 0.
* @param topic The topic data.
- * @param length The topic length.
+ * @param topic_length The topic length.
*/
typedef void tox_group_topic_cb(
Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id,
- const uint8_t topic[], size_t length,
+ const uint8_t topic[], size_t topic_length,
void *user_data);
/**
@@ -4252,12 +3928,14 @@ void tox_callback_group_topic(Tox *tox, tox_group_topic_cb *callback);
* Return the length of the group name. If the group number is invalid, the
* return value is unspecified.
*/
-size_t tox_group_get_name_size(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Queries *error);
+size_t tox_group_get_name_size(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Query *error);
/**
- * Write the name of the group designated by the given group number to a byte array.
+ * Write the name of the group designated by the given group number to a byte
+ * array.
*
- * Call tox_group_get_name_size to determine the allocation size for the `name` parameter.
+ * Call tox_group_get_name_size to determine the allocation size for the `name`
+ * parameter.
*
* @param name A valid memory region large enough to store the group name.
* If this parameter is NULL, this function call has no effect.
@@ -4266,7 +3944,7 @@ size_t tox_group_get_name_size(const Tox *tox, Tox_Group_Number group_number, To
*/
bool tox_group_get_name(
const Tox *tox, Tox_Group_Number group_number,
- uint8_t name[], Tox_Err_Group_State_Queries *error);
+ uint8_t name[], Tox_Err_Group_State_Query *error);
/**
* Write the Chat ID designated by the given group number to a byte array.
@@ -4280,7 +3958,7 @@ bool tox_group_get_name(
*/
bool tox_group_get_chat_id(
const Tox *tox, Tox_Group_Number group_number, uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE],
- Tox_Err_Group_State_Queries *error);
+ Tox_Err_Group_State_Query *error);
/**
* Return the number of groups in the Tox chats array.
@@ -4288,19 +3966,21 @@ bool tox_group_get_chat_id(
uint32_t tox_group_get_number_groups(const Tox *tox);
/**
- * Return the privacy state of the group designated by the given group number. If group number
- * is invalid, the return value is unspecified.
+ * Return the privacy state of the group designated by the given group number.
+ * If group number is invalid, the return value is unspecified.
*
* The value returned is equal to the data received by the last
* `group_privacy_state` callback.
*
- * @see the `Group chat founder controls` section for the respective set function.
+ * @see the `Group chat Founder controls` section for the respective set
+ * function.
*/
Tox_Group_Privacy_State tox_group_get_privacy_state(const Tox *tox, Tox_Group_Number group_number,
- Tox_Err_Group_State_Queries *error);
+ Tox_Err_Group_State_Query *error);
/**
- * @param group_number The group number of the group the privacy state is intended for.
+ * @param group_number The group number of the group the privacy state is
+ * intended for.
* @param privacy_state The new privacy state.
*/
typedef void tox_group_privacy_state_cb(Tox *tox, Tox_Group_Number group_number, Tox_Group_Privacy_State privacy_state,
@@ -4314,18 +3994,21 @@ typedef void tox_group_privacy_state_cb(Tox *tox, Tox_Group_Number group_number,
void tox_callback_group_privacy_state(Tox *tox, tox_group_privacy_state_cb *callback);
/**
- * Return the voice state of the group designated by the given group number. If group number
- * is invalid, the return value is unspecified.
+ * Return the voice state of the group designated by the given group number. If
+ * group number is invalid, the return value is unspecified.
*
- * The value returned is equal to the data received by the last `group_voice_state` callback.
+ * The value returned is equal to the data received by the last
+ * `group_voice_state` callback.
*
- * @see the `Group chat founder controls` section for the respective set function.
+ * @see the `Group chat Founder controls` section for the respective set
+ * function.
*/
Tox_Group_Voice_State tox_group_get_voice_state(const Tox *tox, Tox_Group_Number group_number,
- Tox_Err_Group_State_Queries *error);
+ Tox_Err_Group_State_Query *error);
/**
- * @param group_number The group number of the group the voice state change is intended for.
+ * @param group_number The group number of the group the voice state change is
+ * intended for.
* @param voice_state The new voice state.
*/
typedef void tox_group_voice_state_cb(Tox *tox, Tox_Group_Number group_number, Tox_Group_Voice_State voice_state,
@@ -4339,19 +4022,22 @@ typedef void tox_group_voice_state_cb(Tox *tox, Tox_Group_Number group_number, T
void tox_callback_group_voice_state(Tox *tox, tox_group_voice_state_cb *callback);
/**
- * Return the topic lock status of the group designated by the given group number. If group number
+ * Return the topic lock status of the group designated by the given group
+ * number. If group number
* is invalid, the return value is unspecified.
*
* The value returned is equal to the data received by the last
* `group_topic_lock` callback.
*
- * @see the `Group chat founder contols` section for the respective set function.
+ * @see the `Group chat Founder controls` section for the respective set
+ * function.
*/
Tox_Group_Topic_Lock tox_group_get_topic_lock(const Tox *tox, Tox_Group_Number group_number,
- Tox_Err_Group_State_Queries *error);
+ Tox_Err_Group_State_Query *error);
/**
- * @param group_number The group number of the group for which the topic lock has changed.
+ * @param group_number The group number of the group for which the topic lock
+ * has changed.
* @param topic_lock The new topic lock state.
*/
typedef void tox_group_topic_lock_cb(Tox *tox, Tox_Group_Number group_number, Tox_Group_Topic_Lock topic_lock, void *user_data);
@@ -4364,18 +4050,21 @@ typedef void tox_group_topic_lock_cb(Tox *tox, Tox_Group_Number group_number, To
void tox_callback_group_topic_lock(Tox *tox, tox_group_topic_lock_cb *callback);
/**
- * Return the maximum number of peers allowed for the group designated by the given group number.
- * If the group number is invalid, the return value is unspecified.
+ * Return the maximum number of peers allowed for the group designated by the
+ * given group number. If the group number is invalid, the return value is
+ * unspecified.
*
* The value returned is equal to the data received by the last
* `group_peer_limit` callback.
*
- * @see the `Group chat founder controls` section for the respective set function.
+ * @see the `Group chat Founder controls` section for the respective set
+ * function.
*/
-uint16_t tox_group_get_peer_limit(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Queries *error);
+uint16_t tox_group_get_peer_limit(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Query *error);
/**
- * @param group_number The group number of the group for which the peer limit has changed.
+ * @param group_number The group number of the group for which the peer limit
+ * has changed.
* @param peer_limit The new peer limit for the group.
*/
typedef void tox_group_peer_limit_cb(Tox *tox, Tox_Group_Number group_number, uint32_t peer_limit, void *user_data);
@@ -4383,7 +4072,8 @@ typedef void tox_group_peer_limit_cb(Tox *tox, Tox_Group_Number group_number, ui
/**
* Set the callback for the `group_peer_limit` event. Pass NULL to unset.
*
- * This event is triggered when the group founder changes the maximum peer limit.
+ * This event is triggered when the group founder changes the maximum peer
+ * limit.
*/
void tox_callback_group_peer_limit(Tox *tox, tox_group_peer_limit_cb *callback);
@@ -4391,35 +4081,39 @@ void tox_callback_group_peer_limit(Tox *tox, tox_group_peer_limit_cb *callback);
* Return the length of the group password. If the group number is invalid, the
* return value is unspecified.
*/
-size_t tox_group_get_password_size(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Queries *error);
+size_t tox_group_get_password_size(const Tox *tox, Tox_Group_Number group_number, Tox_Err_Group_State_Query *error);
/**
- * Write the password for the group designated by the given group number to a byte array.
+ * Write the password for the group designated by the given group number to a
+ * byte array.
*
- * Call tox_group_get_password_size to determine the allocation size for the `password` parameter.
+ * Call tox_group_get_password_size to determine the allocation size for the
+ * `password` parameter.
*
- * The data received is equal to the data received by the last
- * `group_password` callback.
+ * The data received is equal to the data received by the last `group_password`
+ * callback.
*
- * @see the `Group chat founder controls` section for the respective set function.
+ * @see the `Group chat Founder controls` section for the respective set
+ * function.
*
- * @param password A valid memory region large enough to store the group password.
- * If this parameter is NULL, this function call has no effect.
+ * @param password A valid memory region large enough to store the group
+ * password. If this parameter is NULL, this function call has no effect.
*
* @return true on success.
*/
bool tox_group_get_password(
const Tox *tox, Tox_Group_Number group_number, uint8_t password[],
- Tox_Err_Group_State_Queries *error);
+ Tox_Err_Group_State_Query *error);
/**
- * @param group_number The group number of the group for which the password has changed.
+ * @param group_number The group number of the group for which the password has
+ * changed.
* @param password The new group password.
- * @param length The length of the password.
+ * @param password_length The length of the password.
*/
typedef void tox_group_password_cb(
Tox *tox, Tox_Group_Number group_number,
- const uint8_t password[], size_t length,
+ const uint8_t password[], size_t password_length,
void *user_data);
/**
@@ -4453,7 +4147,7 @@ typedef enum Tox_Err_Group_Send_Message {
TOX_ERR_GROUP_SEND_MESSAGE_TOO_LONG,
/**
- * The message pointer is null or length is zero.
+ * The message pointer is NULL or length is zero.
*/
TOX_ERR_GROUP_SEND_MESSAGE_EMPTY,
@@ -4487,12 +4181,13 @@ const char *tox_err_group_send_message_to_string(Tox_Err_Group_Send_Message valu
* This function creates a group message packet and pushes it into the send
* queue.
*
- * The message length may not exceed TOX_GROUP_MAX_MESSAGE_LENGTH. Larger messages
- * must be split by the client and sent as separate messages. Other clients can
- * then reassemble the fragments. Messages may not be empty.
+ * The message length may not exceed TOX_GROUP_MAX_MESSAGE_LENGTH. Larger
+ * messages must be split by the client and sent as separate messages. Other
+ * clients can then reassemble the fragments. Messages may not be empty.
*
- * @param group_number The group number of the group the message is intended for.
- * @param type Message type (normal, action, ...).
+ * @param group_number The group number of the group the message is intended
+ * for.
+ * @param message_type Message type (normal, action, ...).
* @param message A non-NULL pointer to the first element of a byte array
* containing the message text.
* @param length Length of the message to be sent.
@@ -4501,7 +4196,7 @@ const char *tox_err_group_send_message_to_string(Tox_Err_Group_Send_Message valu
* returned message ID value will be undefined.
*/
Tox_Group_Message_Id tox_group_send_message(
- const Tox *tox, Tox_Group_Number group_number, Tox_Message_Type type,
+ const Tox *tox, Tox_Group_Number group_number, Tox_Message_Type message_type,
const uint8_t message[], size_t length,
Tox_Err_Group_Send_Message *error);
@@ -4528,11 +4223,16 @@ typedef enum Tox_Err_Group_Send_Private_Message {
TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_TOO_LONG,
/**
- * The message pointer is null or length is zero.
+ * The message pointer is NULL or length is zero.
*/
TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_EMPTY,
/**
+ * The message type is invalid.
+ */
+ TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_BAD_TYPE,
+
+ /**
* The caller does not have the required permissions to send group messages.
*/
TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_PERMISSIONS,
@@ -4547,11 +4247,6 @@ typedef enum Tox_Err_Group_Send_Private_Message {
*/
TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_DISCONNECTED,
- /**
- * The message type is invalid.
- */
- TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_BAD_TYPE,
-
} Tox_Err_Group_Send_Private_Message;
const char *tox_err_group_send_private_message_to_string(Tox_Err_Group_Send_Private_Message value);
@@ -4559,23 +4254,25 @@ const char *tox_err_group_send_private_message_to_string(Tox_Err_Group_Send_Priv
/**
* Send a text chat message to the specified peer in the specified group.
*
- * This function creates a group private message packet and pushes it into the send
- * queue.
+ * This function creates a group private message packet and pushes it into the
+ * send queue.
*
- * The message length may not exceed TOX_GROUP_MAX_MESSAGE_LENGTH. Larger messages
- * must be split by the client and sent as separate messages. Other clients can
- * then reassemble the fragments. Messages may not be empty.
+ * The message length may not exceed TOX_GROUP_MAX_MESSAGE_LENGTH. Larger
+ * messages must be split by the client and sent as separate messages. Other
+ * clients can then reassemble the fragments. Messages may not be empty.
*
- * @param group_number The group number of the group the message is intended for.
+ * @param group_number The group number of the group the message is intended
+ * for.
* @param peer_id The ID of the peer the message is intended for.
+ * @param message_type The type of message (normal, action, ...).
* @param message A non-NULL pointer to the first element of a byte array
* containing the message text.
* @param length Length of the message to be sent.
*
* @return true on success.
*/
-bool tox_group_send_private_message(
- const Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Message_Type type,
+Tox_Group_Message_Id tox_group_send_private_message(
+ const Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Message_Type message_type,
const uint8_t message[], size_t length,
Tox_Err_Group_Send_Private_Message *error);
@@ -4599,16 +4296,11 @@ typedef enum Tox_Err_Group_Send_Custom_Packet {
TOX_ERR_GROUP_SEND_CUSTOM_PACKET_TOO_LONG,
/**
- * The message pointer is null or length is zero.
+ * The message pointer is NULL or length is zero.
*/
TOX_ERR_GROUP_SEND_CUSTOM_PACKET_EMPTY,
/**
- * The caller does not have the required permissions to send group messages.
- */
- TOX_ERR_GROUP_SEND_CUSTOM_PACKET_PERMISSIONS,
-
- /**
* The group is disconnected.
*/
TOX_ERR_GROUP_SEND_CUSTOM_PACKET_DISCONNECTED,
@@ -4626,15 +4318,17 @@ const char *tox_err_group_send_custom_packet_to_string(Tox_Err_Group_Send_Custom
/**
* Send a custom packet to the group.
*
- * If lossless is true the packet will be lossless. Lossless packet behaviour is comparable
- * to TCP (reliability, arrive in order) but with packets instead of a stream.
+ * If lossless is true the packet will be lossless. Lossless packet behaviour is
+ * comparable to TCP (reliability, arrive in order) but with packets instead of
+ * a stream.
*
- * If lossless is false, the packet will be lossy. Lossy packets behave like UDP packets,
- * meaning they might never reach the other side or might arrive more than once (if someone
- * is messing with the connection) or might arrive in the wrong order.
+ * If lossless is false, the packet will be lossy. Lossy packets behave like UDP
+ * packets, meaning they might never reach the other side or might arrive more
+ * than once (if someone is messing with the connection) or might arrive in the
+ * wrong order.
*
- * Unless latency is an issue or message reliability is not important, it is recommended that you use
- * lossless packets.
+ * Unless latency is an issue or message reliability is not important, it is
+ * recommended that you use lossless packets.
*
* The message length may not exceed TOX_MAX_CUSTOM_PACKET_SIZE. Larger packets
* must be split by the client and sent as separate packets. Other clients can
@@ -4672,7 +4366,7 @@ typedef enum Tox_Err_Group_Send_Custom_Private_Packet {
TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_TOO_LONG,
/**
- * The message pointer is null or length is zero.
+ * The message pointer is NULL or length is zero.
*/
TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_EMPTY,
@@ -4682,11 +4376,6 @@ typedef enum Tox_Err_Group_Send_Custom_Private_Packet {
TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_PEER_NOT_FOUND,
/**
- * The caller does not have the required permissions to send group messages.
- */
- TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_PERMISSIONS,
-
- /**
* The packet failed to send.
*/
TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_FAIL_SEND,
@@ -4703,15 +4392,17 @@ const char *tox_err_group_send_custom_private_packet_to_string(Tox_Err_Group_Sen
/**
* Send a custom private packet to a designated peer in the group.
*
- * If lossless is true the packet will be lossless. Lossless packet behaviour is comparable
- * to TCP (reliability, arrive in order) but with packets instead of a stream.
+ * If lossless is true the packet will be lossless. Lossless packet behaviour is
+ * comparable to TCP (reliability, arrive in order) but with packets instead of
+ * a stream.
*
- * If lossless is false, the packet will be lossy. Lossy packets behave like UDP packets,
- * meaning they might never reach the other side or might arrive more than once (if someone
- * is messing with the connection) or might arrive in the wrong order.
+ * If lossless is false, the packet will be lossy. Lossy packets behave like UDP
+ * packets, meaning they might never reach the other side or might arrive more
+ * than once (if someone is messing with the connection) or might arrive in the
+ * wrong order.
*
- * Unless latency is an issue or message reliability is not important, it is recommended that you use
- * lossless packets.
+ * Unless latency is an issue or message reliability is not important, it is
+ * recommended that you use lossless packets.
*
* The packet length may not exceed TOX_MAX_CUSTOM_PACKET_SIZE. Larger packets
* must be split by the client and sent as separate packets. Other clients can
@@ -4736,16 +4427,18 @@ bool tox_group_send_custom_private_packet(const Tox *tox, Tox_Group_Number group
******************************************************************************/
/**
- * @param group_number The group number of the group the message is intended for.
+ * @param group_number The group number of the group the message is intended
+ * for.
* @param peer_id The ID of the peer who sent the message.
- * @param type The type of message (normal, action, ...).
+ * @param message_type The type of message (normal, action, ...).
* @param message The message data.
- * @param message_id A pseudo message id that clients can use to uniquely identify this group message.
- * @param length The length of the message.
+ * @param message_length The length of the message.
+ * @param message_id A pseudo message id that clients can use to uniquely
+ * identify this group message.
*/
typedef void tox_group_message_cb(
- Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Message_Type type,
- const uint8_t message[], size_t length, Tox_Group_Message_Id message_id, void *user_data);
+ Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Message_Type message_type,
+ const uint8_t message[], size_t message_length, Tox_Group_Message_Id message_id, void *user_data);
/**
* Set the callback for the `group_message` event. Pass NULL to unset.
@@ -4755,14 +4448,18 @@ typedef void tox_group_message_cb(
void tox_callback_group_message(Tox *tox, tox_group_message_cb *callback);
/**
- * @param group_number The group number of the group the private message is intended for.
+ * @param group_number The group number of the group the private message is
+ * intended for.
* @param peer_id The ID of the peer who sent the private message.
+ * @param message_type The type of message (normal, action, ...).
* @param message The message data.
- * @param length The length of the message.
+ * @param message_length The length of the message.
+ * @param message_id A pseudo message id that clients can use to uniquely
+ * identify this group message.
*/
typedef void tox_group_private_message_cb(
- Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Message_Type type,
- const uint8_t message[], size_t length, void *user_data);
+ Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Message_Type message_type,
+ const uint8_t message[], size_t message_length, Tox_Group_Message_Id message_id, void *user_data);
/**
* Set the callback for the `group_private_message` event. Pass NULL to unset.
@@ -4775,11 +4472,11 @@ void tox_callback_group_private_message(Tox *tox, tox_group_private_message_cb *
* @param group_number The group number of the group the packet is intended for.
* @param peer_id The ID of the peer who sent the packet.
* @param data The packet data.
- * @param length The length of the data.
+ * @param data_length The length of the data.
*/
typedef void tox_group_custom_packet_cb(
Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id,
- const uint8_t data[], size_t length, void *user_data);
+ const uint8_t data[], size_t data_length, void *user_data);
/**
* Set the callback for the `group_custom_packet` event. Pass NULL to unset.
@@ -4792,14 +4489,15 @@ void tox_callback_group_custom_packet(Tox *tox, tox_group_custom_packet_cb *call
* @param group_number The group number of the group the packet is intended for.
* @param peer_id The ID of the peer who sent the packet.
* @param data The packet data.
- * @param length The length of the data.
+ * @param data_length The length of the data.
*/
typedef void tox_group_custom_private_packet_cb(
Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id,
- const uint8_t data[], size_t length, void *user_data);
+ const uint8_t data[], size_t data_length, void *user_data);
/**
- * Set the callback for the `group_custom_private_packet` event. Pass NULL to unset.
+ * Set the callback for the `group_custom_private_packet` event. Pass NULL to
+ * unset.
*
* This event is triggered when the client receives a custom private packet.
*/
@@ -4829,7 +4527,8 @@ typedef enum Tox_Err_Group_Invite_Friend {
TOX_ERR_GROUP_INVITE_FRIEND_FRIEND_NOT_FOUND,
/**
- * Creation of the invite packet failed. This indicates a network related error.
+ * Creation of the invite packet failed. This indicates a network related
+ * error.
*/
TOX_ERR_GROUP_INVITE_FRIEND_INVITE_FAIL,
@@ -4850,10 +4549,13 @@ const char *tox_err_group_invite_friend_to_string(Tox_Err_Group_Invite_Friend va
/**
* Invite a friend to a group.
*
- * This function creates an invite request packet and pushes it to the send queue.
+ * This function creates an invite request packet and pushes it to the send
+ * queue.
*
- * @param group_number The group number of the group the message is intended for.
- * @param friend_number The friend number of the friend the invite is intended for.
+ * @param group_number The group number of the group the message is intended
+ * for.
+ * @param friend_number The friend number of the friend the invite is intended
+ * for.
*
* @return true on success.
*/
@@ -4889,36 +4591,44 @@ typedef enum Tox_Err_Group_Invite_Accept {
TOX_ERR_GROUP_INVITE_ACCEPT_EMPTY,
/**
- * Failed to set password. This usually occurs if the password exceeds TOX_GROUP_MAX_PASSWORD_SIZE.
+ * Failed to set password. This usually occurs if the password exceeds
+ * TOX_GROUP_MAX_PASSWORD_SIZE.
*/
TOX_ERR_GROUP_INVITE_ACCEPT_PASSWORD,
/**
- * There was a core error when initiating the group.
+ * The friend number passed did not designate a valid friend.
*/
- TOX_ERR_GROUP_INVITE_ACCEPT_CORE,
+ TOX_ERR_GROUP_INVITE_ACCEPT_FRIEND_NOT_FOUND,
/**
* Packet failed to send.
*/
TOX_ERR_GROUP_INVITE_ACCEPT_FAIL_SEND,
+ /**
+ * Invite data or name is NULL.
+ */
+ TOX_ERR_GROUP_INVITE_ACCEPT_NULL,
+
} Tox_Err_Group_Invite_Accept;
const char *tox_err_group_invite_accept_to_string(Tox_Err_Group_Invite_Accept value);
/**
- * Accept an invite to a group chat that the client previously received from a friend. The invite
- * is only valid while the inviter is present in the group.
+ * Accept an invite to a group chat that the client previously received from a
+ * friend. The invite is only valid while the inviter is present in the group.
*
* @param invite_data The invite data received from the `group_invite` event.
* @param length The length of the invite data.
* @param name The name of the peer joining the group.
- * @param name_length The length of the peer's name. This must be greater than zero and no larger
- * than TOX_MAX_NAME_LENGTH.
- * @param password The password required to join the group. Set to NULL if no password is required.
- * @param password_length The length of the password. If password_length is equal to zero, the password
- * parameter will be ignored. password_length must be no larger than TOX_GROUP_MAX_PASSWORD_SIZE.
+ * @param name_length The length of the peer's name. This must be greater than
+ * zero and no larger than TOX_MAX_NAME_LENGTH.
+ * @param password The password required to join the group. Set to NULL if no
+ * password is required.
+ * @param password_length The length of the password. If password_length is
+ * equal to zero, the password parameter will be ignored. password_length
+ * must be no larger than TOX_GROUP_MAX_PASSWORD_SIZE.
*
* @return the group_number on success, UINT32_MAX on failure.
*/
@@ -4932,26 +4642,30 @@ Tox_Group_Number tox_group_invite_accept(
/**
* @param friend_number The friend number of the contact who sent the invite.
* @param invite_data The invite data.
- * @param length The length of invite_data.
+ * @param invite_data_length The length of invite_data.
+ * @param group_name The name of the group. In conferences, this is "title".
+ * @param group_name_length The length of the group name.
*/
typedef void tox_group_invite_cb(
Tox *tox, Tox_Friend_Number friend_number,
- const uint8_t invite_data[], size_t length,
+ const uint8_t invite_data[], size_t invite_data_length,
const uint8_t group_name[], size_t group_name_length,
void *user_data);
/**
* Set the callback for the `group_invite` event. Pass NULL to unset.
*
- * This event is triggered when the client receives a group invite from a friend. The client must store
- * invite_data which is used to join the group via tox_group_invite_accept.
+ * This event is triggered when the client receives a group invite from a
+ * friend. The client must store invite_data which is used to join the group
+ * via tox_group_invite_accept.
*/
void tox_callback_group_invite(Tox *tox, tox_group_invite_cb *callback);
/**
- * @param group_number The group number of the group in which a new peer has joined.
- * @param peer_id The permanent ID of the new peer. This id should not be relied on for
- * client behaviour and should be treated as a random value.
+ * @param group_number The group number of the group in which a new peer has
+ * joined.
+ * @param peer_id The permanent ID of the new peer. This id should not be relied
+ * on for client behaviour and should be treated as a random value.
*/
typedef void tox_group_peer_join_cb(Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, void *user_data);
@@ -4963,7 +4677,8 @@ typedef void tox_group_peer_join_cb(Tox *tox, Tox_Group_Number group_number, Tox
void tox_callback_group_peer_join(Tox *tox, tox_group_peer_join_cb *callback);
/**
- * Represents peer exit events. These should be used with the `group_peer_exit` event.
+ * Represents peer exit events. These should be used with the `group_peer_exit`
+ * event.
*/
typedef enum Tox_Group_Exit_Type {
@@ -4983,8 +4698,9 @@ typedef enum Tox_Group_Exit_Type {
TOX_GROUP_EXIT_TYPE_DISCONNECTED,
/**
- * Your connection with all peers has been severed. This will occur when you are kicked from
- * a group, rejoin a group, or manually disconnect from a group.
+ * Your connection with all peers has been severed. This will occur when you
+ * are kicked from a group, rejoin a group, or manually disconnect from a
+ * group.
*/
TOX_GROUP_EXIT_TYPE_SELF_DISCONNECTED,
@@ -5004,8 +4720,8 @@ const char *tox_group_exit_type_to_string(Tox_Group_Exit_Type value);
/**
* @param group_number The group number of the group in which a peer has left.
- * @param peer_id The ID of the peer who left the group. This ID no longer designates a valid peer
- * and cannot be used for API calls.
+ * @param peer_id The ID of the peer who left the group. This ID no longer
+ * designates a valid peer and cannot be used for API calls.
* @param exit_type The type of exit event. One of Tox_Group_Exit_Type.
* @param name The nickname of the peer who left the group.
* @param name_length The length of the peer name.
@@ -5032,14 +4748,14 @@ typedef void tox_group_self_join_cb(Tox *tox, Tox_Group_Number group_number, voi
/**
* Set the callback for the `group_self_join` event. Pass NULL to unset.
*
- * This event is triggered when the client has successfully joined a group. Use this to initialize
- * any group information the client may need.
+ * This event is triggered when the client has successfully joined a group. Use
+ * this to initialize any group information the client may need.
*/
void tox_callback_group_self_join(Tox *tox, tox_group_self_join_cb *callback);
/**
- * Represents types of failed group join attempts. These are used in the tox_callback_group_rejected
- * callback when a peer fails to join a group.
+ * Represents types of failed group join attempts. These are used in the
+ * tox_callback_group_rejected callback when a peer fails to join a group.
*/
typedef enum Tox_Group_Join_Fail {
@@ -5054,8 +4770,8 @@ typedef enum Tox_Group_Join_Fail {
TOX_GROUP_JOIN_FAIL_INVALID_PASSWORD,
/**
- * The join attempt failed due to an unspecified error. This often occurs when the group is
- * not found in the DHT.
+ * The join attempt failed due to an unspecified error. This often occurs
+ * when the group is not found in the DHT.
*/
TOX_GROUP_JOIN_FAIL_UNKNOWN,
@@ -5064,7 +4780,8 @@ typedef enum Tox_Group_Join_Fail {
const char *tox_group_join_fail_to_string(Tox_Group_Join_Fail value);
/**
- * @param group_number The group number of the group for which the join has failed.
+ * @param group_number The group number of the group for which the join has
+ * failed.
* @param fail_type The type of group rejection.
*/
typedef void tox_group_join_fail_cb(Tox *tox, Tox_Group_Number group_number, Tox_Group_Join_Fail fail_type, void *user_data);
@@ -5078,289 +4795,306 @@ void tox_callback_group_join_fail(Tox *tox, tox_group_join_fail_cb *callback);
/*******************************************************************************
*
- * :: Group chat founder controls (these only work for the group founder)
+ * :: Group chat Founder controls
*
******************************************************************************/
-typedef enum Tox_Err_Group_Founder_Set_Password {
+typedef enum Tox_Err_Group_Set_Password {
/**
* The function returned successfully.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK,
+ TOX_ERR_GROUP_SET_PASSWORD_OK,
/**
* The group number passed did not designate a valid group.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_GROUP_NOT_FOUND,
+ TOX_ERR_GROUP_SET_PASSWORD_GROUP_NOT_FOUND,
/**
* The caller does not have the required permissions to set the password.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_PERMISSIONS,
+ TOX_ERR_GROUP_SET_PASSWORD_PERMISSIONS,
/**
* Password length exceeded TOX_GROUP_MAX_PASSWORD_SIZE.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_TOO_LONG,
+ TOX_ERR_GROUP_SET_PASSWORD_TOO_LONG,
/**
* The packet failed to send.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_FAIL_SEND,
+ TOX_ERR_GROUP_SET_PASSWORD_FAIL_SEND,
/**
* The function failed to allocate enough memory for the operation.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_MALLOC,
+ TOX_ERR_GROUP_SET_PASSWORD_MALLOC,
/**
* The group is disconnected.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_DISCONNECTED,
+ TOX_ERR_GROUP_SET_PASSWORD_DISCONNECTED,
-} Tox_Err_Group_Founder_Set_Password;
+} Tox_Err_Group_Set_Password;
-const char *tox_err_group_founder_set_password_to_string(Tox_Err_Group_Founder_Set_Password value);
+const char *tox_err_group_set_password_to_string(Tox_Err_Group_Set_Password value);
/**
* Set or unset the group password.
*
- * This function sets the groups password, creates a new group shared state including the change,
- * and distributes it to the rest of the group.
+ * This function allows Founders to set or unset a group password. It will
+ * create a new group shared state including the change and distribute it to the
+ * rest of the group.
*
- * @param group_number The group number of the group for which we wish to set the password.
- * @param password The password we want to set. Set password to NULL to unset the password.
- * @param length The length of the password. length must be no longer than TOX_GROUP_MAX_PASSWORD_SIZE.
+ * @param group_number The group number of the group for which we wish to set
+ * the password.
+ * @param password The password we want to set. Set password to NULL to unset
+ * the password.
+ * @param length The length of the password. length must be no longer than
+ * TOX_GROUP_MAX_PASSWORD_SIZE.
*
* @return true on success.
*/
-bool tox_group_founder_set_password(
+bool tox_group_set_password(
Tox *tox, Tox_Group_Number group_number,
const uint8_t password[], size_t length,
- Tox_Err_Group_Founder_Set_Password *error);
+ Tox_Err_Group_Set_Password *error);
-typedef enum Tox_Err_Group_Founder_Set_Topic_Lock {
+typedef enum Tox_Err_Group_Set_Topic_Lock {
/**
* The function returned successfully.
*/
- TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK,
+ TOX_ERR_GROUP_SET_TOPIC_LOCK_OK,
/**
* The group number passed did not designate a valid group.
*/
- TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_GROUP_NOT_FOUND,
+ TOX_ERR_GROUP_SET_TOPIC_LOCK_GROUP_NOT_FOUND,
/**
* Tox_Group_Topic_Lock is an invalid type.
*/
- TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_INVALID,
+ TOX_ERR_GROUP_SET_TOPIC_LOCK_INVALID,
/**
* The caller does not have the required permissions to set the topic lock.
*/
- TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_PERMISSIONS,
+ TOX_ERR_GROUP_SET_TOPIC_LOCK_PERMISSIONS,
/**
- * The topic lock could not be set. This may occur due to an error related to
- * cryptographic signing of the new shared state.
+ * The topic lock could not be set. This may occur due to an error related
+ * to cryptographic signing of the new shared state.
*/
- TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SET,
+ TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SET,
/**
* The packet failed to send.
*/
- TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SEND,
+ TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SEND,
/**
* The group is disconnected.
*/
- TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_DISCONNECTED,
+ TOX_ERR_GROUP_SET_TOPIC_LOCK_DISCONNECTED,
-} Tox_Err_Group_Founder_Set_Topic_Lock;
+} Tox_Err_Group_Set_Topic_Lock;
-const char *tox_err_group_founder_set_topic_lock_to_string(Tox_Err_Group_Founder_Set_Topic_Lock value);
+const char *tox_err_group_set_topic_lock_to_string(Tox_Err_Group_Set_Topic_Lock value);
/**
* Set the group topic lock state.
*
- * This function sets the group's topic lock state to enabled or disabled, creates a new shared
- * state including the change, and distributes it to the rest of the group.
+ * This function allows Founders to enable or disable the group's topic lock. It
+ * will create a new shared state including the change and distribute it to the
+ * rest of the group.
*
- * When the topic lock is enabled, only the group founder and moderators may set the topic.
- * When disabled, all peers except those with the observer role may set the topic.
+ * When the topic lock is enabled, only the group founder and moderators may set
+ * the topic. When disabled, all peers except those with the observer role may
+ * set the topic.
*
- * @param group_number The group number of the group for which we wish to change the topic lock state.
+ * @param group_number The group number of the group for which we wish to change
+ * the topic lock state.
* @param topic_lock The state we wish to set the topic lock to.
*
* @return true on success.
*/
-bool tox_group_founder_set_topic_lock(Tox *tox, Tox_Group_Number group_number, Tox_Group_Topic_Lock topic_lock,
- Tox_Err_Group_Founder_Set_Topic_Lock *error);
+bool tox_group_set_topic_lock(Tox *tox, Tox_Group_Number group_number, Tox_Group_Topic_Lock topic_lock,
+ Tox_Err_Group_Set_Topic_Lock *error);
-typedef enum Tox_Err_Group_Founder_Set_Voice_State {
+typedef enum Tox_Err_Group_Set_Voice_State {
/**
* The function returned successfully.
*/
- TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK,
+ TOX_ERR_GROUP_SET_VOICE_STATE_OK,
/**
* The group number passed did not designate a valid group.
*/
- TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_GROUP_NOT_FOUND,
+ TOX_ERR_GROUP_SET_VOICE_STATE_GROUP_NOT_FOUND,
/**
- * The caller does not have the required permissions to set the privacy state.
+ * The caller does not have the required permissions to set the privacy
+ * state.
*/
- TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_PERMISSIONS,
+ TOX_ERR_GROUP_SET_VOICE_STATE_PERMISSIONS,
/**
- * The voice state could not be set. This may occur due to an error related to
- * cryptographic signing of the new shared state.
+ * The voice state could not be set. This may occur due to an error related
+ * to cryptographic signing of the new shared state.
*/
- TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SET,
+ TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SET,
/**
* The packet failed to send.
*/
- TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SEND,
+ TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SEND,
/**
* The group is disconnected.
*/
- TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_DISCONNECTED,
+ TOX_ERR_GROUP_SET_VOICE_STATE_DISCONNECTED,
-} Tox_Err_Group_Founder_Set_Voice_State;
+} Tox_Err_Group_Set_Voice_State;
-const char *tox_err_group_founder_set_voice_state_to_string(Tox_Err_Group_Founder_Set_Voice_State value);
+const char *tox_err_group_set_voice_state_to_string(Tox_Err_Group_Set_Voice_State value);
/**
* Set the group voice state.
*
- * This function sets the group's voice state, creates a new group shared state
- * including the change, and distributes it to the rest of the group.
+ * This function allows Founders to set the group's voice state. It will create
+ * a new group shared state including the change and distribute it to the rest
+ * of the group.
*
- * If an attempt is made to set the voice state to the same state that the group is already
- * in, the function call will be successful and no action will be taken.
+ * If an attempt is made to set the voice state to the same state that the group
+ * is already in, the function call will be successful and no action will be
+ * taken.
*
- * @param group_number The group number of the group for which we wish to change the voice state.
+ * @param group_number The group number of the group for which we wish to change
+ * the voice state.
* @param voice_state The voice state we wish to set the group to.
*
* @return true on success.
*/
-bool tox_group_founder_set_voice_state(Tox *tox, Tox_Group_Number group_number, Tox_Group_Voice_State voice_state,
- Tox_Err_Group_Founder_Set_Voice_State *error);
+bool tox_group_set_voice_state(Tox *tox, Tox_Group_Number group_number, Tox_Group_Voice_State voice_state,
+ Tox_Err_Group_Set_Voice_State *error);
-typedef enum Tox_Err_Group_Founder_Set_Privacy_State {
+typedef enum Tox_Err_Group_Set_Privacy_State {
/**
* The function returned successfully.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK,
+ TOX_ERR_GROUP_SET_PRIVACY_STATE_OK,
/**
* The group number passed did not designate a valid group.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_GROUP_NOT_FOUND,
+ TOX_ERR_GROUP_SET_PRIVACY_STATE_GROUP_NOT_FOUND,
/**
- * The caller does not have the required permissions to set the privacy state.
+ * The caller does not have the required permissions to set the privacy
+ * state.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_PERMISSIONS,
+ TOX_ERR_GROUP_SET_PRIVACY_STATE_PERMISSIONS,
/**
- * The privacy state could not be set. This may occur due to an error related to
- * cryptographic signing of the new shared state.
+ * The privacy state could not be set. This may occur due to an error
+ * related to cryptographic signing of the new shared state.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SET,
+ TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SET,
/**
* The packet failed to send.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SEND,
+ TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SEND,
/**
* The group is disconnected.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_DISCONNECTED,
+ TOX_ERR_GROUP_SET_PRIVACY_STATE_DISCONNECTED,
-} Tox_Err_Group_Founder_Set_Privacy_State;
+} Tox_Err_Group_Set_Privacy_State;
-const char *tox_err_group_founder_set_privacy_state_to_string(Tox_Err_Group_Founder_Set_Privacy_State value);
+const char *tox_err_group_set_privacy_state_to_string(Tox_Err_Group_Set_Privacy_State value);
/**
* Set the group privacy state.
*
- * This function sets the group's privacy state, creates a new group shared state
- * including the change, and distributes it to the rest of the group.
+ * This function allows Founders to set the group's privacy state. It will
+ * create a new group shared state including the change and distribute it to the
+ * rest of the group.
*
- * If an attempt is made to set the privacy state to the same state that the group is already
- * in, the function call will be successful and no action will be taken.
+ * If an attempt is made to set the privacy state to the same state that the
+ * group is already in, the function call will be successful and no action will
+ * be taken.
*
- * @param group_number The group number of the group for which we wish to change the privacy state.
+ * @param group_number The group number of the group for which we wish to change
+ * the privacy state.
* @param privacy_state The privacy state we wish to set the group to.
*
* @return true on success.
*/
-bool tox_group_founder_set_privacy_state(Tox *tox, Tox_Group_Number group_number, Tox_Group_Privacy_State privacy_state,
- Tox_Err_Group_Founder_Set_Privacy_State *error);
+bool tox_group_set_privacy_state(Tox *tox, Tox_Group_Number group_number, Tox_Group_Privacy_State privacy_state,
+ Tox_Err_Group_Set_Privacy_State *error);
-typedef enum Tox_Err_Group_Founder_Set_Peer_Limit {
+typedef enum Tox_Err_Group_Set_Peer_Limit {
/**
* The function returned successfully.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK,
+ TOX_ERR_GROUP_SET_PEER_LIMIT_OK,
/**
* The group number passed did not designate a valid group.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_GROUP_NOT_FOUND,
+ TOX_ERR_GROUP_SET_PEER_LIMIT_GROUP_NOT_FOUND,
/**
* The caller does not have the required permissions to set the peer limit.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_PERMISSIONS,
+ TOX_ERR_GROUP_SET_PEER_LIMIT_PERMISSIONS,
/**
- * The peer limit could not be set. This may occur due to an error related to
- * cryptographic signing of the new shared state.
+ * The peer limit could not be set. This may occur due to an error related
+ * to cryptographic signing of the new shared state.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SET,
+ TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SET,
/**
* The packet failed to send.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SEND,
+ TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SEND,
/**
* The group is disconnected.
*/
- TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_DISCONNECTED,
+ TOX_ERR_GROUP_SET_PEER_LIMIT_DISCONNECTED,
-} Tox_Err_Group_Founder_Set_Peer_Limit;
+} Tox_Err_Group_Set_Peer_Limit;
-const char *tox_err_group_founder_set_peer_limit_to_string(Tox_Err_Group_Founder_Set_Peer_Limit value);
+const char *tox_err_group_set_peer_limit_to_string(Tox_Err_Group_Set_Peer_Limit value);
/**
* Set the group peer limit.
*
- * This function sets a limit for the number of peers who may be in the group, creates a new
- * group shared state including the change, and distributes it to the rest of the group.
+ * This function allows Founders to set a limit for the number of peers who may
+ * be in the group. It will create a new group shared state including the change
+ * and distribute it to the rest of the group.
*
- * @param group_number The group number of the group for which we wish to set the peer limit.
+ * @param group_number The group number of the group for which we wish to set
+ * the peer limit.
* @param peer_limit The maximum number of peers to allow in the group.
*
* @return true on success.
*/
-bool tox_group_founder_set_peer_limit(Tox *tox, Tox_Group_Number group_number, uint16_t peer_limit,
- Tox_Err_Group_Founder_Set_Peer_Limit *error);
+bool tox_group_set_peer_limit(Tox *tox, Tox_Group_Number group_number, uint16_t peer_limit,
+ Tox_Err_Group_Set_Peer_Limit *error);
/*******************************************************************************
*
- * :: Group chat moderation
+ * :: Group chat moderation controls
*
******************************************************************************/
@@ -5393,7 +5127,8 @@ const char *tox_err_group_set_ignore_to_string(Tox_Err_Group_Set_Ignore value);
/**
* Ignore or unignore a peer.
*
- * @param group_number The group number of the group in which you wish to ignore a peer.
+ * @param group_number The group number of the group in which you wish to ignore
+ * a peer.
* @param peer_id The ID of the peer who shall be ignored or unignored.
* @param ignore True to ignore the peer, false to unignore the peer.
*
@@ -5402,123 +5137,134 @@ const char *tox_err_group_set_ignore_to_string(Tox_Err_Group_Set_Ignore value);
bool tox_group_set_ignore(Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, bool ignore,
Tox_Err_Group_Set_Ignore *error);
-typedef enum Tox_Err_Group_Mod_Set_Role {
+typedef enum Tox_Err_Group_Set_Role {
/**
* The function returned successfully.
*/
- TOX_ERR_GROUP_MOD_SET_ROLE_OK,
+ TOX_ERR_GROUP_SET_ROLE_OK,
/**
* The group number passed did not designate a valid group.
*/
- TOX_ERR_GROUP_MOD_SET_ROLE_GROUP_NOT_FOUND,
+ TOX_ERR_GROUP_SET_ROLE_GROUP_NOT_FOUND,
/**
- * The ID passed did not designate a valid peer. Note: you cannot set your own role.
+ * The ID passed did not designate a valid peer. Note: you cannot set your
+ * own role.
*/
- TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND,
+ TOX_ERR_GROUP_SET_ROLE_PEER_NOT_FOUND,
/**
* The caller does not have the required permissions for this action.
*/
- TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS,
+ TOX_ERR_GROUP_SET_ROLE_PERMISSIONS,
/**
- * The role assignment is invalid. This will occur if you try to set a peer's role to
- * the role they already have.
+ * The role assignment is invalid. This will occur if you try to set a
+ * peer's role to the role they already have.
*/
- TOX_ERR_GROUP_MOD_SET_ROLE_ASSIGNMENT,
+ TOX_ERR_GROUP_SET_ROLE_ASSIGNMENT,
/**
- * The role was not successfully set. This may occur if the packet failed to send, or
- * if the role limit has been reached.
+ * The role was not successfully set. This may occur if the packet failed to
+ * send, or if the role limit has been reached.
*/
- TOX_ERR_GROUP_MOD_SET_ROLE_FAIL_ACTION,
+ TOX_ERR_GROUP_SET_ROLE_FAIL_ACTION,
/**
* The caller attempted to set their own role.
*/
- TOX_ERR_GROUP_MOD_SET_ROLE_SELF,
+ TOX_ERR_GROUP_SET_ROLE_SELF,
-} Tox_Err_Group_Mod_Set_Role;
+} Tox_Err_Group_Set_Role;
-const char *tox_err_group_mod_set_role_to_string(Tox_Err_Group_Mod_Set_Role value);
+const char *tox_err_group_set_role_to_string(Tox_Err_Group_Set_Role value);
/**
* Set a peer's role.
*
- * This function will first remove the peer's previous role and then assign them a new role.
- * It will also send a packet to the rest of the group, requesting that they perform
- * the role reassignment. Note: peers cannot be set to the founder role.
+ * This function will first remove the peer's previous role and then assign them
+ * a new role. It will also send a packet to the rest of the group, requesting
+ * that they perform the role reassignment.
*
- * @param group_number The group number of the group the in which you wish set the peer's role.
+ * Only Founders may promote peers to the Moderator role, and only Founders and
+ * Moderators may set peers to the Observer or User role. Moderators may not set
+ * the role of other Moderators or the Founder. Peers may not be promoted to the
+ * Founder role.
+ *
+ * @param group_number The group number of the group the in which you wish set
+ * the peer's role.
* @param peer_id The ID of the peer whose role you wish to set.
* @param role The role you wish to set the peer to.
*
* @return true on success.
*/
-bool tox_group_mod_set_role(Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Group_Role role,
- Tox_Err_Group_Mod_Set_Role *error);
+bool tox_group_set_role(Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id, Tox_Group_Role role,
+ Tox_Err_Group_Set_Role *error);
-typedef enum Tox_Err_Group_Mod_Kick_Peer {
+typedef enum Tox_Err_Group_Kick_Peer {
/**
* The function returned successfully.
*/
- TOX_ERR_GROUP_MOD_KICK_PEER_OK,
+ TOX_ERR_GROUP_KICK_PEER_OK,
/**
* The group number passed did not designate a valid group.
*/
- TOX_ERR_GROUP_MOD_KICK_PEER_GROUP_NOT_FOUND,
+ TOX_ERR_GROUP_KICK_PEER_GROUP_NOT_FOUND,
/**
* The ID passed did not designate a valid peer.
*/
- TOX_ERR_GROUP_MOD_KICK_PEER_PEER_NOT_FOUND,
+ TOX_ERR_GROUP_KICK_PEER_PEER_NOT_FOUND,
/**
* The caller does not have the required permissions for this action.
*/
- TOX_ERR_GROUP_MOD_KICK_PEER_PERMISSIONS,
+ TOX_ERR_GROUP_KICK_PEER_PERMISSIONS,
/**
* The peer could not be kicked from the group.
*/
- TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_ACTION,
+ TOX_ERR_GROUP_KICK_PEER_FAIL_ACTION,
/**
* The packet failed to send.
*/
- TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_SEND,
+ TOX_ERR_GROUP_KICK_PEER_FAIL_SEND,
/**
* The caller attempted to set their own role.
*/
- TOX_ERR_GROUP_MOD_KICK_PEER_SELF,
+ TOX_ERR_GROUP_KICK_PEER_SELF,
-} Tox_Err_Group_Mod_Kick_Peer;
+} Tox_Err_Group_Kick_Peer;
-const char *tox_err_group_mod_kick_peer_to_string(Tox_Err_Group_Mod_Kick_Peer value);
+const char *tox_err_group_kick_peer_to_string(Tox_Err_Group_Kick_Peer value);
/**
* Kick a peer.
*
- * This function will remove a peer from the caller's peer list and send a packet to all
- * group members requesting them to do the same. Note: This function will not trigger
- * the `group_peer_exit` event for the caller.
+ * This function allows peers with the Founder or Moderator role to silently
+ * instruct all other peers in the group to remove a particular peer from their
+ * peer list.
+ *
+ * Note: This function will not trigger the `group_peer_exit` event for the
+ * caller.
*
* @param group_number The group number of the group the action is intended for.
* @param peer_id The ID of the peer who will be kicked.
*
* @return true on success.
*/
-bool tox_group_mod_kick_peer(const Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id,
- Tox_Err_Group_Mod_Kick_Peer *error);
+bool tox_group_kick_peer(const Tox *tox, Tox_Group_Number group_number, Tox_Group_Peer_Number peer_id,
+ Tox_Err_Group_Kick_Peer *error);
/**
- * Represents moderation events. These should be used with the `group_moderation` event.
+ * Represents moderation events. These should be used with the
+ * `group_moderation` event.
*/
typedef enum Tox_Group_Mod_Event {
@@ -5559,12 +5305,13 @@ typedef void tox_group_moderation_cb(
/**
* Set the callback for the `group_moderation` event. Pass NULL to unset.
*
- * This event is triggered when a moderator or founder executes a moderation event, with
- * the exception of the peer who initiates the event. It is also triggered when the
- * observer and moderator lists are silently modified (this may occur during group syncing).
+ * This event is triggered when a moderator or founder executes a moderation
+ * event, with the exception of the peer who initiates the event. It is also
+ * triggered when the observer and moderator lists are silently modified (this
+ * may occur during group syncing).
*
- * If either peer id does not designate a valid peer in the group chat, the client should
- * manually update all peer roles.
+ * If either peer id does not designate a valid peer in the group chat, the
+ * client should manually update all peer roles.
*/
void tox_callback_group_moderation(Tox *tox, tox_group_moderation_cb *callback);
@@ -5579,6 +5326,7 @@ void tox_callback_group_moderation(Tox *tox, tox_group_moderation_cb *callback);
//!TOKSTYLE-
#ifndef DOXYGEN_IGNORE
+#ifndef TOX_HIDE_DEPRECATED
typedef Tox_Err_Options_New TOX_ERR_OPTIONS_NEW;
typedef Tox_Err_New TOX_ERR_NEW;
typedef Tox_Err_Bootstrap TOX_ERR_BOOTSTRAP;
@@ -5613,11 +5361,11 @@ typedef Tox_User_Status TOX_USER_STATUS;
typedef Tox_Message_Type TOX_MESSAGE_TYPE;
typedef Tox_Proxy_Type TOX_PROXY_TYPE;
typedef Tox_Savedata_Type TOX_SAVEDATA_TYPE;
-typedef Tox_Log_Level TOX_LOG_LEVEL;
typedef Tox_Connection TOX_CONNECTION;
typedef Tox_File_Control TOX_FILE_CONTROL;
typedef Tox_Conference_Type TOX_CONFERENCE_TYPE;
typedef enum Tox_File_Kind TOX_FILE_KIND;
+#endif /* TOX_HIDE_DEPRECATED */
#endif
//!TOKSTYLE+
diff --git a/protocols/Tox/libtox/src/toxcore/tox_api.c b/protocols/Tox/libtox/src/toxcore/tox_api.c
index 02791674b5..808cd473f5 100644
--- a/protocols/Tox/libtox/src/toxcore/tox_api.c
+++ b/protocols/Tox/libtox/src/toxcore/tox_api.c
@@ -1,20 +1,11 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2021 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
*/
-#include "tox.h"
+#include "tox.h" // IWYU pragma: associated
-#include <stdlib.h>
-
-#include "ccompat.h"
+#include "tox_options.h"
#include "tox_private.h"
-#define SET_ERROR_PARAMETER(param, x) \
- do { \
- if (param != nullptr) { \
- *param = x; \
- } \
- } while (0)
-
uint32_t tox_version_major(void)
{
return TOX_VERSION_MAJOR;
@@ -136,199 +127,6 @@ uint32_t tox_dht_node_public_key_size(void)
return TOX_DHT_NODE_PUBLIC_KEY_SIZE;
}
-bool tox_options_get_ipv6_enabled(const Tox_Options *options)
-{
- return options->ipv6_enabled;
-}
-void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled)
-{
- options->ipv6_enabled = ipv6_enabled;
-}
-bool tox_options_get_udp_enabled(const Tox_Options *options)
-{
- return options->udp_enabled;
-}
-void tox_options_set_udp_enabled(Tox_Options *options, bool udp_enabled)
-{
- options->udp_enabled = udp_enabled;
-}
-Tox_Proxy_Type tox_options_get_proxy_type(const Tox_Options *options)
-{
- return options->proxy_type;
-}
-void tox_options_set_proxy_type(Tox_Options *options, Tox_Proxy_Type proxy_type)
-{
- options->proxy_type = proxy_type;
-}
-const char *tox_options_get_proxy_host(const Tox_Options *options)
-{
- return options->proxy_host;
-}
-void tox_options_set_proxy_host(Tox_Options *options, const char *proxy_host)
-{
- options->proxy_host = proxy_host;
-}
-uint16_t tox_options_get_proxy_port(const Tox_Options *options)
-{
- return options->proxy_port;
-}
-void tox_options_set_proxy_port(Tox_Options *options, uint16_t proxy_port)
-{
- options->proxy_port = proxy_port;
-}
-uint16_t tox_options_get_start_port(const Tox_Options *options)
-{
- return options->start_port;
-}
-void tox_options_set_start_port(Tox_Options *options, uint16_t start_port)
-{
- options->start_port = start_port;
-}
-uint16_t tox_options_get_end_port(const Tox_Options *options)
-{
- return options->end_port;
-}
-void tox_options_set_end_port(Tox_Options *options, uint16_t end_port)
-{
- options->end_port = end_port;
-}
-uint16_t tox_options_get_tcp_port(const Tox_Options *options)
-{
- return options->tcp_port;
-}
-void tox_options_set_tcp_port(Tox_Options *options, uint16_t tcp_port)
-{
- options->tcp_port = tcp_port;
-}
-bool tox_options_get_hole_punching_enabled(const Tox_Options *options)
-{
- return options->hole_punching_enabled;
-}
-void tox_options_set_hole_punching_enabled(Tox_Options *options, bool hole_punching_enabled)
-{
- options->hole_punching_enabled = hole_punching_enabled;
-}
-Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options *options)
-{
- return options->savedata_type;
-}
-void tox_options_set_savedata_type(Tox_Options *options, Tox_Savedata_Type savedata_type)
-{
- options->savedata_type = savedata_type;
-}
-size_t tox_options_get_savedata_length(const Tox_Options *options)
-{
- return options->savedata_length;
-}
-void tox_options_set_savedata_length(Tox_Options *options, size_t savedata_length)
-{
- options->savedata_length = savedata_length;
-}
-tox_log_cb *tox_options_get_log_callback(const Tox_Options *options)
-{
- return options->log_callback;
-}
-void tox_options_set_log_callback(Tox_Options *options, tox_log_cb *log_callback)
-{
- options->log_callback = log_callback;
-}
-void *tox_options_get_log_user_data(const Tox_Options *options)
-{
- return options->log_user_data;
-}
-void tox_options_set_log_user_data(Tox_Options *options, void *log_user_data)
-{
- options->log_user_data = log_user_data;
-}
-bool tox_options_get_local_discovery_enabled(const Tox_Options *options)
-{
- return options->local_discovery_enabled;
-}
-void tox_options_set_local_discovery_enabled(Tox_Options *options, bool local_discovery_enabled)
-{
- options->local_discovery_enabled = local_discovery_enabled;
-}
-bool tox_options_get_dht_announcements_enabled(const Tox_Options *options)
-{
- return options->dht_announcements_enabled;
-}
-void tox_options_set_dht_announcements_enabled(Tox_Options *options, bool dht_announcements_enabled)
-{
- options->dht_announcements_enabled = dht_announcements_enabled;
-}
-bool tox_options_get_experimental_thread_safety(const Tox_Options *options)
-{
- return options->experimental_thread_safety;
-}
-void tox_options_set_experimental_thread_safety(
- Tox_Options *options, bool experimental_thread_safety)
-{
- options->experimental_thread_safety = experimental_thread_safety;
-}
-const Tox_System *tox_options_get_operating_system(const Tox_Options *options)
-{
- return options->operating_system;
-}
-void tox_options_set_operating_system(Tox_Options *options, const Tox_System *operating_system)
-{
- options->operating_system = operating_system;
-}
-bool tox_options_get_experimental_groups_persistence(const Tox_Options *options)
-{
- return options->experimental_groups_persistence;
-}
-void tox_options_set_experimental_groups_persistence(
- Tox_Options *options, bool experimental_groups_persistence)
-{
- options->experimental_groups_persistence = experimental_groups_persistence;
-}
-
-const uint8_t *tox_options_get_savedata_data(const Tox_Options *options)
-{
- return options->savedata_data;
-}
-
-void tox_options_set_savedata_data(Tox_Options *options, const uint8_t *savedata_data, size_t length)
-{
- options->savedata_data = savedata_data;
- options->savedata_length = length;
-}
-
-void tox_options_default(Tox_Options *options)
-{
- if (options != nullptr) {
- const Tox_Options default_options = {false};
- *options = default_options;
- tox_options_set_ipv6_enabled(options, true);
- tox_options_set_udp_enabled(options, true);
- tox_options_set_proxy_type(options, TOX_PROXY_TYPE_NONE);
- tox_options_set_hole_punching_enabled(options, true);
- tox_options_set_local_discovery_enabled(options, true);
- tox_options_set_dht_announcements_enabled(options, true);
- tox_options_set_experimental_thread_safety(options, false);
- tox_options_set_experimental_groups_persistence(options, false);
- }
-}
-
-Tox_Options *tox_options_new(Tox_Err_Options_New *error)
-{
- Tox_Options *options = (Tox_Options *)calloc(1, sizeof(Tox_Options));
-
- if (options != nullptr) {
- tox_options_default(options);
- SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_OK);
- return options;
- }
-
- SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_MALLOC);
- return nullptr;
-}
-
-void tox_options_free(Tox_Options *options)
-{
- free(options);
-}
-
const char *tox_user_status_to_string(Tox_User_Status value)
{
switch (value) {
@@ -386,27 +184,6 @@ const char *tox_savedata_type_to_string(Tox_Savedata_Type value)
return "<invalid Tox_Savedata_Type>";
}
-const char *tox_log_level_to_string(Tox_Log_Level value)
-{
- switch (value) {
- case TOX_LOG_LEVEL_TRACE:
- return "TOX_LOG_LEVEL_TRACE";
-
- case TOX_LOG_LEVEL_DEBUG:
- return "TOX_LOG_LEVEL_DEBUG";
-
- case TOX_LOG_LEVEL_INFO:
- return "TOX_LOG_LEVEL_INFO";
-
- case TOX_LOG_LEVEL_WARNING:
- return "TOX_LOG_LEVEL_WARNING";
-
- case TOX_LOG_LEVEL_ERROR:
- return "TOX_LOG_LEVEL_ERROR";
- }
-
- return "<invalid Tox_Log_Level>";
-}
const char *tox_err_options_new_to_string(Tox_Err_Options_New value)
{
switch (value) {
@@ -895,6 +672,9 @@ const char *tox_err_conference_join_to_string(Tox_Err_Conference_Join value)
case TOX_ERR_CONFERENCE_JOIN_FAIL_SEND:
return "TOX_ERR_CONFERENCE_JOIN_FAIL_SEND";
+
+ case TOX_ERR_CONFERENCE_JOIN_NULL:
+ return "TOX_ERR_CONFERENCE_JOIN_NULL";
}
return "<invalid Tox_Err_Conference_Join>";
@@ -1253,17 +1033,17 @@ const char *tox_err_group_peer_query_to_string(Tox_Err_Group_Peer_Query value)
return "<invalid Tox_Err_Group_Peer_Query>";
}
-const char *tox_err_group_state_queries_to_string(Tox_Err_Group_State_Queries value)
+const char *tox_err_group_state_query_to_string(Tox_Err_Group_State_Query value)
{
switch (value) {
- case TOX_ERR_GROUP_STATE_QUERIES_OK:
- return "TOX_ERR_GROUP_STATE_QUERIES_OK";
+ case TOX_ERR_GROUP_STATE_QUERY_OK:
+ return "TOX_ERR_GROUP_STATE_QUERY_OK";
- case TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND:
- return "TOX_ERR_GROUP_STATE_QUERIES_GROUP_NOT_FOUND";
+ case TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND:
+ return "TOX_ERR_GROUP_STATE_QUERY_GROUP_NOT_FOUND";
}
- return "<invalid Tox_Err_Group_State_Queries>";
+ return "<invalid Tox_Err_Group_State_Query>";
}
const char *tox_err_group_topic_set_to_string(Tox_Err_Group_Topic_Set value)
{
@@ -1340,6 +1120,9 @@ const char *tox_err_group_send_private_message_to_string(Tox_Err_Group_Send_Priv
case TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_EMPTY:
return "TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_EMPTY";
+ case TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_BAD_TYPE:
+ return "TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_BAD_TYPE";
+
case TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_PERMISSIONS:
return "TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_PERMISSIONS";
@@ -1348,9 +1131,6 @@ const char *tox_err_group_send_private_message_to_string(Tox_Err_Group_Send_Priv
case TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_DISCONNECTED:
return "TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_DISCONNECTED";
-
- case TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_BAD_TYPE:
- return "TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_BAD_TYPE";
}
return "<invalid Tox_Err_Group_Send_Private_Message>";
@@ -1370,9 +1150,6 @@ const char *tox_err_group_send_custom_packet_to_string(Tox_Err_Group_Send_Custom
case TOX_ERR_GROUP_SEND_CUSTOM_PACKET_EMPTY:
return "TOX_ERR_GROUP_SEND_CUSTOM_PACKET_EMPTY";
- case TOX_ERR_GROUP_SEND_CUSTOM_PACKET_PERMISSIONS:
- return "TOX_ERR_GROUP_SEND_CUSTOM_PACKET_PERMISSIONS";
-
case TOX_ERR_GROUP_SEND_CUSTOM_PACKET_DISCONNECTED:
return "TOX_ERR_GROUP_SEND_CUSTOM_PACKET_DISCONNECTED";
@@ -1400,9 +1177,6 @@ const char *tox_err_group_send_custom_private_packet_to_string(Tox_Err_Group_Sen
case TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_PEER_NOT_FOUND:
return "TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_PEER_NOT_FOUND";
- case TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_PERMISSIONS:
- return "TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_PERMISSIONS";
-
case TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_FAIL_SEND:
return "TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_FAIL_SEND";
@@ -1457,11 +1231,14 @@ const char *tox_err_group_invite_accept_to_string(Tox_Err_Group_Invite_Accept va
case TOX_ERR_GROUP_INVITE_ACCEPT_PASSWORD:
return "TOX_ERR_GROUP_INVITE_ACCEPT_PASSWORD";
- case TOX_ERR_GROUP_INVITE_ACCEPT_CORE:
- return "TOX_ERR_GROUP_INVITE_ACCEPT_CORE";
+ case TOX_ERR_GROUP_INVITE_ACCEPT_FRIEND_NOT_FOUND:
+ return "TOX_ERR_GROUP_INVITE_ACCEPT_FRIEND_NOT_FOUND";
case TOX_ERR_GROUP_INVITE_ACCEPT_FAIL_SEND:
return "TOX_ERR_GROUP_INVITE_ACCEPT_FAIL_SEND";
+
+ case TOX_ERR_GROUP_INVITE_ACCEPT_NULL:
+ return "TOX_ERR_GROUP_INVITE_ACCEPT_NULL";
}
return "<invalid Tox_Err_Group_Invite_Accept>";
@@ -1505,131 +1282,131 @@ const char *tox_group_join_fail_to_string(Tox_Group_Join_Fail value)
return "<invalid Tox_Group_Join_Fail>";
}
-const char *tox_err_group_founder_set_password_to_string(Tox_Err_Group_Founder_Set_Password value)
+const char *tox_err_group_set_password_to_string(Tox_Err_Group_Set_Password value)
{
switch (value) {
- case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK:
- return "TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK";
+ case TOX_ERR_GROUP_SET_PASSWORD_OK:
+ return "TOX_ERR_GROUP_SET_PASSWORD_OK";
- case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_GROUP_NOT_FOUND:
- return "TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_GROUP_NOT_FOUND";
+ case TOX_ERR_GROUP_SET_PASSWORD_GROUP_NOT_FOUND:
+ return "TOX_ERR_GROUP_SET_PASSWORD_GROUP_NOT_FOUND";
- case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_PERMISSIONS:
- return "TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_PERMISSIONS";
+ case TOX_ERR_GROUP_SET_PASSWORD_PERMISSIONS:
+ return "TOX_ERR_GROUP_SET_PASSWORD_PERMISSIONS";
- case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_TOO_LONG:
- return "TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_TOO_LONG";
+ case TOX_ERR_GROUP_SET_PASSWORD_TOO_LONG:
+ return "TOX_ERR_GROUP_SET_PASSWORD_TOO_LONG";
- case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_FAIL_SEND:
- return "TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_FAIL_SEND";
+ case TOX_ERR_GROUP_SET_PASSWORD_FAIL_SEND:
+ return "TOX_ERR_GROUP_SET_PASSWORD_FAIL_SEND";
- case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_MALLOC:
- return "TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_MALLOC";
+ case TOX_ERR_GROUP_SET_PASSWORD_MALLOC:
+ return "TOX_ERR_GROUP_SET_PASSWORD_MALLOC";
- case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_DISCONNECTED:
- return "TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_DISCONNECTED";
+ case TOX_ERR_GROUP_SET_PASSWORD_DISCONNECTED:
+ return "TOX_ERR_GROUP_SET_PASSWORD_DISCONNECTED";
}
- return "<invalid Tox_Err_Group_Founder_Set_Password>";
+ return "<invalid Tox_Err_Group_Set_Password>";
}
-const char *tox_err_group_founder_set_topic_lock_to_string(Tox_Err_Group_Founder_Set_Topic_Lock value)
+const char *tox_err_group_set_topic_lock_to_string(Tox_Err_Group_Set_Topic_Lock value)
{
switch (value) {
- case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK:
- return "TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK";
+ case TOX_ERR_GROUP_SET_TOPIC_LOCK_OK:
+ return "TOX_ERR_GROUP_SET_TOPIC_LOCK_OK";
- case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_GROUP_NOT_FOUND:
- return "TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_GROUP_NOT_FOUND";
+ case TOX_ERR_GROUP_SET_TOPIC_LOCK_GROUP_NOT_FOUND:
+ return "TOX_ERR_GROUP_SET_TOPIC_LOCK_GROUP_NOT_FOUND";
- case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_INVALID:
- return "TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_INVALID";
+ case TOX_ERR_GROUP_SET_TOPIC_LOCK_INVALID:
+ return "TOX_ERR_GROUP_SET_TOPIC_LOCK_INVALID";
- case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_PERMISSIONS:
- return "TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_PERMISSIONS";
+ case TOX_ERR_GROUP_SET_TOPIC_LOCK_PERMISSIONS:
+ return "TOX_ERR_GROUP_SET_TOPIC_LOCK_PERMISSIONS";
- case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SET:
- return "TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SET";
+ case TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SET:
+ return "TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SET";
- case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SEND:
- return "TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_FAIL_SEND";
+ case TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SEND:
+ return "TOX_ERR_GROUP_SET_TOPIC_LOCK_FAIL_SEND";
- case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_DISCONNECTED:
- return "TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_DISCONNECTED";
+ case TOX_ERR_GROUP_SET_TOPIC_LOCK_DISCONNECTED:
+ return "TOX_ERR_GROUP_SET_TOPIC_LOCK_DISCONNECTED";
}
- return "<invalid Tox_Err_Group_Founder_Set_Topic_Lock>";
+ return "<invalid Tox_Err_Group_Set_Topic_Lock>";
}
-const char *tox_err_group_founder_set_voice_state_to_string(Tox_Err_Group_Founder_Set_Voice_State value)
+const char *tox_err_group_set_voice_state_to_string(Tox_Err_Group_Set_Voice_State value)
{
switch (value) {
- case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK:
- return "TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK";
+ case TOX_ERR_GROUP_SET_VOICE_STATE_OK:
+ return "TOX_ERR_GROUP_SET_VOICE_STATE_OK";
- case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_GROUP_NOT_FOUND:
- return "TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_GROUP_NOT_FOUND";
+ case TOX_ERR_GROUP_SET_VOICE_STATE_GROUP_NOT_FOUND:
+ return "TOX_ERR_GROUP_SET_VOICE_STATE_GROUP_NOT_FOUND";
- case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_PERMISSIONS:
- return "TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_PERMISSIONS";
+ case TOX_ERR_GROUP_SET_VOICE_STATE_PERMISSIONS:
+ return "TOX_ERR_GROUP_SET_VOICE_STATE_PERMISSIONS";
- case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SET:
- return "TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SET";
+ case TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SET:
+ return "TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SET";
- case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SEND:
- return "TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_FAIL_SEND";
+ case TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SEND:
+ return "TOX_ERR_GROUP_SET_VOICE_STATE_FAIL_SEND";
- case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_DISCONNECTED:
- return "TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_DISCONNECTED";
+ case TOX_ERR_GROUP_SET_VOICE_STATE_DISCONNECTED:
+ return "TOX_ERR_GROUP_SET_VOICE_STATE_DISCONNECTED";
}
- return "<invalid Tox_Err_Group_Founder_Set_Voice_State>";
+ return "<invalid Tox_Err_Group_Set_Voice_State>";
}
-const char *tox_err_group_founder_set_privacy_state_to_string(Tox_Err_Group_Founder_Set_Privacy_State value)
+const char *tox_err_group_set_privacy_state_to_string(Tox_Err_Group_Set_Privacy_State value)
{
switch (value) {
- case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK:
- return "TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK";
+ case TOX_ERR_GROUP_SET_PRIVACY_STATE_OK:
+ return "TOX_ERR_GROUP_SET_PRIVACY_STATE_OK";
- case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_GROUP_NOT_FOUND:
- return "TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_GROUP_NOT_FOUND";
+ case TOX_ERR_GROUP_SET_PRIVACY_STATE_GROUP_NOT_FOUND:
+ return "TOX_ERR_GROUP_SET_PRIVACY_STATE_GROUP_NOT_FOUND";
- case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_PERMISSIONS:
- return "TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_PERMISSIONS";
+ case TOX_ERR_GROUP_SET_PRIVACY_STATE_PERMISSIONS:
+ return "TOX_ERR_GROUP_SET_PRIVACY_STATE_PERMISSIONS";
- case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SET:
- return "TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SET";
+ case TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SET:
+ return "TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SET";
- case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SEND:
- return "TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_FAIL_SEND";
+ case TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SEND:
+ return "TOX_ERR_GROUP_SET_PRIVACY_STATE_FAIL_SEND";
- case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_DISCONNECTED:
- return "TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_DISCONNECTED";
+ case TOX_ERR_GROUP_SET_PRIVACY_STATE_DISCONNECTED:
+ return "TOX_ERR_GROUP_SET_PRIVACY_STATE_DISCONNECTED";
}
- return "<invalid Tox_Err_Group_Founder_Set_Privacy_State>";
+ return "<invalid Tox_Err_Group_Set_Privacy_State>";
}
-const char *tox_err_group_founder_set_peer_limit_to_string(Tox_Err_Group_Founder_Set_Peer_Limit value)
+const char *tox_err_group_set_peer_limit_to_string(Tox_Err_Group_Set_Peer_Limit value)
{
switch (value) {
- case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK:
- return "TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK";
+ case TOX_ERR_GROUP_SET_PEER_LIMIT_OK:
+ return "TOX_ERR_GROUP_SET_PEER_LIMIT_OK";
- case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_GROUP_NOT_FOUND:
- return "TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_GROUP_NOT_FOUND";
+ case TOX_ERR_GROUP_SET_PEER_LIMIT_GROUP_NOT_FOUND:
+ return "TOX_ERR_GROUP_SET_PEER_LIMIT_GROUP_NOT_FOUND";
- case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_PERMISSIONS:
- return "TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_PERMISSIONS";
+ case TOX_ERR_GROUP_SET_PEER_LIMIT_PERMISSIONS:
+ return "TOX_ERR_GROUP_SET_PEER_LIMIT_PERMISSIONS";
- case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SET:
- return "TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SET";
+ case TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SET:
+ return "TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SET";
- case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SEND:
- return "TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_FAIL_SEND";
+ case TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SEND:
+ return "TOX_ERR_GROUP_SET_PEER_LIMIT_FAIL_SEND";
- case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_DISCONNECTED:
- return "TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_DISCONNECTED";
+ case TOX_ERR_GROUP_SET_PEER_LIMIT_DISCONNECTED:
+ return "TOX_ERR_GROUP_SET_PEER_LIMIT_DISCONNECTED";
}
- return "<invalid Tox_Err_Group_Founder_Set_Peer_Limit>";
+ return "<invalid Tox_Err_Group_Set_Peer_Limit>";
}
const char *tox_err_group_set_ignore_to_string(Tox_Err_Group_Set_Ignore value)
{
@@ -1649,59 +1426,59 @@ const char *tox_err_group_set_ignore_to_string(Tox_Err_Group_Set_Ignore value)
return "<invalid Tox_Err_Group_Set_Ignore>";
}
-const char *tox_err_group_mod_set_role_to_string(Tox_Err_Group_Mod_Set_Role value)
+const char *tox_err_group_set_role_to_string(Tox_Err_Group_Set_Role value)
{
switch (value) {
- case TOX_ERR_GROUP_MOD_SET_ROLE_OK:
- return "TOX_ERR_GROUP_MOD_SET_ROLE_OK";
+ case TOX_ERR_GROUP_SET_ROLE_OK:
+ return "TOX_ERR_GROUP_SET_ROLE_OK";
- case TOX_ERR_GROUP_MOD_SET_ROLE_GROUP_NOT_FOUND:
- return "TOX_ERR_GROUP_MOD_SET_ROLE_GROUP_NOT_FOUND";
+ case TOX_ERR_GROUP_SET_ROLE_GROUP_NOT_FOUND:
+ return "TOX_ERR_GROUP_SET_ROLE_GROUP_NOT_FOUND";
- case TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND:
- return "TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND";
+ case TOX_ERR_GROUP_SET_ROLE_PEER_NOT_FOUND:
+ return "TOX_ERR_GROUP_SET_ROLE_PEER_NOT_FOUND";
- case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS:
- return "TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS";
+ case TOX_ERR_GROUP_SET_ROLE_PERMISSIONS:
+ return "TOX_ERR_GROUP_SET_ROLE_PERMISSIONS";
- case TOX_ERR_GROUP_MOD_SET_ROLE_ASSIGNMENT:
- return "TOX_ERR_GROUP_MOD_SET_ROLE_ASSIGNMENT";
+ case TOX_ERR_GROUP_SET_ROLE_ASSIGNMENT:
+ return "TOX_ERR_GROUP_SET_ROLE_ASSIGNMENT";
- case TOX_ERR_GROUP_MOD_SET_ROLE_FAIL_ACTION:
- return "TOX_ERR_GROUP_MOD_SET_ROLE_FAIL_ACTION";
+ case TOX_ERR_GROUP_SET_ROLE_FAIL_ACTION:
+ return "TOX_ERR_GROUP_SET_ROLE_FAIL_ACTION";
- case TOX_ERR_GROUP_MOD_SET_ROLE_SELF:
- return "TOX_ERR_GROUP_MOD_SET_ROLE_SELF";
+ case TOX_ERR_GROUP_SET_ROLE_SELF:
+ return "TOX_ERR_GROUP_SET_ROLE_SELF";
}
- return "<invalid Tox_Err_Group_Mod_Set_Role>";
+ return "<invalid Tox_Err_Group_Set_Role>";
}
-const char *tox_err_group_mod_kick_peer_to_string(Tox_Err_Group_Mod_Kick_Peer value)
+const char *tox_err_group_kick_peer_to_string(Tox_Err_Group_Kick_Peer value)
{
switch (value) {
- case TOX_ERR_GROUP_MOD_KICK_PEER_OK:
- return "TOX_ERR_GROUP_MOD_KICK_PEER_OK";
+ case TOX_ERR_GROUP_KICK_PEER_OK:
+ return "TOX_ERR_GROUP_KICK_PEER_OK";
- case TOX_ERR_GROUP_MOD_KICK_PEER_GROUP_NOT_FOUND:
- return "TOX_ERR_GROUP_MOD_KICK_PEER_GROUP_NOT_FOUND";
+ case TOX_ERR_GROUP_KICK_PEER_GROUP_NOT_FOUND:
+ return "TOX_ERR_GROUP_KICK_PEER_GROUP_NOT_FOUND";
- case TOX_ERR_GROUP_MOD_KICK_PEER_PEER_NOT_FOUND:
- return "TOX_ERR_GROUP_MOD_KICK_PEER_PEER_NOT_FOUND";
+ case TOX_ERR_GROUP_KICK_PEER_PEER_NOT_FOUND:
+ return "TOX_ERR_GROUP_KICK_PEER_PEER_NOT_FOUND";
- case TOX_ERR_GROUP_MOD_KICK_PEER_PERMISSIONS:
- return "TOX_ERR_GROUP_MOD_KICK_PEER_PERMISSIONS";
+ case TOX_ERR_GROUP_KICK_PEER_PERMISSIONS:
+ return "TOX_ERR_GROUP_KICK_PEER_PERMISSIONS";
- case TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_ACTION:
- return "TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_ACTION";
+ case TOX_ERR_GROUP_KICK_PEER_FAIL_ACTION:
+ return "TOX_ERR_GROUP_KICK_PEER_FAIL_ACTION";
- case TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_SEND:
- return "TOX_ERR_GROUP_MOD_KICK_PEER_FAIL_SEND";
+ case TOX_ERR_GROUP_KICK_PEER_FAIL_SEND:
+ return "TOX_ERR_GROUP_KICK_PEER_FAIL_SEND";
- case TOX_ERR_GROUP_MOD_KICK_PEER_SELF:
- return "TOX_ERR_GROUP_MOD_KICK_PEER_SELF";
+ case TOX_ERR_GROUP_KICK_PEER_SELF:
+ return "TOX_ERR_GROUP_KICK_PEER_SELF";
}
- return "<invalid Tox_Err_Group_Mod_Kick_Peer>";
+ return "<invalid Tox_Err_Group_Kick_Peer>";
}
const char *tox_group_mod_event_to_string(Tox_Group_Mod_Event value)
{
@@ -1721,3 +1498,120 @@ const char *tox_group_mod_event_to_string(Tox_Group_Mod_Event value)
return "<invalid Tox_Group_Mod_Event>";
}
+const char *tox_netprof_packet_id_to_string(Tox_Netprof_Packet_Id value)
+{
+ switch (value) {
+ case TOX_NETPROF_PACKET_ID_ZERO:
+ return "TOX_NETPROF_PACKET_ID_ZERO";
+ case TOX_NETPROF_PACKET_ID_ONE:
+ return "TOX_NETPROF_PACKET_ID_ONE";
+ case TOX_NETPROF_PACKET_ID_TWO:
+ return "TOX_NETPROF_PACKET_ID_TWO";
+ case TOX_NETPROF_PACKET_ID_TCP_DISCONNECT:
+ return "TOX_NETPROF_PACKET_ID_TCP_DISCONNECT";
+ case TOX_NETPROF_PACKET_ID_FOUR:
+ return "TOX_NETPROF_PACKET_ID_FOUR";
+ case TOX_NETPROF_PACKET_ID_TCP_PONG:
+ return "TOX_NETPROF_PACKET_ID_TCP_PONG";
+ case TOX_NETPROF_PACKET_ID_TCP_OOB_SEND:
+ return "TOX_NETPROF_PACKET_ID_TCP_OOB_SEND";
+ case TOX_NETPROF_PACKET_ID_TCP_OOB_RECV:
+ return "TOX_NETPROF_PACKET_ID_TCP_OOB_RECV";
+ case TOX_NETPROF_PACKET_ID_TCP_ONION_REQUEST:
+ return "TOX_NETPROF_PACKET_ID_TCP_ONION_REQUEST";
+ case TOX_NETPROF_PACKET_ID_TCP_ONION_RESPONSE:
+ return "TOX_NETPROF_PACKET_ID_TCP_ONION_RESPONSE";
+ case TOX_NETPROF_PACKET_ID_TCP_DATA:
+ return "TOX_NETPROF_PACKET_ID_TCP_DATA";
+ case TOX_NETPROF_PACKET_ID_COOKIE_REQUEST:
+ return "TOX_NETPROF_PACKET_ID_COOKIE_REQUEST";
+ case TOX_NETPROF_PACKET_ID_COOKIE_RESPONSE:
+ return "TOX_NETPROF_PACKET_ID_COOKIE_RESPONSE";
+ case TOX_NETPROF_PACKET_ID_CRYPTO_HS:
+ return "TOX_NETPROF_PACKET_ID_CRYPTO_HS";
+ case TOX_NETPROF_PACKET_ID_CRYPTO_DATA:
+ return "TOX_NETPROF_PACKET_ID_CRYPTO_DATA";
+ case TOX_NETPROF_PACKET_ID_CRYPTO:
+ return "TOX_NETPROF_PACKET_ID_CRYPTO";
+ case TOX_NETPROF_PACKET_ID_LAN_DISCOVERY:
+ return "TOX_NETPROF_PACKET_ID_LAN_DISCOVERY";
+ case TOX_NETPROF_PACKET_ID_GC_HANDSHAKE:
+ return "TOX_NETPROF_PACKET_ID_GC_HANDSHAKE";
+ case TOX_NETPROF_PACKET_ID_GC_LOSSLESS:
+ return "TOX_NETPROF_PACKET_ID_GC_LOSSLESS";
+ case TOX_NETPROF_PACKET_ID_GC_LOSSY:
+ return "TOX_NETPROF_PACKET_ID_GC_LOSSY";
+ case TOX_NETPROF_PACKET_ID_ONION_SEND_INITIAL:
+ return "TOX_NETPROF_PACKET_ID_ONION_SEND_INITIAL";
+ case TOX_NETPROF_PACKET_ID_ONION_SEND_1:
+ return "TOX_NETPROF_PACKET_ID_ONION_SEND_1";
+ case TOX_NETPROF_PACKET_ID_ONION_SEND_2:
+ return "TOX_NETPROF_PACKET_ID_ONION_SEND_2";
+ case TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST_OLD:
+ return "TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST_OLD";
+ case TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE_OLD:
+ return "TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE_OLD";
+ case TOX_NETPROF_PACKET_ID_ONION_DATA_REQUEST:
+ return "TOX_NETPROF_PACKET_ID_ONION_DATA_REQUEST";
+ case TOX_NETPROF_PACKET_ID_ONION_DATA_RESPONSE:
+ return "TOX_NETPROF_PACKET_ID_ONION_DATA_RESPONSE";
+ case TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST:
+ return "TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST";
+ case TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE:
+ return "TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE";
+ case TOX_NETPROF_PACKET_ID_ONION_RECV_3:
+ return "TOX_NETPROF_PACKET_ID_ONION_RECV_3";
+ case TOX_NETPROF_PACKET_ID_ONION_RECV_2:
+ return "TOX_NETPROF_PACKET_ID_ONION_RECV_2";
+ case TOX_NETPROF_PACKET_ID_ONION_RECV_1:
+ return "TOX_NETPROF_PACKET_ID_ONION_RECV_1";
+ case TOX_NETPROF_PACKET_ID_FORWARD_REQUEST:
+ return "TOX_NETPROF_PACKET_ID_FORWARD_REQUEST";
+ case TOX_NETPROF_PACKET_ID_FORWARDING:
+ return "TOX_NETPROF_PACKET_ID_FORWARDING";
+ case TOX_NETPROF_PACKET_ID_FORWARD_REPLY:
+ return "TOX_NETPROF_PACKET_ID_FORWARD_REPLY";
+ case TOX_NETPROF_PACKET_ID_DATA_SEARCH_REQUEST:
+ return "TOX_NETPROF_PACKET_ID_DATA_SEARCH_REQUEST";
+ case TOX_NETPROF_PACKET_ID_DATA_SEARCH_RESPONSE:
+ return "TOX_NETPROF_PACKET_ID_DATA_SEARCH_RESPONSE";
+ case TOX_NETPROF_PACKET_ID_DATA_RETRIEVE_REQUEST:
+ return "TOX_NETPROF_PACKET_ID_DATA_RETRIEVE_REQUEST";
+ case TOX_NETPROF_PACKET_ID_DATA_RETRIEVE_RESPONSE:
+ return "TOX_NETPROF_PACKET_ID_DATA_RETRIEVE_RESPONSE";
+ case TOX_NETPROF_PACKET_ID_STORE_ANNOUNCE_REQUEST:
+ return "TOX_NETPROF_PACKET_ID_STORE_ANNOUNCE_REQUEST";
+ case TOX_NETPROF_PACKET_ID_STORE_ANNOUNCE_RESPONSE:
+ return "TOX_NETPROF_PACKET_ID_STORE_ANNOUNCE_RESPONSE";
+ case TOX_NETPROF_PACKET_ID_BOOTSTRAP_INFO:
+ return "TOX_NETPROF_PACKET_ID_BOOTSTRAP_INFO";
+ }
+
+ return "<invalid Tox_Netprof_Packet_Id>";
+}
+const char *tox_netprof_packet_type_to_string(Tox_Netprof_Packet_Type value)
+{
+ switch (value) {
+ case TOX_NETPROF_PACKET_TYPE_TCP_CLIENT:
+ return "TOX_NETPROF_PACKET_TYPE_TCP_CLIENT";
+ case TOX_NETPROF_PACKET_TYPE_TCP_SERVER:
+ return "TOX_NETPROF_PACKET_TYPE_TCP_SERVER";
+ case TOX_NETPROF_PACKET_TYPE_TCP:
+ return "TOX_NETPROF_PACKET_TYPE_TCP";
+ case TOX_NETPROF_PACKET_TYPE_UDP:
+ return "TOX_NETPROF_PACKET_TYPE_UDP";
+ }
+
+ return "<invalid Tox_Netprof_Packet_Type>";
+}
+const char *tox_netprof_direction_to_string(Tox_Netprof_Direction value)
+{
+ switch (value) {
+ case TOX_NETPROF_DIRECTION_SENT:
+ return "TOX_NETPROF_DIRECTION_SENT";
+ case TOX_NETPROF_DIRECTION_RECV:
+ return "TOX_NETPROF_DIRECTION_RECV";
+ }
+
+ return "<invalid Tox_Netprof_Direction>";
+}
diff --git a/protocols/Tox/libtox/src/toxcore/tox_dispatch.c b/protocols/Tox/libtox/src/toxcore/tox_dispatch.c
index 5383925bfa..c793f6b582 100644
--- a/protocols/Tox/libtox/src/toxcore/tox_dispatch.c
+++ b/protocols/Tox/libtox/src/toxcore/tox_dispatch.c
@@ -1,15 +1,15 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#include "tox_dispatch.h"
+#include <stdint.h>
#include <stdlib.h>
#include "attributes.h"
#include "ccompat.h"
#include "events/events_alloc.h" // IWYU pragma: keep
-#include "tox.h"
#include "tox_event.h"
#include "tox_events.h"
@@ -53,7 +53,7 @@ struct Tox_Dispatch {
tox_events_group_self_join_cb *group_self_join_callback;
tox_events_group_join_fail_cb *group_join_fail_callback;
tox_events_group_moderation_cb *group_moderation_callback;
- tox_events_dht_get_nodes_response_cb *dht_get_nodes_response_callback;
+ tox_events_dht_nodes_response_cb *dht_nodes_response_callback;
};
Tox_Dispatch *tox_dispatch_new(Tox_Err_Dispatch_New *error)
@@ -279,10 +279,10 @@ void tox_events_callback_group_moderation(
{
dispatch->group_moderation_callback = callback;
}
-void tox_events_callback_dht_get_nodes_response(
- Tox_Dispatch *dispatch, tox_events_dht_get_nodes_response_cb *callback)
+void tox_events_callback_dht_nodes_response(
+ Tox_Dispatch *dispatch, tox_events_dht_nodes_response_cb *callback)
{
- dispatch->dht_get_nodes_response_callback = callback;
+ dispatch->dht_nodes_response_callback = callback;
}
non_null(1, 2) nullable(3)
@@ -601,9 +601,9 @@ static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Ev
break;
}
- case TOX_EVENT_DHT_GET_NODES_RESPONSE: {
- if (dispatch->dht_get_nodes_response_callback != nullptr) {
- dispatch->dht_get_nodes_response_callback(event->data.dht_get_nodes_response, user_data);
+ case TOX_EVENT_DHT_NODES_RESPONSE: {
+ if (dispatch->dht_nodes_response_callback != nullptr) {
+ dispatch->dht_nodes_response_callback(event->data.dht_nodes_response, user_data);
}
break;
diff --git a/protocols/Tox/libtox/src/toxcore/tox_dispatch.h b/protocols/Tox/libtox/src/toxcore/tox_dispatch.h
index 2588065a4d..6ad3fc8b66 100644
--- a/protocols/Tox/libtox/src/toxcore/tox_dispatch.h
+++ b/protocols/Tox/libtox/src/toxcore/tox_dispatch.h
@@ -1,5 +1,12 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
+ */
+
+/**
+ * WARNING: This is an experimental API and is subject to change.
+ *
+ * At this point, it probably won't change very much anymore, but we may have
+ * small breaking changes before a stable release.
*/
#ifndef C_TOXCORE_TOXCORE_TOX_DISPATCH_H
@@ -129,8 +136,8 @@ typedef void tox_events_group_join_fail_cb(
const Tox_Event_Group_Join_Fail *event, void *user_data);
typedef void tox_events_group_moderation_cb(
const Tox_Event_Group_Moderation *event, void *user_data);
-typedef void tox_events_dht_get_nodes_response_cb(
- const Tox_Event_Dht_Get_Nodes_Response *event, void *user_data);
+typedef void tox_events_dht_nodes_response_cb(
+ const Tox_Event_Dht_Nodes_Response *event, void *user_data);
void tox_events_callback_conference_connected(
Tox_Dispatch *dispatch, tox_events_conference_connected_cb *callback);
@@ -210,8 +217,8 @@ void tox_events_callback_group_join_fail(
Tox_Dispatch *dispatch, tox_events_group_join_fail_cb *callback);
void tox_events_callback_group_moderation(
Tox_Dispatch *dispatch, tox_events_group_moderation_cb *callback);
-void tox_events_callback_dht_get_nodes_response(
- Tox_Dispatch *dispatch, tox_events_dht_get_nodes_response_cb *callback);
+void tox_events_callback_dht_nodes_response(
+ Tox_Dispatch *dispatch, tox_events_dht_nodes_response_cb *callback);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/protocols/Tox/libtox/src/toxcore/tox_event.c b/protocols/Tox/libtox/src/toxcore/tox_event.c
index b0a65503cd..0a08b622e9 100644
--- a/protocols/Tox/libtox/src/toxcore/tox_event.c
+++ b/protocols/Tox/libtox/src/toxcore/tox_event.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#include "tox_event.h"
@@ -133,8 +133,8 @@ const char *tox_event_type_to_string(Tox_Event_Type type)
case TOX_EVENT_GROUP_MODERATION:
return "TOX_EVENT_GROUP_MODERATION";
- case TOX_EVENT_DHT_GET_NODES_RESPONSE:
- return "TOX_EVENT_DHT_GET_NODES_RESPONSE";
+ case TOX_EVENT_DHT_NODES_RESPONSE:
+ return "TOX_EVENT_DHT_NODES_RESPONSE";
case TOX_EVENT_INVALID:
return "TOX_EVENT_INVALID";
@@ -350,8 +350,8 @@ bool tox_event_construct(Tox_Event *event, Tox_Event_Type type, const Memory *me
break;
}
- case TOX_EVENT_DHT_GET_NODES_RESPONSE: {
- event->data.dht_get_nodes_response = tox_event_dht_get_nodes_response_new(mem);
+ case TOX_EVENT_DHT_NODES_RESPONSE: {
+ event->data.dht_nodes_response = tox_event_dht_nodes_response_new(mem);
break;
}
@@ -565,8 +565,8 @@ void tox_event_destruct(Tox_Event *event, const Memory *mem)
break;
}
- case TOX_EVENT_DHT_GET_NODES_RESPONSE: {
- tox_event_dht_get_nodes_response_free(event->data.dht_get_nodes_response, mem);
+ case TOX_EVENT_DHT_NODES_RESPONSE: {
+ tox_event_dht_nodes_response_free(event->data.dht_nodes_response, mem);
break;
}
@@ -705,8 +705,8 @@ static bool tox_event_data_pack(Tox_Event_Type type, const Tox_Event_Data *data,
case TOX_EVENT_GROUP_MODERATION:
return tox_event_group_moderation_pack(data->group_moderation, bp);
- case TOX_EVENT_DHT_GET_NODES_RESPONSE:
- return tox_event_dht_get_nodes_response_pack(data->dht_get_nodes_response, bp);
+ case TOX_EVENT_DHT_NODES_RESPONSE:
+ return tox_event_dht_nodes_response_pack(data->dht_nodes_response, bp);
case TOX_EVENT_INVALID:
return false;
@@ -725,216 +725,216 @@ bool tox_event_pack(const Tox_Event *event, Bin_Pack *bp)
}
non_null()
-static bool tox_event_type_from_int(uint32_t value, Tox_Event_Type *out)
+static bool tox_event_type_from_int(uint32_t value, Tox_Event_Type *out_enum)
{
switch (value) {
case TOX_EVENT_SELF_CONNECTION_STATUS: {
- *out = TOX_EVENT_SELF_CONNECTION_STATUS;
+ *out_enum = TOX_EVENT_SELF_CONNECTION_STATUS;
return true;
}
case TOX_EVENT_FRIEND_REQUEST: {
- *out = TOX_EVENT_FRIEND_REQUEST;
+ *out_enum = TOX_EVENT_FRIEND_REQUEST;
return true;
}
case TOX_EVENT_FRIEND_CONNECTION_STATUS: {
- *out = TOX_EVENT_FRIEND_CONNECTION_STATUS;
+ *out_enum = TOX_EVENT_FRIEND_CONNECTION_STATUS;
return true;
}
case TOX_EVENT_FRIEND_LOSSY_PACKET: {
- *out = TOX_EVENT_FRIEND_LOSSY_PACKET;
+ *out_enum = TOX_EVENT_FRIEND_LOSSY_PACKET;
return true;
}
case TOX_EVENT_FRIEND_LOSSLESS_PACKET: {
- *out = TOX_EVENT_FRIEND_LOSSLESS_PACKET;
+ *out_enum = TOX_EVENT_FRIEND_LOSSLESS_PACKET;
return true;
}
case TOX_EVENT_FRIEND_NAME: {
- *out = TOX_EVENT_FRIEND_NAME;
+ *out_enum = TOX_EVENT_FRIEND_NAME;
return true;
}
case TOX_EVENT_FRIEND_STATUS: {
- *out = TOX_EVENT_FRIEND_STATUS;
+ *out_enum = TOX_EVENT_FRIEND_STATUS;
return true;
}
case TOX_EVENT_FRIEND_STATUS_MESSAGE: {
- *out = TOX_EVENT_FRIEND_STATUS_MESSAGE;
+ *out_enum = TOX_EVENT_FRIEND_STATUS_MESSAGE;
return true;
}
case TOX_EVENT_FRIEND_MESSAGE: {
- *out = TOX_EVENT_FRIEND_MESSAGE;
+ *out_enum = TOX_EVENT_FRIEND_MESSAGE;
return true;
}
case TOX_EVENT_FRIEND_READ_RECEIPT: {
- *out = TOX_EVENT_FRIEND_READ_RECEIPT;
+ *out_enum = TOX_EVENT_FRIEND_READ_RECEIPT;
return true;
}
case TOX_EVENT_FRIEND_TYPING: {
- *out = TOX_EVENT_FRIEND_TYPING;
+ *out_enum = TOX_EVENT_FRIEND_TYPING;
return true;
}
case TOX_EVENT_FILE_CHUNK_REQUEST: {
- *out = TOX_EVENT_FILE_CHUNK_REQUEST;
+ *out_enum = TOX_EVENT_FILE_CHUNK_REQUEST;
return true;
}
case TOX_EVENT_FILE_RECV: {
- *out = TOX_EVENT_FILE_RECV;
+ *out_enum = TOX_EVENT_FILE_RECV;
return true;
}
case TOX_EVENT_FILE_RECV_CHUNK: {
- *out = TOX_EVENT_FILE_RECV_CHUNK;
+ *out_enum = TOX_EVENT_FILE_RECV_CHUNK;
return true;
}
case TOX_EVENT_FILE_RECV_CONTROL: {
- *out = TOX_EVENT_FILE_RECV_CONTROL;
+ *out_enum = TOX_EVENT_FILE_RECV_CONTROL;
return true;
}
case TOX_EVENT_CONFERENCE_INVITE: {
- *out = TOX_EVENT_CONFERENCE_INVITE;
+ *out_enum = TOX_EVENT_CONFERENCE_INVITE;
return true;
}
case TOX_EVENT_CONFERENCE_CONNECTED: {
- *out = TOX_EVENT_CONFERENCE_CONNECTED;
+ *out_enum = TOX_EVENT_CONFERENCE_CONNECTED;
return true;
}
case TOX_EVENT_CONFERENCE_PEER_LIST_CHANGED: {
- *out = TOX_EVENT_CONFERENCE_PEER_LIST_CHANGED;
+ *out_enum = TOX_EVENT_CONFERENCE_PEER_LIST_CHANGED;
return true;
}
case TOX_EVENT_CONFERENCE_PEER_NAME: {
- *out = TOX_EVENT_CONFERENCE_PEER_NAME;
+ *out_enum = TOX_EVENT_CONFERENCE_PEER_NAME;
return true;
}
case TOX_EVENT_CONFERENCE_TITLE: {
- *out = TOX_EVENT_CONFERENCE_TITLE;
+ *out_enum = TOX_EVENT_CONFERENCE_TITLE;
return true;
}
case TOX_EVENT_CONFERENCE_MESSAGE: {
- *out = TOX_EVENT_CONFERENCE_MESSAGE;
+ *out_enum = TOX_EVENT_CONFERENCE_MESSAGE;
return true;
}
case TOX_EVENT_GROUP_PEER_NAME: {
- *out = TOX_EVENT_GROUP_PEER_NAME;
+ *out_enum = TOX_EVENT_GROUP_PEER_NAME;
return true;
}
case TOX_EVENT_GROUP_PEER_STATUS: {
- *out = TOX_EVENT_GROUP_PEER_STATUS;
+ *out_enum = TOX_EVENT_GROUP_PEER_STATUS;
return true;
}
case TOX_EVENT_GROUP_TOPIC: {
- *out = TOX_EVENT_GROUP_TOPIC;
+ *out_enum = TOX_EVENT_GROUP_TOPIC;
return true;
}
case TOX_EVENT_GROUP_PRIVACY_STATE: {
- *out = TOX_EVENT_GROUP_PRIVACY_STATE;
+ *out_enum = TOX_EVENT_GROUP_PRIVACY_STATE;
return true;
}
case TOX_EVENT_GROUP_VOICE_STATE: {
- *out = TOX_EVENT_GROUP_VOICE_STATE;
+ *out_enum = TOX_EVENT_GROUP_VOICE_STATE;
return true;
}
case TOX_EVENT_GROUP_TOPIC_LOCK: {
- *out = TOX_EVENT_GROUP_TOPIC_LOCK;
+ *out_enum = TOX_EVENT_GROUP_TOPIC_LOCK;
return true;
}
case TOX_EVENT_GROUP_PEER_LIMIT: {
- *out = TOX_EVENT_GROUP_PEER_LIMIT;
+ *out_enum = TOX_EVENT_GROUP_PEER_LIMIT;
return true;
}
case TOX_EVENT_GROUP_PASSWORD: {
- *out = TOX_EVENT_GROUP_PASSWORD;
+ *out_enum = TOX_EVENT_GROUP_PASSWORD;
return true;
}
case TOX_EVENT_GROUP_MESSAGE: {
- *out = TOX_EVENT_GROUP_MESSAGE;
+ *out_enum = TOX_EVENT_GROUP_MESSAGE;
return true;
}
case TOX_EVENT_GROUP_PRIVATE_MESSAGE: {
- *out = TOX_EVENT_GROUP_PRIVATE_MESSAGE;
+ *out_enum = TOX_EVENT_GROUP_PRIVATE_MESSAGE;
return true;
}
case TOX_EVENT_GROUP_CUSTOM_PACKET: {
- *out = TOX_EVENT_GROUP_CUSTOM_PACKET;
+ *out_enum = TOX_EVENT_GROUP_CUSTOM_PACKET;
return true;
}
case TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET: {
- *out = TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET;
+ *out_enum = TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET;
return true;
}
case TOX_EVENT_GROUP_INVITE: {
- *out = TOX_EVENT_GROUP_INVITE;
+ *out_enum = TOX_EVENT_GROUP_INVITE;
return true;
}
case TOX_EVENT_GROUP_PEER_JOIN: {
- *out = TOX_EVENT_GROUP_PEER_JOIN;
+ *out_enum = TOX_EVENT_GROUP_PEER_JOIN;
return true;
}
case TOX_EVENT_GROUP_PEER_EXIT: {
- *out = TOX_EVENT_GROUP_PEER_EXIT;
+ *out_enum = TOX_EVENT_GROUP_PEER_EXIT;
return true;
}
case TOX_EVENT_GROUP_SELF_JOIN: {
- *out = TOX_EVENT_GROUP_SELF_JOIN;
+ *out_enum = TOX_EVENT_GROUP_SELF_JOIN;
return true;
}
case TOX_EVENT_GROUP_JOIN_FAIL: {
- *out = TOX_EVENT_GROUP_JOIN_FAIL;
+ *out_enum = TOX_EVENT_GROUP_JOIN_FAIL;
return true;
}
case TOX_EVENT_GROUP_MODERATION: {
- *out = TOX_EVENT_GROUP_MODERATION;
+ *out_enum = TOX_EVENT_GROUP_MODERATION;
return true;
}
- case TOX_EVENT_DHT_GET_NODES_RESPONSE: {
- *out = TOX_EVENT_DHT_GET_NODES_RESPONSE;
+ case TOX_EVENT_DHT_NODES_RESPONSE: {
+ *out_enum = TOX_EVENT_DHT_NODES_RESPONSE;
return true;
}
case TOX_EVENT_INVALID: {
- *out = TOX_EVENT_INVALID;
+ *out_enum = TOX_EVENT_INVALID;
return true;
}
default: {
- *out = TOX_EVENT_INVALID;
+ *out_enum = TOX_EVENT_INVALID;
return false;
}
}
@@ -1069,8 +1069,8 @@ static bool tox_event_data_unpack(Tox_Event_Type type, Tox_Event_Data *data, Bin
case TOX_EVENT_GROUP_MODERATION:
return tox_event_group_moderation_unpack(&data->group_moderation, bu, mem);
- case TOX_EVENT_DHT_GET_NODES_RESPONSE:
- return tox_event_dht_get_nodes_response_unpack(&data->dht_get_nodes_response, bu, mem);
+ case TOX_EVENT_DHT_NODES_RESPONSE:
+ return tox_event_dht_nodes_response_unpack(&data->dht_nodes_response, bu, mem);
case TOX_EVENT_INVALID:
return false;
diff --git a/protocols/Tox/libtox/src/toxcore/tox_event.h b/protocols/Tox/libtox/src/toxcore/tox_event.h
index fa98aae229..eebc233608 100644
--- a/protocols/Tox/libtox/src/toxcore/tox_event.h
+++ b/protocols/Tox/libtox/src/toxcore/tox_event.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_TOX_EVENT_H
@@ -61,7 +61,7 @@ typedef union Tox_Event_Data {
Tox_Event_Group_Self_Join *group_self_join;
Tox_Event_Group_Join_Fail *group_join_fail;
Tox_Event_Group_Moderation *group_moderation;
- Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response;
+ Tox_Event_Dht_Nodes_Response *dht_nodes_response;
} Tox_Event_Data;
struct Tox_Event {
@@ -113,7 +113,7 @@ non_null() Tox_Event_Group_Peer_Exit *tox_event_group_peer_exit_new(const Memory
non_null() Tox_Event_Group_Self_Join *tox_event_group_self_join_new(const Memory *mem);
non_null() Tox_Event_Group_Join_Fail *tox_event_group_join_fail_new(const Memory *mem);
non_null() Tox_Event_Group_Moderation *tox_event_group_moderation_new(const Memory *mem);
-non_null() Tox_Event_Dht_Get_Nodes_Response *tox_event_dht_get_nodes_response_new(const Memory *mem);
+non_null() Tox_Event_Dht_Nodes_Response *tox_event_dht_nodes_response_new(const Memory *mem);
/**
* Destructor.
@@ -159,7 +159,7 @@ non_null(2) nullable(1) void tox_event_group_peer_exit_free(Tox_Event_Group_Peer
non_null(2) nullable(1) void tox_event_group_self_join_free(Tox_Event_Group_Self_Join *group_self_join, const Memory *mem);
non_null(2) nullable(1) void tox_event_group_join_fail_free(Tox_Event_Group_Join_Fail *group_join_fail, const Memory *mem);
non_null(2) nullable(1) void tox_event_group_moderation_free(Tox_Event_Group_Moderation *group_moderation, const Memory *mem);
-non_null(2) nullable(1) void tox_event_dht_get_nodes_response_free(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, const Memory *mem);
+non_null(2) nullable(1) void tox_event_dht_nodes_response_free(Tox_Event_Dht_Nodes_Response *dht_nodes_response, const Memory *mem);
/**
* Pack into msgpack.
@@ -205,7 +205,7 @@ non_null() bool tox_event_group_peer_exit_pack(const Tox_Event_Group_Peer_Exit *
non_null() bool tox_event_group_self_join_pack(const Tox_Event_Group_Self_Join *event, Bin_Pack *bp);
non_null() bool tox_event_group_join_fail_pack(const Tox_Event_Group_Join_Fail *event, Bin_Pack *bp);
non_null() bool tox_event_group_moderation_pack(const Tox_Event_Group_Moderation *event, Bin_Pack *bp);
-non_null() bool tox_event_dht_get_nodes_response_pack(const Tox_Event_Dht_Get_Nodes_Response *event, Bin_Pack *bp);
+non_null() bool tox_event_dht_nodes_response_pack(const Tox_Event_Dht_Nodes_Response *event, Bin_Pack *bp);
/**
* Unpack from msgpack.
@@ -251,7 +251,7 @@ non_null() bool tox_event_group_peer_exit_unpack(Tox_Event_Group_Peer_Exit **eve
non_null() bool tox_event_group_self_join_unpack(Tox_Event_Group_Self_Join **event, Bin_Unpack *bu, const Memory *mem);
non_null() bool tox_event_group_join_fail_unpack(Tox_Event_Group_Join_Fail **event, Bin_Unpack *bu, const Memory *mem);
non_null() bool tox_event_group_moderation_unpack(Tox_Event_Group_Moderation **event, Bin_Unpack *bu, const Memory *mem);
-non_null() bool tox_event_dht_get_nodes_response_unpack(Tox_Event_Dht_Get_Nodes_Response **event, Bin_Unpack *bu, const Memory *mem);
+non_null() bool tox_event_dht_nodes_response_unpack(Tox_Event_Dht_Nodes_Response **event, Bin_Unpack *bu, const Memory *mem);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/protocols/Tox/libtox/src/toxcore/tox_events.c b/protocols/Tox/libtox/src/toxcore/tox_events.c
index a5d995cf50..81bb76ff8c 100644
--- a/protocols/Tox/libtox/src/toxcore/tox_events.c
+++ b/protocols/Tox/libtox/src/toxcore/tox_events.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022-2024 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#include "tox_events.h"
@@ -17,7 +17,7 @@
#include "tox.h"
#include "tox_event.h"
#include "tox_private.h"
-#include "tox_struct.h"
+#include "tox_struct.h" // IWYU pragma: keep
/*****************************************************
*
@@ -66,7 +66,7 @@ void tox_events_init(Tox *tox)
tox_callback_group_self_join(tox, tox_events_handle_group_self_join);
tox_callback_group_join_fail(tox, tox_events_handle_group_join_fail);
tox_callback_group_moderation(tox, tox_events_handle_group_moderation);
- tox_callback_dht_get_nodes_response(tox, tox_events_handle_dht_get_nodes_response);
+ tox_callback_dht_nodes_response(tox, tox_events_handle_dht_nodes_response);
}
uint32_t tox_events_get_size(const Tox_Events *events)
@@ -173,7 +173,7 @@ Tox_Events *tox_events_load(const Tox_System *sys, const uint8_t *bytes, uint32_
};
events->mem = sys->mem;
- if (!bin_unpack_obj(tox_events_unpack_handler, events, bytes, bytes_size)) {
+ if (!bin_unpack_obj(sys->mem, tox_events_unpack_handler, events, bytes, bytes_size)) {
tox_events_free(events);
return nullptr;
}
diff --git a/protocols/Tox/libtox/src/toxcore/tox_events.h b/protocols/Tox/libtox/src/toxcore/tox_events.h
index 3edaa7d06b..d82930e450 100644
--- a/protocols/Tox/libtox/src/toxcore/tox_events.h
+++ b/protocols/Tox/libtox/src/toxcore/tox_events.h
@@ -1,5 +1,12 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022-2024 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
+ */
+
+/**
+ * WARNING: This is an experimental API and is subject to change.
+ *
+ * At this point, it probably won't change very much anymore, but we may have
+ * small breaking changes before a stable release.
*/
#ifndef C_TOXCORE_TOXCORE_TOX_EVENTS_H
@@ -248,7 +255,7 @@ uint32_t tox_event_group_message_get_group_number(
const Tox_Event_Group_Message *group_message);
uint32_t tox_event_group_message_get_peer_id(
const Tox_Event_Group_Message *group_message);
-Tox_Message_Type tox_event_group_message_get_type(
+Tox_Message_Type tox_event_group_message_get_message_type(
const Tox_Event_Group_Message *group_message);
const uint8_t *tox_event_group_message_get_message(
const Tox_Event_Group_Message *group_message);
@@ -262,12 +269,14 @@ uint32_t tox_event_group_private_message_get_group_number(
const Tox_Event_Group_Private_Message *group_private_message);
uint32_t tox_event_group_private_message_get_peer_id(
const Tox_Event_Group_Private_Message *group_private_message);
-Tox_Message_Type tox_event_group_private_message_get_type(
+Tox_Message_Type tox_event_group_private_message_get_message_type(
const Tox_Event_Group_Private_Message *group_private_message);
const uint8_t *tox_event_group_private_message_get_message(
const Tox_Event_Group_Private_Message *group_private_message);
uint32_t tox_event_group_private_message_get_message_length(
const Tox_Event_Group_Private_Message *group_private_message);
+uint32_t tox_event_group_private_message_get_message_id(
+ const Tox_Event_Group_Private_Message *group_private_message);
typedef struct Tox_Event_Group_Custom_Packet Tox_Event_Group_Custom_Packet;
uint32_t tox_event_group_custom_packet_get_group_number(
@@ -343,15 +352,15 @@ uint32_t tox_event_group_moderation_get_target_peer_id(
Tox_Group_Mod_Event tox_event_group_moderation_get_mod_type(
const Tox_Event_Group_Moderation *group_moderation);
-typedef struct Tox_Event_Dht_Get_Nodes_Response Tox_Event_Dht_Get_Nodes_Response;
-const uint8_t *tox_event_dht_get_nodes_response_get_public_key(
- const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response);
-const uint8_t *tox_event_dht_get_nodes_response_get_ip(
- const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response);
-uint32_t tox_event_dht_get_nodes_response_get_ip_length(
- const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response);
-uint16_t tox_event_dht_get_nodes_response_get_port(
- const Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response);
+typedef struct Tox_Event_Dht_Nodes_Response Tox_Event_Dht_Nodes_Response;
+const uint8_t *tox_event_dht_nodes_response_get_public_key(
+ const Tox_Event_Dht_Nodes_Response *dht_nodes_response);
+const uint8_t *tox_event_dht_nodes_response_get_ip(
+ const Tox_Event_Dht_Nodes_Response *dht_nodes_response);
+uint32_t tox_event_dht_nodes_response_get_ip_length(
+ const Tox_Event_Dht_Nodes_Response *dht_nodes_response);
+uint16_t tox_event_dht_nodes_response_get_port(
+ const Tox_Event_Dht_Nodes_Response *dht_nodes_response);
typedef enum Tox_Event_Type {
TOX_EVENT_SELF_CONNECTION_STATUS = 0,
@@ -401,7 +410,7 @@ typedef enum Tox_Event_Type {
TOX_EVENT_GROUP_JOIN_FAIL = 37,
TOX_EVENT_GROUP_MODERATION = 38,
- TOX_EVENT_DHT_GET_NODES_RESPONSE = 39,
+ TOX_EVENT_DHT_NODES_RESPONSE = 39,
TOX_EVENT_INVALID = 255,
} Tox_Event_Type;
@@ -498,7 +507,7 @@ const Tox_Event_Group_Join_Fail *tox_event_get_group_join_fail(
const Tox_Event *event);
const Tox_Event_Group_Moderation *tox_event_get_group_moderation(
const Tox_Event *event);
-const Tox_Event_Dht_Get_Nodes_Response *tox_event_get_dht_get_nodes_response(
+const Tox_Event_Dht_Nodes_Response *tox_event_get_dht_nodes_response(
const Tox_Event *event);
/**
@@ -568,6 +577,8 @@ void tox_events_free(Tox_Events *events);
uint32_t tox_events_bytes_size(const Tox_Events *events);
bool tox_events_get_bytes(const Tox_Events *events, uint8_t *bytes);
+typedef struct Tox_System Tox_System;
+
Tox_Events *tox_events_load(const Tox_System *sys, const uint8_t *bytes, uint32_t bytes_size);
bool tox_events_equal(const Tox_System *sys, const Tox_Events *a, const Tox_Events *b);
diff --git a/protocols/Tox/libtox/src/toxcore/tox_log_level.c b/protocols/Tox/libtox/src/toxcore/tox_log_level.c
new file mode 100644
index 0000000000..04f83b0f9a
--- /dev/null
+++ b/protocols/Tox/libtox/src/toxcore/tox_log_level.c
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright © 2016-2025 The TokTok team.
+ * Copyright © 2013 Tox project.
+ */
+#include "tox_log_level.h"
+
+const char *tox_log_level_to_string(Tox_Log_Level value)
+{
+ switch (value) {
+ case TOX_LOG_LEVEL_TRACE:
+ return "TOX_LOG_LEVEL_TRACE";
+
+ case TOX_LOG_LEVEL_DEBUG:
+ return "TOX_LOG_LEVEL_DEBUG";
+
+ case TOX_LOG_LEVEL_INFO:
+ return "TOX_LOG_LEVEL_INFO";
+
+ case TOX_LOG_LEVEL_WARNING:
+ return "TOX_LOG_LEVEL_WARNING";
+
+ case TOX_LOG_LEVEL_ERROR:
+ return "TOX_LOG_LEVEL_ERROR";
+ }
+
+ return "<invalid Tox_Log_Level>";
+}
diff --git a/protocols/Tox/libtox/src/toxcore/tox_log_level.h b/protocols/Tox/libtox/src/toxcore/tox_log_level.h
new file mode 100644
index 0000000000..0009ecd54b
--- /dev/null
+++ b/protocols/Tox/libtox/src/toxcore/tox_log_level.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright © 2022-2025 The TokTok team.
+ */
+
+#ifndef C_TOXCORE_TOXCORE_TOX_LOG_LEVEL_H
+#define C_TOXCORE_TOXCORE_TOX_LOG_LEVEL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Severity level of log messages.
+ */
+typedef enum Tox_Log_Level {
+ /**
+ * Very detailed traces including all network activity.
+ */
+ TOX_LOG_LEVEL_TRACE,
+
+ /**
+ * Debug messages such as which port we bind to.
+ */
+ TOX_LOG_LEVEL_DEBUG,
+
+ /**
+ * Informational log messages such as video call status changes.
+ */
+ TOX_LOG_LEVEL_INFO,
+
+ /**
+ * Warnings about internal inconsistency or logic errors.
+ */
+ TOX_LOG_LEVEL_WARNING,
+
+ /**
+ * Severe unexpected errors caused by external or internal inconsistency.
+ */
+ TOX_LOG_LEVEL_ERROR,
+} Tox_Log_Level;
+
+const char *tox_log_level_to_string(Tox_Log_Level value);
+
+//!TOKSTYLE-
+#ifndef DOXYGEN_IGNORE
+
+#ifndef TOX_HIDE_DEPRECATED
+typedef Tox_Log_Level TOX_LOG_LEVEL;
+#endif /* TOX_HIDE_DEPRECATED */
+
+#endif
+//!TOKSTYLE+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* C_TOXCORE_TOXCORE_TOX_LOG_LEVEL_H */
diff --git a/protocols/Tox/libtox/src/toxcore/tox_options.c b/protocols/Tox/libtox/src/toxcore/tox_options.c
new file mode 100644
index 0000000000..d67a8aebd0
--- /dev/null
+++ b/protocols/Tox/libtox/src/toxcore/tox_options.c
@@ -0,0 +1,285 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright © 2016-2025 The TokTok team.
+ * Copyright © 2013 Tox project.
+ */
+
+#include "tox_options.h"
+
+#include <stdlib.h> // free, malloc, calloc
+#include <string.h> // memcpy, strlen
+
+#include "ccompat.h" // nullptr
+
+#define SET_ERROR_PARAMETER(param, x) \
+ do { \
+ if (param != nullptr) { \
+ *param = x; \
+ } \
+ } while (0)
+
+
+bool tox_options_get_ipv6_enabled(const Tox_Options *options)
+{
+ return options->ipv6_enabled;
+}
+void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled)
+{
+ options->ipv6_enabled = ipv6_enabled;
+}
+bool tox_options_get_udp_enabled(const Tox_Options *options)
+{
+ return options->udp_enabled;
+}
+void tox_options_set_udp_enabled(Tox_Options *options, bool udp_enabled)
+{
+ options->udp_enabled = udp_enabled;
+}
+Tox_Proxy_Type tox_options_get_proxy_type(const Tox_Options *options)
+{
+ return options->proxy_type;
+}
+void tox_options_set_proxy_type(Tox_Options *options, Tox_Proxy_Type proxy_type)
+{
+ options->proxy_type = proxy_type;
+}
+const char *tox_options_get_proxy_host(const Tox_Options *options)
+{
+ return options->proxy_host;
+}
+bool tox_options_set_proxy_host(Tox_Options *options, const char *proxy_host)
+{
+ if (!options->experimental_owned_data) {
+ options->proxy_host = proxy_host;
+ return true;
+ }
+
+ if (options->owned_proxy_host != nullptr) {
+ free(options->owned_proxy_host);
+ options->owned_proxy_host = nullptr;
+ }
+ if (proxy_host == nullptr) {
+ options->proxy_host = nullptr;
+ return true;
+ }
+
+ const size_t proxy_host_length = strlen(proxy_host) + 1;
+ char *owned_ptr = (char *)malloc(proxy_host_length);
+ if (owned_ptr == nullptr) {
+ options->proxy_host = proxy_host;
+ options->owned_proxy_host = nullptr;
+ return false;
+ }
+
+ memcpy(owned_ptr, proxy_host, proxy_host_length);
+ options->proxy_host = owned_ptr;
+ options->owned_proxy_host = owned_ptr;
+ return true;
+}
+uint16_t tox_options_get_proxy_port(const Tox_Options *options)
+{
+ return options->proxy_port;
+}
+void tox_options_set_proxy_port(Tox_Options *options, uint16_t proxy_port)
+{
+ options->proxy_port = proxy_port;
+}
+uint16_t tox_options_get_start_port(const Tox_Options *options)
+{
+ return options->start_port;
+}
+void tox_options_set_start_port(Tox_Options *options, uint16_t start_port)
+{
+ options->start_port = start_port;
+}
+uint16_t tox_options_get_end_port(const Tox_Options *options)
+{
+ return options->end_port;
+}
+void tox_options_set_end_port(Tox_Options *options, uint16_t end_port)
+{
+ options->end_port = end_port;
+}
+uint16_t tox_options_get_tcp_port(const Tox_Options *options)
+{
+ return options->tcp_port;
+}
+void tox_options_set_tcp_port(Tox_Options *options, uint16_t tcp_port)
+{
+ options->tcp_port = tcp_port;
+}
+bool tox_options_get_hole_punching_enabled(const Tox_Options *options)
+{
+ return options->hole_punching_enabled;
+}
+void tox_options_set_hole_punching_enabled(Tox_Options *options, bool hole_punching_enabled)
+{
+ options->hole_punching_enabled = hole_punching_enabled;
+}
+Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options *options)
+{
+ return options->savedata_type;
+}
+void tox_options_set_savedata_type(Tox_Options *options, Tox_Savedata_Type savedata_type)
+{
+ options->savedata_type = savedata_type;
+}
+size_t tox_options_get_savedata_length(const Tox_Options *options)
+{
+ return options->savedata_length;
+}
+void tox_options_set_savedata_length(Tox_Options *options, size_t savedata_length)
+{
+ options->savedata_length = savedata_length;
+}
+tox_log_cb *tox_options_get_log_callback(const Tox_Options *options)
+{
+ return options->log_callback;
+}
+void tox_options_set_log_callback(Tox_Options *options, tox_log_cb *log_callback)
+{
+ options->log_callback = log_callback;
+}
+void *tox_options_get_log_user_data(const Tox_Options *options)
+{
+ return options->log_user_data;
+}
+void tox_options_set_log_user_data(Tox_Options *options, void *log_user_data)
+{
+ options->log_user_data = log_user_data;
+}
+bool tox_options_get_local_discovery_enabled(const Tox_Options *options)
+{
+ return options->local_discovery_enabled;
+}
+void tox_options_set_local_discovery_enabled(Tox_Options *options, bool local_discovery_enabled)
+{
+ options->local_discovery_enabled = local_discovery_enabled;
+}
+bool tox_options_get_dht_announcements_enabled(const Tox_Options *options)
+{
+ return options->dht_announcements_enabled;
+}
+void tox_options_set_dht_announcements_enabled(Tox_Options *options, bool dht_announcements_enabled)
+{
+ options->dht_announcements_enabled = dht_announcements_enabled;
+}
+bool tox_options_get_experimental_thread_safety(const Tox_Options *options)
+{
+ return options->experimental_thread_safety;
+}
+void tox_options_set_experimental_thread_safety(
+ Tox_Options *options, bool experimental_thread_safety)
+{
+ options->experimental_thread_safety = experimental_thread_safety;
+}
+bool tox_options_get_experimental_groups_persistence(const Tox_Options *options)
+{
+ return options->experimental_groups_persistence;
+}
+void tox_options_set_experimental_groups_persistence(
+ Tox_Options *options, bool experimental_groups_persistence)
+{
+ options->experimental_groups_persistence = experimental_groups_persistence;
+}
+bool tox_options_get_experimental_disable_dns(const Tox_Options *options)
+{
+ return options->experimental_disable_dns;
+}
+void tox_options_set_experimental_disable_dns(Tox_Options *options, bool experimental_disable_dns)
+{
+ options->experimental_disable_dns = experimental_disable_dns;
+}
+bool tox_options_get_experimental_owned_data(const Tox_Options *options)
+{
+ return options->experimental_owned_data;
+}
+void tox_options_set_experimental_owned_data(
+ Tox_Options *options, bool experimental_owned_data)
+{
+ options->experimental_owned_data = experimental_owned_data;
+}
+
+const uint8_t *tox_options_get_savedata_data(const Tox_Options *options)
+{
+ return options->savedata_data;
+}
+
+bool tox_options_set_savedata_data(Tox_Options *options, const uint8_t *savedata_data, size_t length)
+{
+ if (!options->experimental_owned_data) {
+ options->savedata_data = savedata_data;
+ options->savedata_length = length;
+ return true;
+ }
+
+ if (options->owned_savedata_data != nullptr) {
+ free(options->owned_savedata_data);
+ options->owned_savedata_data = nullptr;
+ }
+ if (savedata_data == nullptr) {
+ options->savedata_data = nullptr;
+ options->savedata_length = 0;
+ return true;
+ }
+
+ uint8_t *owned_ptr = (uint8_t *)malloc(length);
+ if (owned_ptr == nullptr) {
+ options->savedata_data = savedata_data;
+ options->savedata_length = length;
+ options->owned_savedata_data = nullptr;
+ return false;
+ }
+
+ memcpy(owned_ptr, savedata_data, length);
+ options->savedata_data = owned_ptr;
+ options->savedata_length = length;
+ options->owned_savedata_data = owned_ptr;
+ return true;
+}
+
+void tox_options_default(Tox_Options *options)
+{
+ if (options != nullptr) {
+ // Free any owned data.
+ tox_options_set_proxy_host(options, nullptr);
+ tox_options_set_savedata_data(options, nullptr, 0);
+
+ // Set the rest to default values.
+ const Tox_Options default_options = {false};
+ *options = default_options;
+ tox_options_set_ipv6_enabled(options, true);
+ tox_options_set_udp_enabled(options, true);
+ tox_options_set_proxy_type(options, TOX_PROXY_TYPE_NONE);
+ tox_options_set_hole_punching_enabled(options, true);
+ tox_options_set_local_discovery_enabled(options, true);
+ tox_options_set_dht_announcements_enabled(options, true);
+ tox_options_set_experimental_thread_safety(options, false);
+ tox_options_set_experimental_groups_persistence(options, false);
+ tox_options_set_experimental_disable_dns(options, false);
+ tox_options_set_experimental_owned_data(options, false);
+ }
+}
+
+Tox_Options *tox_options_new(Tox_Err_Options_New *error)
+{
+ Tox_Options *options = (Tox_Options *)calloc(1, sizeof(Tox_Options));
+
+ if (options != nullptr) {
+ tox_options_default(options);
+ SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_OK);
+ return options;
+ }
+
+ SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_MALLOC);
+ return nullptr;
+}
+
+void tox_options_free(Tox_Options *options)
+{
+ if (options != nullptr) {
+ // Free any owned data.
+ tox_options_set_proxy_host(options, nullptr);
+ tox_options_set_savedata_data(options, nullptr, 0);
+ free(options);
+ }
+}
diff --git a/protocols/Tox/libtox/src/toxcore/tox_options.h b/protocols/Tox/libtox/src/toxcore/tox_options.h
new file mode 100644
index 0000000000..7d8b7aafaa
--- /dev/null
+++ b/protocols/Tox/libtox/src/toxcore/tox_options.h
@@ -0,0 +1,455 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright © 2016-2025 The TokTok team.
+ * Copyright © 2013 Tox project.
+ */
+
+#ifndef C_TOXCORE_TOXCORE_TOX_OPTIONS_H
+#define C_TOXCORE_TOXCORE_TOX_OPTIONS_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "tox_log_level.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Tox;
+
+/** @{
+ * @name Startup options
+ */
+
+/**
+ * @brief Type of proxy used to connect to TCP relays.
+ */
+typedef enum Tox_Proxy_Type {
+ /**
+ * Don't use a proxy.
+ */
+ TOX_PROXY_TYPE_NONE,
+
+ /**
+ * HTTP proxy using CONNECT.
+ */
+ TOX_PROXY_TYPE_HTTP,
+
+ /**
+ * SOCKS proxy for simple socket pipes.
+ */
+ TOX_PROXY_TYPE_SOCKS5,
+} Tox_Proxy_Type;
+
+const char *tox_proxy_type_to_string(Tox_Proxy_Type value);
+
+/**
+ * @brief Type of savedata to create the Tox instance from.
+ */
+typedef enum Tox_Savedata_Type {
+ /**
+ * No savedata.
+ */
+ TOX_SAVEDATA_TYPE_NONE,
+
+ /**
+ * Savedata is one that was obtained from tox_get_savedata.
+ */
+ TOX_SAVEDATA_TYPE_TOX_SAVE,
+
+ /**
+ * Savedata is a secret key of length TOX_SECRET_KEY_SIZE.
+ */
+ TOX_SAVEDATA_TYPE_SECRET_KEY,
+} Tox_Savedata_Type;
+
+const char *tox_savedata_type_to_string(Tox_Savedata_Type value);
+
+/**
+ * @brief This event is triggered when Tox logs an internal message.
+ *
+ * This is mostly useful for debugging. This callback can be called from any
+ * function, not just tox_iterate. This means the user data lifetime must at
+ * least extend between registering and unregistering it or tox_kill.
+ *
+ * Other toxcore modules such as toxav may concurrently call this callback at
+ * any time. Thus, user code must make sure it is equipped to handle concurrent
+ * execution, e.g. by employing appropriate mutex locking.
+ *
+ * When using the experimental_thread_safety option, no Tox API functions can
+ * be called from within the log callback.
+ *
+ * @param level The severity of the log message.
+ * @param file The source file from which the message originated.
+ * @param line The source line from which the message originated.
+ * @param func The function from which the message originated.
+ * @param message The log message.
+ * @param user_data The user data pointer passed to tox_new in options.
+ */
+typedef void tox_log_cb(struct Tox *tox, Tox_Log_Level level, const char *file,
+ uint32_t line, const char *func, const char *message,
+ void *user_data);
+
+/**
+ * @brief This struct contains all the startup options for Tox.
+ *
+ * You must tox_options_new to allocate an object of this type.
+ *
+ * WARNING: Although this struct happens to be visible in the API, it is
+ * effectively private. Do not allocate this yourself or access members
+ * directly, as it *will* break binary compatibility frequently.
+ *
+ * @deprecated The memory layout of this struct (size, alignment, and field
+ * order) is not part of the ABI. To remain compatible, prefer to use
+ * tox_options_new to allocate the object and accessor functions to set the
+ * members. The struct will become opaque (i.e. the definition will become
+ * private) in v0.3.0.
+ */
+typedef struct Tox_Options Tox_Options;
+
+#ifndef TOX_HIDE_DEPRECATED
+struct Tox_Options {
+ /**
+ * The type of socket to create.
+ *
+ * If this is set to false, an IPv4 socket is created, which subsequently
+ * only allows IPv4 communication.
+ * If it is set to true, an IPv6 socket is created, allowing both IPv4 and
+ * IPv6 communication.
+ */
+ bool ipv6_enabled;
+
+ /**
+ * Enable the use of UDP communication when available.
+ *
+ * Setting this to false will force Tox to use TCP only. Communications will
+ * need to be relayed through a TCP relay node, potentially slowing them
+ * down.
+ *
+ * If a proxy is enabled, UDP will be disabled if either the Tox library or
+ * the proxy don't support proxying UDP messages.
+ */
+ bool udp_enabled;
+
+ /**
+ * Enable local network peer discovery.
+ *
+ * Disabling this will cause Tox to not look for peers on the local network.
+ */
+ bool local_discovery_enabled;
+
+ /**
+ * Enable storing DHT announcements and forwarding corresponding requests.
+ *
+ * Disabling this will cause Tox to ignore the relevant packets.
+ */
+ bool dht_announcements_enabled;
+
+ /**
+ * Pass communications through a proxy.
+ */
+ Tox_Proxy_Type proxy_type;
+
+ /**
+ * The IP address or DNS name of the proxy to be used.
+ *
+ * If used, this must be non-NULL and be a valid DNS name. The name must not
+ * exceed TOX_MAX_HOSTNAME_LENGTH characters, and be in a NUL-terminated C
+ * string format (TOX_MAX_HOSTNAME_LENGTH includes the NUL byte).
+ *
+ * This member is ignored (it can be NULL) if proxy_type is
+ * TOX_PROXY_TYPE_NONE.
+ *
+ * The data pointed at by this member is owned by the user, so must
+ * outlive the options object (unless experimental_owned_data is set).
+ */
+ const char *proxy_host;
+
+ /**
+ * The port to use to connect to the proxy server.
+ *
+ * Ports must be in the range (1, 65535). The value is ignored if
+ * proxy_type is TOX_PROXY_TYPE_NONE.
+ */
+ uint16_t proxy_port;
+
+ /**
+ * The start port of the inclusive port range to attempt to use.
+ *
+ * If both start_port and end_port are 0, the default port range will be
+ * used: `[33445, 33545]`.
+ *
+ * If either start_port or end_port is 0 while the other is non-zero, the
+ * non-zero port will be the only port in the range.
+ *
+ * Having start_port > end_port will yield the same behavior as if
+ * start_port and end_port were swapped.
+ */
+ uint16_t start_port;
+
+ /**
+ * The end port of the inclusive port range to attempt to use.
+ */
+ uint16_t end_port;
+
+ /**
+ * The port to use for the TCP server (relay). If 0, the TCP server is
+ * disabled.
+ *
+ * Enabling it is not required for Tox to function properly.
+ *
+ * When enabled, your Tox instance can act as a TCP relay for other Tox
+ * instance. This leads to increased traffic, thus when writing a client
+ * it is recommended to enable TCP server only if the user has an option
+ * to disable it.
+ */
+ uint16_t tcp_port;
+
+ /**
+ * Enables or disables UDP hole-punching. (Default: enabled).
+ */
+ bool hole_punching_enabled;
+
+ /**
+ * The type of savedata to load from.
+ */
+ Tox_Savedata_Type savedata_type;
+
+ /**
+ * The savedata (either a Tox save or a secret key) to load from.
+ *
+ * The data pointed at by this member is owned by the user, so must
+ * outlive the options object (unless experimental_owned_data is set).
+ */
+ const uint8_t *savedata_data;
+
+ /**
+ * The length of the savedata.
+ */
+ size_t savedata_length;
+
+ /**
+ * Logging callback for the new Tox instance.
+ */
+ tox_log_cb *log_callback;
+
+ /**
+ * User data pointer passed to the logging callback.
+ */
+ void *log_user_data;
+
+ /**
+ * These options are experimental, so avoid writing code that depends on
+ * them. Options marked "experimental" may change their behaviour or go away
+ * entirely in the future, or may be renamed to something non-experimental
+ * if they become part of the supported API.
+ */
+ /**
+ * Make public API functions thread-safe using a per-instance lock.
+ *
+ * Default: false.
+ */
+ bool experimental_thread_safety;
+
+ /**
+ * Enable saving DHT-based group chats to Tox save data (via
+ * `tox_get_savedata`). This format will change in the future, so don't rely
+ * on it.
+ *
+ * As an alternative, clients can save the group chat ID in client-owned
+ * savedata. Then, when the client starts, it can use `tox_group_join`
+ * with the saved chat ID to recreate the group chat.
+ *
+ * Default: false.
+ */
+ bool experimental_groups_persistence;
+
+ /**
+ * @brief Disable DNS hostname resolution.
+ *
+ * Hostnames or IP addresses are passed to the bootstrap/add_tcp_relay
+ * function and proxy host options. If disabled (this flag is true), only
+ * IP addresses are allowed.
+ *
+ * If this is set to true, the library will not attempt to resolve
+ * hostnames. This is useful for clients that want to resolve hostnames
+ * themselves and pass the resolved IP addresses to the library (e.g. in
+ * case it wants to use Tor).
+ * Passing hostnames will result in a TOX_ERR_BOOTSTRAP_BAD_HOST error if
+ * this is set to true.
+ *
+ * Default: false. May become true in the future (0.3.0).
+ */
+ bool experimental_disable_dns;
+
+ /**
+ * @brief Whether the savedata data is owned by the Tox_Options object.
+ *
+ * If true, the setters for savedata and proxy_host try to copy the string.
+ * If that fails, the value is not copied and the member is set to the
+ * user-provided pointer. In that case, the user must not free the string
+ * until the Tox_Options object is freed. Client code can check whether
+ * allocation succeeded by checking the returned bool. If
+ * experimental_owned_data is false, it will always return true. If set to
+ * true, the return value will be false on allocation failure.
+ *
+ * If set to true, this must be set before any other member that allocates
+ * memory is set.
+ */
+ bool experimental_owned_data;
+
+ /**
+ * @brief Owned pointer to the savedata data.
+ * @private
+ */
+ uint8_t *owned_savedata_data;
+
+ /**
+ * @brief Owned pointer to the proxy host.
+ * @private
+ */
+ char *owned_proxy_host;
+};
+#endif /* TOX_HIDE_DEPRECATED */
+
+bool tox_options_get_ipv6_enabled(const Tox_Options *options);
+
+void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled);
+
+bool tox_options_get_udp_enabled(const Tox_Options *options);
+
+void tox_options_set_udp_enabled(Tox_Options *options, bool udp_enabled);
+
+bool tox_options_get_local_discovery_enabled(const Tox_Options *options);
+
+void tox_options_set_local_discovery_enabled(Tox_Options *options, bool local_discovery_enabled);
+
+bool tox_options_get_dht_announcements_enabled(const Tox_Options *options);
+
+void tox_options_set_dht_announcements_enabled(
+ Tox_Options *options, bool dht_announcements_enabled);
+
+Tox_Proxy_Type tox_options_get_proxy_type(const Tox_Options *options);
+
+void tox_options_set_proxy_type(Tox_Options *options, Tox_Proxy_Type proxy_type);
+
+const char *tox_options_get_proxy_host(const Tox_Options *options);
+
+bool tox_options_set_proxy_host(Tox_Options *options, const char *proxy_host);
+
+uint16_t tox_options_get_proxy_port(const Tox_Options *options);
+
+void tox_options_set_proxy_port(Tox_Options *options, uint16_t proxy_port);
+
+uint16_t tox_options_get_start_port(const Tox_Options *options);
+
+void tox_options_set_start_port(Tox_Options *options, uint16_t start_port);
+
+uint16_t tox_options_get_end_port(const Tox_Options *options);
+
+void tox_options_set_end_port(Tox_Options *options, uint16_t end_port);
+
+uint16_t tox_options_get_tcp_port(const Tox_Options *options);
+
+void tox_options_set_tcp_port(Tox_Options *options, uint16_t tcp_port);
+
+bool tox_options_get_hole_punching_enabled(const Tox_Options *options);
+
+void tox_options_set_hole_punching_enabled(Tox_Options *options, bool hole_punching_enabled);
+
+Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options *options);
+
+void tox_options_set_savedata_type(Tox_Options *options, Tox_Savedata_Type savedata_type);
+
+const uint8_t *tox_options_get_savedata_data(const Tox_Options *options);
+
+bool tox_options_set_savedata_data(
+ Tox_Options *options, const uint8_t savedata_data[], size_t length);
+
+size_t tox_options_get_savedata_length(const Tox_Options *options);
+
+void tox_options_set_savedata_length(Tox_Options *options, size_t savedata_length);
+
+tox_log_cb *tox_options_get_log_callback(const Tox_Options *options);
+
+void tox_options_set_log_callback(Tox_Options *options, tox_log_cb *log_callback);
+
+void *tox_options_get_log_user_data(const Tox_Options *options);
+
+void tox_options_set_log_user_data(Tox_Options *options, void *log_user_data);
+
+bool tox_options_get_experimental_owned_data(const Tox_Options *options);
+
+void tox_options_set_experimental_owned_data(Tox_Options *options, bool experimental_owned_data);
+
+bool tox_options_get_experimental_thread_safety(const Tox_Options *options);
+
+void tox_options_set_experimental_thread_safety(
+ Tox_Options *options, bool experimental_thread_safety);
+
+bool tox_options_get_experimental_groups_persistence(const Tox_Options *options);
+
+void tox_options_set_experimental_groups_persistence(
+ Tox_Options *options, bool experimental_groups_persistence);
+
+bool tox_options_get_experimental_disable_dns(const Tox_Options *options);
+
+void tox_options_set_experimental_disable_dns(Tox_Options *options, bool experimental_disable_dns);
+
+/**
+ * @brief Initialises a Tox_Options object with the default options.
+ *
+ * The result of this function is independent of the original options. All
+ * values will be overwritten, no values will be read (so it is permissible
+ * to pass an uninitialised object).
+ *
+ * If options is NULL, this function has no effect.
+ *
+ * @param options An options object to be filled with default options.
+ */
+void tox_options_default(Tox_Options *options);
+
+typedef enum Tox_Err_Options_New {
+ /**
+ * The function returned successfully.
+ */
+ TOX_ERR_OPTIONS_NEW_OK,
+
+ /**
+ * The function failed to allocate enough memory for the options struct.
+ */
+ TOX_ERR_OPTIONS_NEW_MALLOC,
+} Tox_Err_Options_New;
+
+const char *tox_err_options_new_to_string(Tox_Err_Options_New value);
+
+/**
+ * @brief Allocates a new Tox_Options object and initialises it with the default
+ * options.
+ *
+ * This function can be used to preserve long term ABI compatibility by
+ * giving the responsibility of allocation and deallocation to the Tox library.
+ *
+ * Objects returned from this function must be freed using the tox_options_free
+ * function.
+ *
+ * @return A new Tox_Options object with default options or NULL on failure.
+ */
+Tox_Options *tox_options_new(Tox_Err_Options_New *error);
+
+/**
+ * @brief Releases all resources associated with an options objects.
+ *
+ * Passing a pointer that was not returned by tox_options_new results in
+ * undefined behaviour.
+ */
+void tox_options_free(Tox_Options *options);
+
+/** @} */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* C_TOXCORE_TOXCORE_TOX_OPTIONS_H */
diff --git a/protocols/Tox/libtox/src/toxcore/tox_pack.c b/protocols/Tox/libtox/src/toxcore/tox_pack.c
index 3d584ac708..63995c8464 100644
--- a/protocols/Tox/libtox/src/toxcore/tox_pack.c
+++ b/protocols/Tox/libtox/src/toxcore/tox_pack.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#include "tox_pack.h"
diff --git a/protocols/Tox/libtox/src/toxcore/tox_pack.h b/protocols/Tox/libtox/src/toxcore/tox_pack.h
index ea8605dcc3..895cd232bb 100644
--- a/protocols/Tox/libtox/src/toxcore/tox_pack.h
+++ b/protocols/Tox/libtox/src/toxcore/tox_pack.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_TOX_PACK_H
diff --git a/protocols/Tox/libtox/src/toxcore/tox_private.c b/protocols/Tox/libtox/src/toxcore/tox_private.c
index 7b6050a9f8..dd9c63cd36 100644
--- a/protocols/Tox/libtox/src/toxcore/tox_private.c
+++ b/protocols/Tox/libtox/src/toxcore/tox_private.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2022 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -11,16 +11,19 @@
#include <assert.h>
#include "DHT.h"
-#include "attributes.h"
+#include "Messenger.h"
+#include "TCP_server.h"
#include "ccompat.h"
#include "crypto_core.h"
#include "group_chats.h"
#include "group_common.h"
+#include "logger.h"
#include "mem.h"
#include "net_crypto.h"
+#include "net_profile.h"
#include "network.h"
#include "tox.h"
-#include "tox_struct.h"
+#include "tox_struct.h" // IWYU pragma: keep
#define SET_ERROR_PARAMETER(param, x) \
do { \
@@ -91,43 +94,43 @@ void *tox_get_av_object(const Tox *tox)
return object;
}
-void tox_callback_dht_get_nodes_response(Tox *tox, tox_dht_get_nodes_response_cb *callback)
+void tox_callback_dht_nodes_response(Tox *tox, tox_dht_nodes_response_cb *callback)
{
assert(tox != nullptr);
- tox->dht_get_nodes_response_callback = callback;
+ tox->dht_nodes_response_callback = callback;
}
-bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port,
- const uint8_t *target_public_key, Tox_Err_Dht_Get_Nodes *error)
+bool tox_dht_send_nodes_request(const Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port,
+ const uint8_t *target_public_key, Tox_Err_Dht_Send_Nodes_Request *error)
{
assert(tox != nullptr);
tox_lock(tox);
if (tox->m->options.udp_disabled) {
- SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_UDP_DISABLED);
+ SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_UDP_DISABLED);
tox_unlock(tox);
return false;
}
if (public_key == nullptr || ip == nullptr || target_public_key == nullptr) {
- SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_NULL);
+ SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_NULL);
tox_unlock(tox);
return false;
}
if (port == 0) {
- SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_BAD_PORT);
+ SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_BAD_PORT);
tox_unlock(tox);
return false;
}
IP_Port *root;
- const int32_t count = net_getipport(tox->sys.mem, ip, &root, TOX_SOCK_DGRAM);
+ const int32_t count = net_getipport(tox->sys.ns, tox->sys.mem, ip, &root, TOX_SOCK_DGRAM, tox->m->options.dns_enabled);
if (count < 1) {
- SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_BAD_IP);
+ SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_BAD_IP);
net_freeipport(tox->sys.mem, root);
tox_unlock(tox);
return false;
@@ -138,7 +141,7 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip
for (int32_t i = 0; i < count; ++i) {
root[i].port = net_htons(port);
- if (dht_getnodes(tox->m->dht, &root[i], public_key, target_public_key)) {
+ if (dht_send_nodes_request(tox->m->dht, &root[i], public_key, target_public_key)) {
success = true;
}
}
@@ -148,11 +151,11 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip
net_freeipport(tox->sys.mem, root);
if (!success) {
- SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_FAIL);
+ SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_FAIL);
return false;
}
- SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_OK);
+ SET_ERROR_PARAMETER(error, TOX_ERR_DHT_SEND_NODES_REQUEST_OK);
return true;
}
@@ -226,3 +229,199 @@ bool tox_group_peer_get_ip_address(const Tox *tox, uint32_t group_number, uint32
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_OK);
return true;
}
+
+uint64_t tox_netprof_get_packet_id_count(const Tox *tox, Tox_Netprof_Packet_Type type, uint8_t id,
+ Tox_Netprof_Direction direction)
+{
+ assert(tox != nullptr);
+
+ tox_lock(tox);
+
+ const Net_Profile *tcp_c_profile = tox->m->tcp_np;
+ const Net_Profile *tcp_s_profile = tcp_server_get_net_profile(tox->m->tcp_server);
+
+ const Packet_Direction dir = (Packet_Direction) direction;
+
+ uint64_t count = 0;
+
+ switch (type) {
+ case TOX_NETPROF_PACKET_TYPE_TCP_CLIENT: {
+ count = netprof_get_packet_count_id(tcp_c_profile, id, dir);
+ break;
+ }
+
+ case TOX_NETPROF_PACKET_TYPE_TCP_SERVER: {
+ count = netprof_get_packet_count_id(tcp_s_profile, id, dir);
+ break;
+ }
+
+ case TOX_NETPROF_PACKET_TYPE_TCP: {
+ const uint64_t tcp_c_count = netprof_get_packet_count_id(tcp_c_profile, id, dir);
+ const uint64_t tcp_s_count = netprof_get_packet_count_id(tcp_s_profile, id, dir);
+ count = tcp_c_count + tcp_s_count;
+ break;
+ }
+
+ case TOX_NETPROF_PACKET_TYPE_UDP: {
+ const Net_Profile *udp_profile = net_get_net_profile(tox->m->net);
+ count = netprof_get_packet_count_id(udp_profile, id, dir);
+ break;
+ }
+
+ default: {
+ LOGGER_ERROR(tox->m->log, "invalid packet type: %d", type);
+ break;
+ }
+ }
+
+ tox_unlock(tox);
+
+ return count;
+}
+
+uint64_t tox_netprof_get_packet_total_count(const Tox *tox, Tox_Netprof_Packet_Type type,
+ Tox_Netprof_Direction direction)
+{
+ assert(tox != nullptr);
+
+ tox_lock(tox);
+
+ const Net_Profile *tcp_c_profile = tox->m->tcp_np;
+ const Net_Profile *tcp_s_profile = tcp_server_get_net_profile(tox->m->tcp_server);
+
+ const Packet_Direction dir = (Packet_Direction) direction;
+
+ uint64_t count = 0;
+
+ switch (type) {
+ case TOX_NETPROF_PACKET_TYPE_TCP_CLIENT: {
+ count = netprof_get_packet_count_total(tcp_c_profile, dir);
+ break;
+ }
+
+ case TOX_NETPROF_PACKET_TYPE_TCP_SERVER: {
+ count = netprof_get_packet_count_total(tcp_s_profile, dir);
+ break;
+ }
+
+ case TOX_NETPROF_PACKET_TYPE_TCP: {
+ const uint64_t tcp_c_count = netprof_get_packet_count_total(tcp_c_profile, dir);
+ const uint64_t tcp_s_count = netprof_get_packet_count_total(tcp_s_profile, dir);
+ count = tcp_c_count + tcp_s_count;
+ break;
+ }
+
+ case TOX_NETPROF_PACKET_TYPE_UDP: {
+ const Net_Profile *udp_profile = net_get_net_profile(tox->m->net);
+ count = netprof_get_packet_count_total(udp_profile, dir);
+ break;
+ }
+
+ default: {
+ LOGGER_ERROR(tox->m->log, "invalid packet type: %d", type);
+ break;
+ }
+ }
+
+ tox_unlock(tox);
+
+ return count;
+}
+
+uint64_t tox_netprof_get_packet_id_bytes(const Tox *tox, Tox_Netprof_Packet_Type type, uint8_t id,
+ Tox_Netprof_Direction direction)
+{
+ assert(tox != nullptr);
+
+ tox_lock(tox);
+
+ const Net_Profile *tcp_c_profile = tox->m->tcp_np;
+ const Net_Profile *tcp_s_profile = tcp_server_get_net_profile(tox->m->tcp_server);
+
+ const Packet_Direction dir = (Packet_Direction) direction;
+
+ uint64_t bytes = 0;
+
+ switch (type) {
+ case TOX_NETPROF_PACKET_TYPE_TCP_CLIENT: {
+ bytes = netprof_get_bytes_id(tcp_c_profile, id, dir);
+ break;
+ }
+
+ case TOX_NETPROF_PACKET_TYPE_TCP_SERVER: {
+ bytes = netprof_get_bytes_id(tcp_s_profile, id, dir);
+ break;
+ }
+
+ case TOX_NETPROF_PACKET_TYPE_TCP: {
+ const uint64_t tcp_c_bytes = netprof_get_bytes_id(tcp_c_profile, id, dir);
+ const uint64_t tcp_s_bytes = netprof_get_bytes_id(tcp_s_profile, id, dir);
+ bytes = tcp_c_bytes + tcp_s_bytes;
+ break;
+ }
+
+ case TOX_NETPROF_PACKET_TYPE_UDP: {
+ const Net_Profile *udp_profile = net_get_net_profile(tox->m->net);
+ bytes = netprof_get_bytes_id(udp_profile, id, dir);
+ break;
+ }
+
+ default: {
+ LOGGER_ERROR(tox->m->log, "invalid packet type: %d", type);
+ break;
+ }
+ }
+
+ tox_unlock(tox);
+
+ return bytes;
+}
+
+uint64_t tox_netprof_get_packet_total_bytes(const Tox *tox, Tox_Netprof_Packet_Type type,
+ Tox_Netprof_Direction direction)
+{
+ assert(tox != nullptr);
+
+ tox_lock(tox);
+
+ const Net_Profile *tcp_c_profile = tox->m->tcp_np;
+ const Net_Profile *tcp_s_profile = tcp_server_get_net_profile(tox->m->tcp_server);
+
+ const Packet_Direction dir = (Packet_Direction) direction;
+
+ uint64_t bytes = 0;
+
+ switch (type) {
+ case TOX_NETPROF_PACKET_TYPE_TCP_CLIENT: {
+ bytes = netprof_get_bytes_total(tcp_c_profile, dir);
+ break;
+ }
+
+ case TOX_NETPROF_PACKET_TYPE_TCP_SERVER: {
+ bytes = netprof_get_bytes_total(tcp_s_profile, dir);
+ break;
+ }
+
+ case TOX_NETPROF_PACKET_TYPE_TCP: {
+ const uint64_t tcp_c_bytes = netprof_get_bytes_total(tcp_c_profile, dir);
+ const uint64_t tcp_s_bytes = netprof_get_bytes_total(tcp_s_profile, dir);
+ bytes = tcp_c_bytes + tcp_s_bytes;
+ break;
+ }
+
+ case TOX_NETPROF_PACKET_TYPE_UDP: {
+ const Net_Profile *udp_profile = net_get_net_profile(tox->m->net);
+ bytes = netprof_get_bytes_total(udp_profile, dir);
+ break;
+ }
+
+ default: {
+ LOGGER_ERROR(tox->m->log, "invalid packet type: %d", type);
+ break;
+ }
+ }
+
+ tox_unlock(tox);
+
+ return bytes;
+}
diff --git a/protocols/Tox/libtox/src/toxcore/tox_private.h b/protocols/Tox/libtox/src/toxcore/tox_private.h
index d36ab026c3..4cc3edd00c 100644
--- a/protocols/Tox/libtox/src/toxcore/tox_private.h
+++ b/protocols/Tox/libtox/src/toxcore/tox_private.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2020 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -11,6 +11,7 @@
#include <stdint.h>
#include "tox.h"
+#include "tox_options.h"
#ifdef __cplusplus
extern "C" {
@@ -18,38 +19,49 @@ extern "C" {
typedef uint64_t tox_mono_time_cb(void *user_data);
-struct Tox_System {
+typedef struct Tox_System {
tox_mono_time_cb *mono_time_callback;
void *mono_time_user_data;
const struct Random *rng;
const struct Network *ns;
const struct Memory *mem;
-};
+} Tox_System;
Tox_System tox_default_system(void);
+const Tox_System *tox_get_system(Tox *tox);
+
+typedef struct Tox_Options_Testing {
+ const struct Tox_System *operating_system;
+} Tox_Options_Testing;
+
+typedef enum Tox_Err_New_Testing {
+ TOX_ERR_NEW_TESTING_OK,
+ TOX_ERR_NEW_TESTING_NULL,
+} Tox_Err_New_Testing;
+
+Tox *tox_new_testing(const Tox_Options *options, Tox_Err_New *error, const Tox_Options_Testing *testing, Tox_Err_New_Testing *testing_error);
+
void tox_lock(const Tox *tox);
void tox_unlock(const Tox *tox);
-const Tox_System *tox_get_system(Tox *tox);
-
/**
- * Set the callback for the `friend_lossy_packet` event for a specific packet ID.
- * Pass NULL to unset.
+ * Set the callback for the `friend_lossy_packet` event for a specific packet
+ * ID. Pass NULL to unset.
*
* allowed packet ID range:
- * from `PACKET_ID_RANGE_LOSSY_START` to `PACKET_ID_RANGE_LOSSY_END` (both inclusive)
+ * from `PACKET_ID_RANGE_LOSSY_START` to `PACKET_ID_RANGE_LOSSY_END` (both
+ * inclusive)
*/
void tox_callback_friend_lossy_packet_per_pktid(Tox *tox, tox_friend_lossy_packet_cb *callback, uint8_t pktid);
/**
- * Set the callback for the `friend_lossless_packet` event for a specific packet ID.
- * Pass NULL to unset.
+ * Set the callback for the `friend_lossless_packet` event for a specific packet
+ * ID. Pass NULL to unset.
*
* allowed packet ID range:
- * from `PACKET_ID_RANGE_LOSSLESS_CUSTOM_START` to `PACKET_ID_RANGE_LOSSLESS_CUSTOM_END` (both inclusive)
- * and
- * `PACKET_ID_MSI`
+ * from `PACKET_ID_RANGE_LOSSLESS_CUSTOM_START` to
+ * `PACKET_ID_RANGE_LOSSLESS_CUSTOM_END` (both inclusive) and `PACKET_ID_MSI`
*/
void tox_callback_friend_lossless_packet_per_pktid(Tox *tox, tox_friend_lossless_packet_cb *callback, uint8_t pktid);
@@ -78,69 +90,73 @@ uint32_t tox_dht_node_public_key_size(void);
/**
* @param public_key The node's public key.
- * @param ip The node's IP address, represented as a null terminated string.
+ * @param ip The node's IP address, represented as a NUL-terminated C string.
* @param port The node's port.
*/
-typedef void tox_dht_get_nodes_response_cb(Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port,
- void *user_data);
+typedef void tox_dht_nodes_response_cb(
+ Tox *tox, const uint8_t *public_key, const char *ip, uint32_t ip_length,
+ uint16_t port, void *user_data);
/**
- * Set the callback for the `dht_get_nodes_response` event. Pass NULL to unset.
+ * Set the callback for the `dht_nodes_response` event. Pass NULL to unset.
*
- * This event is triggered when a getnodes response is received from a DHT peer.
+ * This event is triggered when a nodes response is received from a DHT peer.
*/
-void tox_callback_dht_get_nodes_response(Tox *tox, tox_dht_get_nodes_response_cb *callback);
+void tox_callback_dht_nodes_response(Tox *tox, tox_dht_nodes_response_cb *callback);
-typedef enum Tox_Err_Dht_Get_Nodes {
+typedef enum Tox_Err_Dht_Send_Nodes_Request {
/**
* The function returned successfully.
*/
- TOX_ERR_DHT_GET_NODES_OK,
+ TOX_ERR_DHT_SEND_NODES_REQUEST_OK,
/**
- * UDP is disabled in tox options; the DHT can only be queried when UDP is enabled.
+ * UDP is disabled in Tox options; the DHT can only be queried when UDP is
+ * enabled.
*/
- TOX_ERR_DHT_GET_NODES_UDP_DISABLED,
+ TOX_ERR_DHT_SEND_NODES_REQUEST_UDP_DISABLED,
/**
* One of the arguments to the function was NULL when it was not expected.
*/
- TOX_ERR_DHT_GET_NODES_NULL,
+ TOX_ERR_DHT_SEND_NODES_REQUEST_NULL,
/**
* The supplied port is invalid.
*/
- TOX_ERR_DHT_GET_NODES_BAD_PORT,
+ TOX_ERR_DHT_SEND_NODES_REQUEST_BAD_PORT,
/**
* The supplied IP address is invalid.
*/
- TOX_ERR_DHT_GET_NODES_BAD_IP,
+ TOX_ERR_DHT_SEND_NODES_REQUEST_BAD_IP,
/**
- * The getnodes request failed. This usually means the packet failed to send.
+ * The nodes request failed. This usually means the packet failed to
+ * send.
*/
- TOX_ERR_DHT_GET_NODES_FAIL,
-} Tox_Err_Dht_Get_Nodes;
+ TOX_ERR_DHT_SEND_NODES_REQUEST_FAIL,
+} Tox_Err_Dht_Send_Nodes_Request;
/**
- * This function sends a getnodes request to a DHT node for its peers that
- * are "close" to the passed target public key according to the distance metric used
- * by the DHT implementation.
+ * This function sends a nodes request to a DHT node for its peers that
+ * are "close" to the passed target public key according to the distance metric
+ * used by the DHT implementation.
*
- * @param public_key The public key of the node that we wish to query. This key must be
- * at least `TOX_DHT_NODE_PUBLIC_KEY_SIZE` bytes in length.
- * @param ip A NULL terminated string representing the IP address of the node we wish to query.
+ * @param public_key The public key of the node that we wish to query. This key
+ * must be at least `TOX_DHT_NODE_PUBLIC_KEY_SIZE` bytes in length.
+ * @param ip A NUL-terminated C string representing the IP address of the node
+ * we wish to query.
* @param port The port of the node we wish to query.
- * @param target_public_key The public key for which we want to find close nodes.
+ * @param target_public_key The public key for which we want to find close
+ * nodes.
*
* @return true on success.
*/
-bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port,
- const uint8_t *target_public_key, Tox_Err_Dht_Get_Nodes *error);
+bool tox_dht_send_nodes_request(const Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port,
+ const uint8_t *target_public_key, Tox_Err_Dht_Send_Nodes_Request *error);
/**
- * This function returns the ratio of close dht nodes that are known to support announce/store.
* This function returns the number of DHT nodes in the closelist.
*
* @return number
@@ -148,8 +164,8 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip
uint16_t tox_dht_get_num_closelist(const Tox *tox);
/**
- * This function returns the number of DHT nodes in the closelist,
- * that are capable to store annouce data (introduced in version 0.2.18).
+ * This function returns the number of DHT nodes in the closelist
+ * that are capable of storing announce data (introduced in version 0.2.18).
*
* @return number
*/
@@ -157,6 +173,267 @@ uint16_t tox_dht_get_num_closelist_announce_capable(const Tox *tox);
/*******************************************************************************
*
+ * :: Network profiler
+ *
+ ******************************************************************************/
+
+
+/**
+ * Represents all of the network packet identifiers that Toxcore uses.
+ *
+ * Notes:
+ * - Some packet ID's have different purposes depending on the
+ * packet type. These ID's are given numeral names.
+ *
+ * - Queries for invalid packet ID's return undefined results. For example,
+ * querying a TCP-exclusive packet ID for UDP, or querying an ID that
+ * doesn't exist in this enum.
+ */
+typedef enum Tox_Netprof_Packet_Id {
+ /**
+ * Ping request packet (UDP).
+ * Routing request (TCP).
+ */
+ TOX_NETPROF_PACKET_ID_ZERO = 0x00,
+
+ /**
+ * Ping response packet (UDP).
+ * Routing response (TCP).
+ */
+ TOX_NETPROF_PACKET_ID_ONE = 0x01,
+
+ /**
+ * Nodes request packet (UDP).
+ * Connection notification (TCP).
+ */
+ TOX_NETPROF_PACKET_ID_TWO = 0x02,
+
+ /**
+ * TCP disconnect notification.
+ */
+ TOX_NETPROF_PACKET_ID_TCP_DISCONNECT = 0x03,
+
+ /**
+ * Nodes response packet (UDP).
+ * Ping packet (TCP).
+ */
+ TOX_NETPROF_PACKET_ID_FOUR = 0x04,
+
+ /**
+ * TCP pong packet.
+ */
+ TOX_NETPROF_PACKET_ID_TCP_PONG = 0x05,
+
+ /**
+ * TCP out-of-band send packet.
+ */
+ TOX_NETPROF_PACKET_ID_TCP_OOB_SEND = 0x06,
+
+ /**
+ * TCP out-of-band receive packet.
+ */
+ TOX_NETPROF_PACKET_ID_TCP_OOB_RECV = 0x07,
+
+ /**
+ * TCP onion request packet.
+ */
+ TOX_NETPROF_PACKET_ID_TCP_ONION_REQUEST = 0x08,
+
+ /**
+ * TCP onion response packet.
+ */
+ TOX_NETPROF_PACKET_ID_TCP_ONION_RESPONSE = 0x09,
+
+ /**
+ * TCP data packet.
+ */
+ TOX_NETPROF_PACKET_ID_TCP_DATA = 0x10,
+
+ /**
+ * Cookie request packet.
+ */
+ TOX_NETPROF_PACKET_ID_COOKIE_REQUEST = 0x18,
+
+ /**
+ * Cookie response packet.
+ */
+ TOX_NETPROF_PACKET_ID_COOKIE_RESPONSE = 0x19,
+
+ /**
+ * Crypto handshake packet.
+ */
+ TOX_NETPROF_PACKET_ID_CRYPTO_HS = 0x1a,
+
+ /**
+ * Crypto data packet.
+ */
+ TOX_NETPROF_PACKET_ID_CRYPTO_DATA = 0x1b,
+
+ /**
+ * Encrypted data packet.
+ */
+ TOX_NETPROF_PACKET_ID_CRYPTO = 0x20,
+
+ /**
+ * LAN discovery packet.
+ */
+ TOX_NETPROF_PACKET_ID_LAN_DISCOVERY = 0x21,
+
+ /**
+ * DHT groupchat packets.
+ */
+ TOX_NETPROF_PACKET_ID_GC_HANDSHAKE = 0x5a,
+ TOX_NETPROF_PACKET_ID_GC_LOSSLESS = 0x5b,
+ TOX_NETPROF_PACKET_ID_GC_LOSSY = 0x5c,
+
+ /**
+ * Onion send packets.
+ */
+ TOX_NETPROF_PACKET_ID_ONION_SEND_INITIAL = 0x80,
+ TOX_NETPROF_PACKET_ID_ONION_SEND_1 = 0x81,
+ TOX_NETPROF_PACKET_ID_ONION_SEND_2 = 0x82,
+
+ /**
+ * DHT announce request packet (deprecated).
+ */
+ TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST_OLD = 0x83,
+
+ /**
+ * DHT announce response packet (deprecated).
+ */
+ TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE_OLD = 0x84,
+
+ /**
+ * Onion data request packet.
+ */
+ TOX_NETPROF_PACKET_ID_ONION_DATA_REQUEST = 0x85,
+
+ /**
+ * Onion data response packet.
+ */
+ TOX_NETPROF_PACKET_ID_ONION_DATA_RESPONSE = 0x86,
+
+ /**
+ * DHT announce request packet.
+ */
+ TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST = 0x87,
+
+ /**
+ * DHT announce response packet.
+ */
+ TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE = 0x88,
+
+ /**
+ * Onion receive packets.
+ */
+ TOX_NETPROF_PACKET_ID_ONION_RECV_3 = 0x8c,
+ TOX_NETPROF_PACKET_ID_ONION_RECV_2 = 0x8d,
+ TOX_NETPROF_PACKET_ID_ONION_RECV_1 = 0x8e,
+
+ TOX_NETPROF_PACKET_ID_FORWARD_REQUEST = 0x90,
+ TOX_NETPROF_PACKET_ID_FORWARDING = 0x91,
+ TOX_NETPROF_PACKET_ID_FORWARD_REPLY = 0x92,
+
+ TOX_NETPROF_PACKET_ID_DATA_SEARCH_REQUEST = 0x93,
+ TOX_NETPROF_PACKET_ID_DATA_SEARCH_RESPONSE = 0x94,
+ TOX_NETPROF_PACKET_ID_DATA_RETRIEVE_REQUEST = 0x95,
+ TOX_NETPROF_PACKET_ID_DATA_RETRIEVE_RESPONSE = 0x96,
+ TOX_NETPROF_PACKET_ID_STORE_ANNOUNCE_REQUEST = 0x97,
+ TOX_NETPROF_PACKET_ID_STORE_ANNOUNCE_RESPONSE = 0x98,
+
+ /**
+ * Bootstrap info packet.
+ */
+ TOX_NETPROF_PACKET_ID_BOOTSTRAP_INFO = 0xf0,
+} Tox_Netprof_Packet_Id;
+
+const char *tox_netprof_packet_id_to_string(Tox_Netprof_Packet_Id value);
+
+/**
+ * Specifies the packet type for a given query.
+ */
+typedef enum Tox_Netprof_Packet_Type {
+ /**
+ * TCP client packets.
+ */
+ TOX_NETPROF_PACKET_TYPE_TCP_CLIENT,
+
+ /**
+ * TCP server packets.
+ */
+ TOX_NETPROF_PACKET_TYPE_TCP_SERVER,
+
+ /**
+ * Combined TCP server and TCP client packets.
+ */
+ TOX_NETPROF_PACKET_TYPE_TCP,
+
+ /**
+ * UDP packets.
+ */
+ TOX_NETPROF_PACKET_TYPE_UDP,
+} Tox_Netprof_Packet_Type;
+
+const char *tox_netprof_packet_type_to_string(Tox_Netprof_Packet_Type value);
+
+/**
+ * Specifies the packet direction for a given query.
+ */
+typedef enum Tox_Netprof_Direction {
+ /**
+ * Outbound packets.
+ */
+ TOX_NETPROF_DIRECTION_SENT,
+
+ /**
+ * Inbound packets.
+ */
+ TOX_NETPROF_DIRECTION_RECV,
+} Tox_Netprof_Direction;
+
+const char *tox_netprof_direction_to_string(Tox_Netprof_Direction value);
+
+/**
+ * Return the number of packets sent or received for a specific packet ID.
+ *
+ * @param type The types of packets being queried.
+ * @param id The packet ID being queried.
+ * @param direction The packet direction.
+ */
+uint64_t tox_netprof_get_packet_id_count(const Tox *tox, Tox_Netprof_Packet_Type type, uint8_t id,
+ Tox_Netprof_Direction direction);
+
+/**
+ * Return the total number of packets sent or received.
+ *
+ * @param type The types of packets being queried.
+ * @param direction The packet direction.
+ */
+uint64_t tox_netprof_get_packet_total_count(const Tox *tox, Tox_Netprof_Packet_Type type,
+ Tox_Netprof_Direction direction);
+
+/**
+ * Return the number of bytes sent or received for a specific packet ID.
+ *
+ * @param type The types of packets being queried.
+ * @param id The packet ID being queried.
+ * @param direction The packet direction.
+ */
+uint64_t tox_netprof_get_packet_id_bytes(const Tox *tox, Tox_Netprof_Packet_Type type, uint8_t id,
+ Tox_Netprof_Direction direction);
+
+/**
+ * Return the total number of bytes sent or received.
+ *
+ * @param type The types of packets being queried.
+ * @param direction The packet direction.
+ */
+uint64_t tox_netprof_get_packet_total_bytes(const Tox *tox, Tox_Netprof_Packet_Type type,
+ Tox_Netprof_Direction direction);
+
+
+/*******************************************************************************
+ *
* :: DHT groupchat queries.
*
******************************************************************************/
@@ -169,30 +446,32 @@ uint16_t tox_dht_get_num_closelist_announce_capable(const Tox *tox);
uint32_t tox_group_peer_ip_string_max_length(void);
/**
- * Return the length of the peer's IP address in string form. If the group number or ID
- * is invalid, the return value is unspecified.
+ * Return the length of the peer's IP address in string form. If the group
+ * number or ID is invalid, the return value is unspecified.
*
* @param group_number The group number of the group we wish to query.
- * @param peer_id The ID of the peer whose IP address length we want to retrieve.
+ * @param peer_id The ID of the peer whose IP address length we want to
+ * retrieve.
*/
size_t tox_group_peer_get_ip_address_size(const Tox *tox, uint32_t group_number, uint32_t peer_id,
Tox_Err_Group_Peer_Query *error);
/**
- * Write the IP address associated with the designated peer_id for the designated group number
- * to ip_addr.
+ * Write the IP address associated with the designated peer_id for the
+ * designated group number to ip_addr.
*
- * If the peer is forcing TCP connections a placeholder value will be written instead,
- * indicating that their real IP address is unknown to us.
+ * If the peer is forcing TCP connections a placeholder value will be written
+ * instead, indicating that their real IP address is unknown to us.
*
- * If `peer_id` designates ourself, it will write either our own IP address or a placeholder value,
- * depending on whether or not we're forcing TCP connections.
+ * If `peer_id` designates ourself, it will write either our own IP address or a
+ * placeholder value, depending on whether or not we're forcing TCP connections.
*
- * Call tox_group_peer_get_ip_address_size to determine the allocation size for the `ip_addr` parameter.
+ * Call tox_group_peer_get_ip_address_size to determine the allocation size for
+ * the `ip_addr` parameter.
*
* @param group_number The group number of the group we wish to query.
* @param peer_id The ID of the peer whose public key we wish to retrieve.
- * @param ip_addr A valid memory region large enough to store the IP address string.
- * If this parameter is NULL, this function call has no effect.
+ * @param ip_addr A valid memory region large enough to store the IP address
+ * string. If this parameter is NULL, this function call has no effect.
*
* @return true on success.
*/
diff --git a/protocols/Tox/libtox/src/toxcore/tox_struct.h b/protocols/Tox/libtox/src/toxcore/tox_struct.h
index bd42fcce8d..9383c2a509 100644
--- a/protocols/Tox/libtox/src/toxcore/tox_struct.h
+++ b/protocols/Tox/libtox/src/toxcore/tox_struct.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2022 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -8,10 +8,9 @@
#include <pthread.h>
-#include "Messenger.h"
-#include "mem.h"
#include "mono_time.h"
#include "tox.h"
+#include "tox_options.h" // tox_log_cb
#include "tox_private.h"
#ifdef __cplusplus
@@ -19,7 +18,7 @@ extern "C" {
#endif
struct Tox {
- Messenger *m;
+ struct Messenger *m;
Mono_Time *mono_time;
Tox_System sys;
pthread_mutex_t *mutex;
@@ -44,7 +43,7 @@ struct Tox {
tox_conference_title_cb *conference_title_callback;
tox_conference_peer_name_cb *conference_peer_name_callback;
tox_conference_peer_list_changed_cb *conference_peer_list_changed_callback;
- tox_dht_get_nodes_response_cb *dht_get_nodes_response_callback;
+ tox_dht_nodes_response_cb *dht_nodes_response_callback;
tox_friend_lossy_packet_cb *friend_lossy_packet_callback_per_pktid[UINT8_MAX + 1];
tox_friend_lossless_packet_cb *friend_lossless_packet_callback_per_pktid[UINT8_MAX + 1];
tox_group_peer_name_cb *group_peer_name_callback;
diff --git a/protocols/Tox/libtox/src/toxcore/tox_unpack.c b/protocols/Tox/libtox/src/toxcore/tox_unpack.c
index b5e05da872..6b31029624 100644
--- a/protocols/Tox/libtox/src/toxcore/tox_unpack.c
+++ b/protocols/Tox/libtox/src/toxcore/tox_unpack.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#include "tox_unpack.h"
@@ -11,21 +11,21 @@
#include "tox.h"
non_null()
-static bool tox_conference_type_from_int(uint32_t value, Tox_Conference_Type *out)
+static bool tox_conference_type_from_int(uint32_t value, Tox_Conference_Type *out_enum)
{
switch (value) {
case TOX_CONFERENCE_TYPE_TEXT: {
- *out = TOX_CONFERENCE_TYPE_TEXT;
+ *out_enum = TOX_CONFERENCE_TYPE_TEXT;
return true;
}
case TOX_CONFERENCE_TYPE_AV: {
- *out = TOX_CONFERENCE_TYPE_AV;
+ *out_enum = TOX_CONFERENCE_TYPE_AV;
return true;
}
default: {
- *out = TOX_CONFERENCE_TYPE_TEXT;
+ *out_enum = TOX_CONFERENCE_TYPE_TEXT;
return false;
}
}
@@ -38,26 +38,26 @@ bool tox_conference_type_unpack(Tox_Conference_Type *val, Bin_Unpack *bu)
}
non_null()
-static bool tox_connection_from_int(uint32_t value, Tox_Connection *out)
+static bool tox_connection_from_int(uint32_t value, Tox_Connection *out_enum)
{
switch (value) {
case TOX_CONNECTION_NONE: {
- *out = TOX_CONNECTION_NONE;
+ *out_enum = TOX_CONNECTION_NONE;
return true;
}
case TOX_CONNECTION_TCP: {
- *out = TOX_CONNECTION_TCP;
+ *out_enum = TOX_CONNECTION_TCP;
return true;
}
case TOX_CONNECTION_UDP: {
- *out = TOX_CONNECTION_UDP;
+ *out_enum = TOX_CONNECTION_UDP;
return true;
}
default: {
- *out = TOX_CONNECTION_NONE;
+ *out_enum = TOX_CONNECTION_NONE;
return false;
}
}
@@ -71,26 +71,26 @@ bool tox_connection_unpack(Tox_Connection *val, Bin_Unpack *bu)
}
non_null()
-static bool tox_file_control_from_int(uint32_t value, Tox_File_Control *out)
+static bool tox_file_control_from_int(uint32_t value, Tox_File_Control *out_enum)
{
switch (value) {
case TOX_FILE_CONTROL_RESUME: {
- *out = TOX_FILE_CONTROL_RESUME;
+ *out_enum = TOX_FILE_CONTROL_RESUME;
return true;
}
case TOX_FILE_CONTROL_PAUSE: {
- *out = TOX_FILE_CONTROL_PAUSE;
+ *out_enum = TOX_FILE_CONTROL_PAUSE;
return true;
}
case TOX_FILE_CONTROL_CANCEL: {
- *out = TOX_FILE_CONTROL_CANCEL;
+ *out_enum = TOX_FILE_CONTROL_CANCEL;
return true;
}
default: {
- *out = TOX_FILE_CONTROL_RESUME;
+ *out_enum = TOX_FILE_CONTROL_RESUME;
return false;
}
}
@@ -104,21 +104,21 @@ bool tox_file_control_unpack(Tox_File_Control *val, Bin_Unpack *bu)
}
non_null()
-static bool tox_message_type_from_int(uint32_t value, Tox_Message_Type *out)
+static bool tox_message_type_from_int(uint32_t value, Tox_Message_Type *out_enum)
{
switch (value) {
case TOX_MESSAGE_TYPE_NORMAL: {
- *out = TOX_MESSAGE_TYPE_NORMAL;
+ *out_enum = TOX_MESSAGE_TYPE_NORMAL;
return true;
}
case TOX_MESSAGE_TYPE_ACTION: {
- *out = TOX_MESSAGE_TYPE_ACTION;
+ *out_enum = TOX_MESSAGE_TYPE_ACTION;
return true;
}
default: {
- *out = TOX_MESSAGE_TYPE_NORMAL;
+ *out_enum = TOX_MESSAGE_TYPE_NORMAL;
return false;
}
}
@@ -132,26 +132,26 @@ bool tox_message_type_unpack(Tox_Message_Type *val, Bin_Unpack *bu)
}
non_null()
-static bool tox_user_status_from_int(uint32_t value, Tox_User_Status *out)
+static bool tox_user_status_from_int(uint32_t value, Tox_User_Status *out_enum)
{
switch (value) {
case TOX_USER_STATUS_NONE: {
- *out = TOX_USER_STATUS_NONE;
+ *out_enum = TOX_USER_STATUS_NONE;
return true;
}
case TOX_USER_STATUS_AWAY: {
- *out = TOX_USER_STATUS_AWAY;
+ *out_enum = TOX_USER_STATUS_AWAY;
return true;
}
case TOX_USER_STATUS_BUSY: {
- *out = TOX_USER_STATUS_BUSY;
+ *out_enum = TOX_USER_STATUS_BUSY;
return true;
}
default: {
- *out = TOX_USER_STATUS_NONE;
+ *out_enum = TOX_USER_STATUS_NONE;
return false;
}
}
@@ -165,19 +165,19 @@ bool tox_user_status_unpack(Tox_User_Status *val, Bin_Unpack *bu)
}
non_null()
-static bool tox_group_privacy_state_from_int(uint32_t value, Tox_Group_Privacy_State *out)
+static bool tox_group_privacy_state_from_int(uint32_t value, Tox_Group_Privacy_State *out_enum)
{
switch (value) {
case TOX_GROUP_PRIVACY_STATE_PUBLIC: {
- *out = TOX_GROUP_PRIVACY_STATE_PUBLIC;
+ *out_enum = TOX_GROUP_PRIVACY_STATE_PUBLIC;
return true;
}
case TOX_GROUP_PRIVACY_STATE_PRIVATE: {
- *out = TOX_GROUP_PRIVACY_STATE_PRIVATE;
+ *out_enum = TOX_GROUP_PRIVACY_STATE_PRIVATE;
return true;
}
default: {
- *out = TOX_GROUP_PRIVACY_STATE_PUBLIC;
+ *out_enum = TOX_GROUP_PRIVACY_STATE_PUBLIC;
return false;
}
}
@@ -189,23 +189,23 @@ bool tox_group_privacy_state_unpack(Tox_Group_Privacy_State *val, Bin_Unpack *bu
&& tox_group_privacy_state_from_int(u32, val);
}
non_null()
-static bool tox_group_voice_state_from_int(uint32_t value, Tox_Group_Voice_State *out)
+static bool tox_group_voice_state_from_int(uint32_t value, Tox_Group_Voice_State *out_enum)
{
switch (value) {
case TOX_GROUP_VOICE_STATE_ALL: {
- *out = TOX_GROUP_VOICE_STATE_ALL;
+ *out_enum = TOX_GROUP_VOICE_STATE_ALL;
return true;
}
case TOX_GROUP_VOICE_STATE_MODERATOR: {
- *out = TOX_GROUP_VOICE_STATE_MODERATOR;
+ *out_enum = TOX_GROUP_VOICE_STATE_MODERATOR;
return true;
}
case TOX_GROUP_VOICE_STATE_FOUNDER: {
- *out = TOX_GROUP_VOICE_STATE_FOUNDER;
+ *out_enum = TOX_GROUP_VOICE_STATE_FOUNDER;
return true;
}
default: {
- *out = TOX_GROUP_VOICE_STATE_ALL;
+ *out_enum = TOX_GROUP_VOICE_STATE_ALL;
return false;
}
}
@@ -218,19 +218,19 @@ bool tox_group_voice_state_unpack(Tox_Group_Voice_State *val, Bin_Unpack *bu)
}
non_null()
-static bool tox_group_topic_lock_from_int(uint32_t value, Tox_Group_Topic_Lock *out)
+static bool tox_group_topic_lock_from_int(uint32_t value, Tox_Group_Topic_Lock *out_enum)
{
switch (value) {
case TOX_GROUP_TOPIC_LOCK_ENABLED: {
- *out = TOX_GROUP_TOPIC_LOCK_ENABLED;
+ *out_enum = TOX_GROUP_TOPIC_LOCK_ENABLED;
return true;
}
case TOX_GROUP_TOPIC_LOCK_DISABLED: {
- *out = TOX_GROUP_TOPIC_LOCK_DISABLED;
+ *out_enum = TOX_GROUP_TOPIC_LOCK_DISABLED;
return true;
}
default: {
- *out = TOX_GROUP_TOPIC_LOCK_ENABLED;
+ *out_enum = TOX_GROUP_TOPIC_LOCK_ENABLED;
return false;
}
}
@@ -243,23 +243,23 @@ bool tox_group_topic_lock_unpack(Tox_Group_Topic_Lock *val, Bin_Unpack *bu)
}
non_null()
-static bool tox_group_join_fail_from_int(uint32_t value, Tox_Group_Join_Fail *out)
+static bool tox_group_join_fail_from_int(uint32_t value, Tox_Group_Join_Fail *out_enum)
{
switch (value) {
case TOX_GROUP_JOIN_FAIL_PEER_LIMIT: {
- *out = TOX_GROUP_JOIN_FAIL_PEER_LIMIT;
+ *out_enum = TOX_GROUP_JOIN_FAIL_PEER_LIMIT;
return true;
}
case TOX_GROUP_JOIN_FAIL_INVALID_PASSWORD: {
- *out = TOX_GROUP_JOIN_FAIL_INVALID_PASSWORD;
+ *out_enum = TOX_GROUP_JOIN_FAIL_INVALID_PASSWORD;
return true;
}
case TOX_GROUP_JOIN_FAIL_UNKNOWN: {
- *out = TOX_GROUP_JOIN_FAIL_UNKNOWN;
+ *out_enum = TOX_GROUP_JOIN_FAIL_UNKNOWN;
return true;
}
default: {
- *out = TOX_GROUP_JOIN_FAIL_PEER_LIMIT;
+ *out_enum = TOX_GROUP_JOIN_FAIL_PEER_LIMIT;
return false;
}
}
@@ -272,27 +272,27 @@ bool tox_group_join_fail_unpack(Tox_Group_Join_Fail *val, Bin_Unpack *bu)
}
non_null()
-static bool tox_group_mod_event_from_int(uint32_t value, Tox_Group_Mod_Event *out)
+static bool tox_group_mod_event_from_int(uint32_t value, Tox_Group_Mod_Event *out_enum)
{
switch (value) {
case TOX_GROUP_MOD_EVENT_KICK: {
- *out = TOX_GROUP_MOD_EVENT_KICK;
+ *out_enum = TOX_GROUP_MOD_EVENT_KICK;
return true;
}
case TOX_GROUP_MOD_EVENT_OBSERVER: {
- *out = TOX_GROUP_MOD_EVENT_OBSERVER;
+ *out_enum = TOX_GROUP_MOD_EVENT_OBSERVER;
return true;
}
case TOX_GROUP_MOD_EVENT_USER: {
- *out = TOX_GROUP_MOD_EVENT_USER;
+ *out_enum = TOX_GROUP_MOD_EVENT_USER;
return true;
}
case TOX_GROUP_MOD_EVENT_MODERATOR: {
- *out = TOX_GROUP_MOD_EVENT_MODERATOR;
+ *out_enum = TOX_GROUP_MOD_EVENT_MODERATOR;
return true;
}
default: {
- *out = TOX_GROUP_MOD_EVENT_KICK;
+ *out_enum = TOX_GROUP_MOD_EVENT_KICK;
return false;
}
}
@@ -305,35 +305,35 @@ bool tox_group_mod_event_unpack(Tox_Group_Mod_Event *val, Bin_Unpack *bu)
}
non_null()
-static bool tox_group_exit_type_from_int(uint32_t value, Tox_Group_Exit_Type *out)
+static bool tox_group_exit_type_from_int(uint32_t value, Tox_Group_Exit_Type *out_enum)
{
switch (value) {
case TOX_GROUP_EXIT_TYPE_QUIT: {
- *out = TOX_GROUP_EXIT_TYPE_QUIT;
+ *out_enum = TOX_GROUP_EXIT_TYPE_QUIT;
return true;
}
case TOX_GROUP_EXIT_TYPE_TIMEOUT: {
- *out = TOX_GROUP_EXIT_TYPE_TIMEOUT;
+ *out_enum = TOX_GROUP_EXIT_TYPE_TIMEOUT;
return true;
}
case TOX_GROUP_EXIT_TYPE_DISCONNECTED: {
- *out = TOX_GROUP_EXIT_TYPE_DISCONNECTED;
+ *out_enum = TOX_GROUP_EXIT_TYPE_DISCONNECTED;
return true;
}
case TOX_GROUP_EXIT_TYPE_SELF_DISCONNECTED: {
- *out = TOX_GROUP_EXIT_TYPE_SELF_DISCONNECTED;
+ *out_enum = TOX_GROUP_EXIT_TYPE_SELF_DISCONNECTED;
return true;
}
case TOX_GROUP_EXIT_TYPE_KICK: {
- *out = TOX_GROUP_EXIT_TYPE_KICK;
+ *out_enum = TOX_GROUP_EXIT_TYPE_KICK;
return true;
}
case TOX_GROUP_EXIT_TYPE_SYNC_ERROR: {
- *out = TOX_GROUP_EXIT_TYPE_SYNC_ERROR;
+ *out_enum = TOX_GROUP_EXIT_TYPE_SYNC_ERROR;
return true;
}
default: {
- *out = TOX_GROUP_EXIT_TYPE_QUIT;
+ *out_enum = TOX_GROUP_EXIT_TYPE_QUIT;
return false;
}
}
diff --git a/protocols/Tox/libtox/src/toxcore/tox_unpack.h b/protocols/Tox/libtox/src/toxcore/tox_unpack.h
index 828d2947a6..09092379da 100644
--- a/protocols/Tox/libtox/src/toxcore/tox_unpack.h
+++ b/protocols/Tox/libtox/src/toxcore/tox_unpack.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2022 The TokTok team.
+ * Copyright © 2022-2025 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_TOX_UNPACK_H
diff --git a/protocols/Tox/libtox/src/toxcore/util.c b/protocols/Tox/libtox/src/toxcore/util.c
index 1851e58a08..455e513cef 100644
--- a/protocols/Tox/libtox/src/toxcore/util.c
+++ b/protocols/Tox/libtox/src/toxcore/util.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
* Copyright © 2013 plutooo
*/
@@ -13,7 +13,6 @@
#include "util.h"
-#include <stdlib.h>
#include <string.h>
#include "ccompat.h"
@@ -81,13 +80,13 @@ bool memeq(const uint8_t *a, size_t a_size, const uint8_t *b, size_t b_size)
return a_size == b_size && memcmp(a, b, a_size) == 0;
}
-uint8_t *memdup(const uint8_t *data, size_t data_size)
+uint8_t *memdup(const Memory *mem, const uint8_t *data, size_t data_size)
{
if (data == nullptr || data_size == 0) {
return nullptr;
}
- uint8_t *copy = (uint8_t *)malloc(data_size);
+ uint8_t *copy = (uint8_t *)mem_balloc(mem, data_size);
if (copy != nullptr) {
memcpy(copy, data, data_size);
diff --git a/protocols/Tox/libtox/src/toxcore/util.h b/protocols/Tox/libtox/src/toxcore/util.h
index 5be74a8d86..9be721318b 100644
--- a/protocols/Tox/libtox/src/toxcore/util.h
+++ b/protocols/Tox/libtox/src/toxcore/util.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
* Copyright © 2013 plutooo
*/
@@ -46,7 +46,7 @@ non_null() bool memeq(const uint8_t *a, size_t a_size, const uint8_t *b, size_t
*
* @return nullptr on allocation failure or if the input data was nullptr or data_size was 0.
*/
-nullable(1) uint8_t *memdup(const uint8_t *data, size_t data_size);
+non_null(1) nullable(2) uint8_t *memdup(const Memory *mem, const uint8_t *data, size_t data_size);
/**
* @brief Set all bytes in `data` to 0.
@@ -79,7 +79,12 @@ uint16_t min_u16(uint16_t a, uint16_t b);
uint32_t min_u32(uint32_t a, uint32_t b);
uint64_t min_u64(uint64_t a, uint64_t b);
-// Comparison function: return -1 if a<b, 0 if a==b, 1 if a>b.
+/**
+ * Comparison function:
+ * @retval -1 if `a < b`
+ * @retval 0 if `a == b`
+ * @retval 1 if `a > b`
+ */
int cmp_uint(uint64_t a, uint64_t b);
/** @brief Returns a 32-bit hash of key of size len */
diff --git a/protocols/Tox/libtox/src/toxencryptsave/defines.h b/protocols/Tox/libtox/src/toxencryptsave/defines.h
index ac80cc7893..ca66f4d38d 100644
--- a/protocols/Tox/libtox/src/toxencryptsave/defines.h
+++ b/protocols/Tox/libtox/src/toxencryptsave/defines.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2021 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
diff --git a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c
index c43e357528..63bda86058 100644
--- a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c
+++ b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -67,7 +67,8 @@ void tox_pass_key_free(Tox_Pass_Key *key)
* produce the same key as was previously used. Any data encrypted with this
* module can be used as input.
*
- * The cipher text must be at least TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes in length.
+ * The cipher text must be at least TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes in
+ * length.
* The salt must be TOX_PASS_SALT_LENGTH bytes in length.
* If the passed byte arrays are smaller than required, the behaviour is
* undefined.
@@ -182,10 +183,11 @@ Tox_Pass_Key *tox_pass_key_derive_with_salt(
}
/**
- * Encrypt a plain text with a key produced by tox_pass_key_derive or tox_pass_key_derive_with_salt.
+ * Encrypt a plain text with a key produced by tox_pass_key_derive or
+ * tox_pass_key_derive_with_salt.
*
- * The output array must be at least `plaintext_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH`
- * bytes long.
+ * The output array must be at least
+ * `plaintext_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH` bytes long.
*
* @param plaintext A byte array of length `plaintext_len`.
* @param plaintext_len The length of the plain text array. Bigger than 0.
@@ -229,8 +231,8 @@ bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t plaintext[], si
ciphertext += crypto_box_NONCEBYTES;
/* now encrypt */
- if (encrypt_data_symmetric(key->key, nonce, plaintext, plaintext_len, ciphertext)
- != plaintext_len + crypto_box_MACBYTES) {
+ const int32_t encrypted_len = encrypt_data_symmetric(os_memory(), key->key, nonce, plaintext, plaintext_len, ciphertext);
+ if (encrypted_len < 0 || (size_t)encrypted_len != plaintext_len + crypto_box_MACBYTES) {
SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED);
return false;
}
@@ -242,9 +244,9 @@ bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t plaintext[], si
/**
* Encrypts the given data with the given passphrase.
*
- * The output array must be at least `plaintext_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH`
- * bytes long. This delegates to tox_pass_key_derive and
- * tox_pass_key_encrypt.
+ * The output array must be at least
+ * `plaintext_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH` bytes long. This delegates
+ * to tox_pass_key_derive and tox_pass_key_encrypt.
*
* @param plaintext A byte array of length `plaintext_len`.
* @param plaintext_len The length of the plain text array. Bigger than 0.
@@ -280,7 +282,8 @@ bool tox_pass_encrypt(const uint8_t plaintext[], size_t plaintext_len, const uin
* tox_pass_key_derive or tox_pass_key_derive_with_salt.
*
* @param ciphertext A byte array of length `ciphertext_len`.
- * @param ciphertext_len The length of the cipher text array. At least TOX_PASS_ENCRYPTION_EXTRA_LENGTH.
+ * @param ciphertext_len The length of the cipher text array. At least
+ * TOX_PASS_ENCRYPTION_EXTRA_LENGTH.
* @param plaintext The plain text array to write the decrypted data to.
*
* @return true on success.
@@ -313,8 +316,8 @@ bool tox_pass_key_decrypt(const Tox_Pass_Key *key, const uint8_t ciphertext[], s
ciphertext += crypto_box_NONCEBYTES;
/* decrypt the ciphertext */
- if (decrypt_data_symmetric(key->key, nonce, ciphertext, decrypt_length + crypto_box_MACBYTES, plaintext)
- != decrypt_length) {
+ const int32_t decrypted_len = decrypt_data_symmetric(os_memory(), key->key, nonce, ciphertext, decrypt_length + crypto_box_MACBYTES, plaintext);
+ if (decrypted_len < 0 || (size_t)decrypted_len != decrypt_length) {
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_FAILED);
return false;
}
@@ -326,11 +329,13 @@ bool tox_pass_key_decrypt(const Tox_Pass_Key *key, const uint8_t ciphertext[], s
/**
* Decrypts the given data with the given passphrase.
*
- * The output array must be at least `ciphertext_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH`
- * bytes long. This delegates to tox_pass_key_decrypt.
+ * The output array must be at least
+ * `ciphertext_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH` bytes long. This
+ * delegates to tox_pass_key_decrypt.
*
* @param ciphertext A byte array of length `ciphertext_len`.
- * @param ciphertext_len The length of the cipher text array. At least TOX_PASS_ENCRYPTION_EXTRA_LENGTH.
+ * @param ciphertext_len The length of the cipher text array. At least
+ * TOX_PASS_ENCRYPTION_EXTRA_LENGTH.
* @param passphrase The user-provided password. Can be empty.
* @param passphrase_len The length of the password.
* @param plaintext The plain text array to write the decrypted data to.
@@ -390,3 +395,63 @@ bool tox_is_data_encrypted(const uint8_t data[TOX_PASS_ENCRYPTION_EXTRA_LENGTH])
{
return memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0;
}
+
+const char *tox_err_key_derivation_to_string(Tox_Err_Key_Derivation error)
+{
+ switch (error) {
+ case TOX_ERR_KEY_DERIVATION_OK:
+ return "TOX_ERR_KEY_DERIVATION_OK";
+ case TOX_ERR_KEY_DERIVATION_NULL:
+ return "TOX_ERR_KEY_DERIVATION_NULL";
+ case TOX_ERR_KEY_DERIVATION_FAILED:
+ return "TOX_ERR_KEY_DERIVATION_FAILED";
+ }
+ return "<invalid Tox_Err_Key_Derivation>";
+}
+
+const char *tox_err_encryption_to_string(Tox_Err_Encryption error)
+{
+ switch (error) {
+ case TOX_ERR_ENCRYPTION_OK:
+ return "TOX_ERR_ENCRYPTION_OK";
+ case TOX_ERR_ENCRYPTION_NULL:
+ return "TOX_ERR_ENCRYPTION_NULL";
+ case TOX_ERR_ENCRYPTION_KEY_DERIVATION_FAILED:
+ return "TOX_ERR_ENCRYPTION_KEY_DERIVATION_FAILED";
+ case TOX_ERR_ENCRYPTION_FAILED:
+ return "TOX_ERR_ENCRYPTION_FAILED";
+ }
+ return "<invalid Tox_Err_Encryption>";
+}
+
+const char *tox_err_decryption_to_string(Tox_Err_Decryption error)
+{
+ switch (error) {
+ case TOX_ERR_DECRYPTION_OK:
+ return "TOX_ERR_DECRYPTION_OK";
+ case TOX_ERR_DECRYPTION_NULL:
+ return "TOX_ERR_DECRYPTION_NULL";
+ case TOX_ERR_DECRYPTION_INVALID_LENGTH:
+ return "TOX_ERR_DECRYPTION_INVALID_LENGTH";
+ case TOX_ERR_DECRYPTION_BAD_FORMAT:
+ return "TOX_ERR_DECRYPTION_BAD_FORMAT";
+ case TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED:
+ return "TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED";
+ case TOX_ERR_DECRYPTION_FAILED:
+ return "TOX_ERR_DECRYPTION_FAILED";
+ }
+ return "<invalid Tox_Err_Decryption>";
+}
+
+const char *tox_err_get_salt_to_string(Tox_Err_Get_Salt error)
+{
+ switch (error) {
+ case TOX_ERR_GET_SALT_OK:
+ return "TOX_ERR_GET_SALT_OK";
+ case TOX_ERR_GET_SALT_NULL:
+ return "TOX_ERR_GET_SALT_NULL";
+ case TOX_ERR_GET_SALT_BAD_FORMAT:
+ return "TOX_ERR_GET_SALT_BAD_FORMAT";
+ }
+ return "<invalid Tox_Err_Get_Salt>";
+}
diff --git a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h
index b9691551c7..f70ff8b4d1 100644
--- a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h
+++ b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2016-2025 The TokTok team.
* Copyright © 2013-2016 Tox Developers.
*/
@@ -88,6 +88,8 @@ typedef enum Tox_Err_Key_Derivation {
} Tox_Err_Key_Derivation;
+const char *tox_err_key_derivation_to_string(Tox_Err_Key_Derivation error);
+
typedef enum Tox_Err_Encryption {
/**
@@ -114,6 +116,8 @@ typedef enum Tox_Err_Encryption {
} Tox_Err_Encryption;
+const char *tox_err_encryption_to_string(Tox_Err_Encryption error);
+
typedef enum Tox_Err_Decryption {
/**
@@ -152,6 +156,8 @@ typedef enum Tox_Err_Decryption {
} Tox_Err_Decryption;
+const char *tox_err_decryption_to_string(Tox_Err_Decryption error);
+
/*******************************************************************************
*
* BEGIN PART 1
@@ -165,9 +171,9 @@ typedef enum Tox_Err_Decryption {
/**
* Encrypts the given data with the given passphrase.
*
- * The output array must be at least `plaintext_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH`
- * bytes long. This delegates to tox_pass_key_derive and
- * tox_pass_key_encrypt.
+ * The output array must be at least
+ * `plaintext_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH` bytes long. This delegates
+ * to tox_pass_key_derive and tox_pass_key_encrypt.
*
* @param plaintext A byte array of length `plaintext_len`.
* @param plaintext_len The length of the plain text array. Bigger than 0.
@@ -183,11 +189,13 @@ bool tox_pass_encrypt(const uint8_t plaintext[], size_t plaintext_len, const uin
/**
* Decrypts the given data with the given passphrase.
*
- * The output array must be at least `ciphertext_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH`
- * bytes long. This delegates to tox_pass_key_decrypt.
+ * The output array must be at least
+ * `ciphertext_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH` bytes long. This
+ * delegates to tox_pass_key_decrypt.
*
* @param ciphertext A byte array of length `ciphertext_len`.
- * @param ciphertext_len The length of the cipher text array. At least TOX_PASS_ENCRYPTION_EXTRA_LENGTH.
+ * @param ciphertext_len The length of the cipher text array. At least
+ * TOX_PASS_ENCRYPTION_EXTRA_LENGTH.
* @param passphrase The user-provided password. Can be empty.
* @param passphrase_len The length of the password.
* @param plaintext The plain text array to write the decrypted data to.
@@ -215,7 +223,8 @@ bool tox_pass_decrypt(const uint8_t ciphertext[], size_t ciphertext_len, const u
* user-provided password.
*
* The Tox_Pass_Key structure is hidden in the implementation. It can be created
- * using tox_pass_key_derive or tox_pass_key_derive_with_salt and must be deallocated using tox_pass_key_free.
+ * using tox_pass_key_derive or tox_pass_key_derive_with_salt and must be
+ * deallocated using tox_pass_key_free.
*/
#ifndef TOX_PASS_KEY_DEFINED
#define TOX_PASS_KEY_DEFINED
@@ -261,10 +270,11 @@ Tox_Pass_Key *tox_pass_key_derive_with_salt(
const uint8_t salt[TOX_PASS_SALT_LENGTH], Tox_Err_Key_Derivation *error);
/**
- * Encrypt a plain text with a key produced by tox_pass_key_derive or tox_pass_key_derive_with_salt.
+ * Encrypt a plain text with a key produced by tox_pass_key_derive or
+ * tox_pass_key_derive_with_salt.
*
- * The output array must be at least `plaintext_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH`
- * bytes long.
+ * The output array must be at least
+ * `plaintext_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH` bytes long.
*
* @param plaintext A byte array of length `plaintext_len`.
* @param plaintext_len The length of the plain text array. Bigger than 0.
@@ -280,7 +290,8 @@ bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t plaintext[], si
* tox_pass_key_derive or tox_pass_key_derive_with_salt.
*
* @param ciphertext A byte array of length `ciphertext_len`.
- * @param ciphertext_len The length of the cipher text array. At least TOX_PASS_ENCRYPTION_EXTRA_LENGTH.
+ * @param ciphertext_len The length of the cipher text array. At least
+ * TOX_PASS_ENCRYPTION_EXTRA_LENGTH.
* @param plaintext The plain text array to write the decrypted data to.
*
* @return true on success.
@@ -308,6 +319,8 @@ typedef enum Tox_Err_Get_Salt {
} Tox_Err_Get_Salt;
+const char *tox_err_get_salt_to_string(Tox_Err_Get_Salt error);
+
/**
* Retrieves the salt used to encrypt the given data.
*
@@ -315,7 +328,8 @@ typedef enum Tox_Err_Get_Salt {
* produce the same key as was previously used. Any data encrypted with this
* module can be used as input.
*
- * The cipher text must be at least TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes in length.
+ * The cipher text must be at least TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes in
+ * length.
* The salt must be TOX_PASS_SALT_LENGTH bytes in length.
* If the passed byte arrays are smaller than required, the behaviour is
* undefined.