diff --git a/.circleci/config.yml b/.circleci/config.yml index 914e426023..1dde721b72 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -126,6 +126,7 @@ jobs: steps: - checkout - run: git submodule update --init --recursive + - run: /src/workspace/tools/inject-repo c-toxcore - run: cd /src/workspace && bazel test -k diff --git a/BUILD.bazel b/BUILD.bazel index 481b46ae39..e846060697 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -10,7 +10,9 @@ genrule( "//c-toxcore/toxcore:tox.h", "//c-toxcore/toxcore:tox_dispatch.h", "//c-toxcore/toxcore:tox_events.h", + "//c-toxcore/toxcore:tox_options.h", "//c-toxcore/toxcore:tox_private.h", + "//c-toxcore/toxcore:tox_types.h", "//c-toxcore/toxencryptsave:toxencryptsave.h", ], outs = [ @@ -18,7 +20,9 @@ genrule( "tox/tox.h", "tox/tox_dispatch.h", "tox/tox_events.h", + "tox/tox_options.h", "tox/tox_private.h", + "tox/tox_types.h", "tox/toxencryptsave.h", ], cmd = """ @@ -26,7 +30,9 @@ genrule( cp $(location //c-toxcore/toxcore:tox.h) $(GENDIR)/c-toxcore/tox/tox.h cp $(location //c-toxcore/toxcore:tox_dispatch.h) $(GENDIR)/c-toxcore/tox/tox_dispatch.h cp $(location //c-toxcore/toxcore:tox_events.h) $(GENDIR)/c-toxcore/tox/tox_events.h + cp $(location //c-toxcore/toxcore:tox_options.h) $(GENDIR)/c-toxcore/tox/tox_options.h cp $(location //c-toxcore/toxcore:tox_private.h) $(GENDIR)/c-toxcore/tox/tox_private.h + cp $(location //c-toxcore/toxcore:tox_types.h) $(GENDIR)/c-toxcore/tox/tox_types.h cp $(location //c-toxcore/toxencryptsave:toxencryptsave.h) $(GENDIR)/c-toxcore/tox/toxencryptsave.h """, visibility = ["//visibility:public"], diff --git a/CMakeLists.txt b/CMakeLists.txt index 9237d21c11..63c955ae95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -348,10 +348,14 @@ set(toxcore_SOURCES toxcore/tox_events.c toxcore/tox_events.h toxcore/tox.h + toxcore/tox_options.c + toxcore/tox_options.h toxcore/tox_private.c toxcore/tox_private.h toxcore/tox_pack.c toxcore/tox_pack.h + toxcore/tox_types.c + toxcore/tox_types.h toxcore/tox_unpack.c toxcore/tox_unpack.h toxcore/util.c @@ -369,8 +373,10 @@ endif() set(toxcore_PKGCONFIG_REQUIRES ${toxcore_PKGCONFIG_REQUIRES} libsodium) set(toxcore_API_HEADERS ${toxcore_SOURCE_DIR}/toxcore/tox.h^tox + ${toxcore_SOURCE_DIR}/toxcore/tox_dispatch.h^tox ${toxcore_SOURCE_DIR}/toxcore/tox_events.h^tox - ${toxcore_SOURCE_DIR}/toxcore/tox_dispatch.h^tox) + ${toxcore_SOURCE_DIR}/toxcore/tox_options.h^tox + ${toxcore_SOURCE_DIR}/toxcore/tox_types.h^tox) if(EXPERIMENTAL_API) set(toxcore_API_HEADERS ${toxcore_API_HEADERS} ${toxcore_SOURCE_DIR}/toxcore/tox_private.h^tox) diff --git a/cmake/StrictAbi.cmake b/cmake/StrictAbi.cmake index ec5792199b..c105fc8ee0 100644 --- a/cmake/StrictAbi.cmake +++ b/cmake/StrictAbi.cmake @@ -32,6 +32,9 @@ function(_make_version_script target) COMMAND ${SHELL} -c "egrep '^\\w' ${header} | grep '${ns}_[a-z0-9_]*(' | grep -v '^typedef' | grep -o '${ns}_[a-z0-9_]*(' | egrep -o '[a-z0-9_]+' | sort -u" OUTPUT_VARIABLE sublib_SYMS OUTPUT_STRIP_TRAILING_WHITESPACE) + if("${sublib_SYMS}" STREQUAL "") + continue() + endif() string(REPLACE "\n" ";" sublib_SYMS ${sublib_SYMS}) foreach(sym ${sublib_SYMS}) diff --git a/other/docker/modules/check b/other/docker/modules/check index e62be62c8a..703ecb59c3 100755 --- a/other/docker/modules/check +++ b/other/docker/modules/check @@ -12,24 +12,24 @@ MODS = {} STD_MODULE = """module std [system] { textual header "/usr/include/alloca.h" textual header "/usr/include/assert.h" - textual header "/usr/include/c++/13.2.1/algorithm" - textual header "/usr/include/c++/13.2.1/array" - textual header "/usr/include/c++/13.2.1/chrono" - textual header "/usr/include/c++/13.2.1/cstddef" - textual header "/usr/include/c++/13.2.1/cstdint" - textual header "/usr/include/c++/13.2.1/cstdio" - textual header "/usr/include/c++/13.2.1/cstdlib" - textual header "/usr/include/c++/13.2.1/cstring" - textual header "/usr/include/c++/13.2.1/iomanip" - textual header "/usr/include/c++/13.2.1/iosfwd" - textual header "/usr/include/c++/13.2.1/limits" - textual header "/usr/include/c++/13.2.1/memory" - textual header "/usr/include/c++/13.2.1/ostream" - textual header "/usr/include/c++/13.2.1/random" - textual header "/usr/include/c++/13.2.1/stdlib.h" - textual header "/usr/include/c++/13.2.1/thread" - textual header "/usr/include/c++/13.2.1/type_traits" - textual header "/usr/include/c++/13.2.1/vector" + textual header "/usr/include/c++/14.2.0/algorithm" + textual header "/usr/include/c++/14.2.0/array" + textual header "/usr/include/c++/14.2.0/chrono" + textual header "/usr/include/c++/14.2.0/cstddef" + textual header "/usr/include/c++/14.2.0/cstdint" + textual header "/usr/include/c++/14.2.0/cstdio" + textual header "/usr/include/c++/14.2.0/cstdlib" + textual header "/usr/include/c++/14.2.0/cstring" + textual header "/usr/include/c++/14.2.0/iomanip" + textual header "/usr/include/c++/14.2.0/iosfwd" + textual header "/usr/include/c++/14.2.0/limits" + textual header "/usr/include/c++/14.2.0/memory" + textual header "/usr/include/c++/14.2.0/ostream" + textual header "/usr/include/c++/14.2.0/random" + textual header "/usr/include/c++/14.2.0/stdlib.h" + textual header "/usr/include/c++/14.2.0/thread" + textual header "/usr/include/c++/14.2.0/type_traits" + textual header "/usr/include/c++/14.2.0/vector" textual header "/usr/include/errno.h" textual header "/usr/include/fortify/stdio.h" textual header "/usr/include/fortify/string.h" diff --git a/other/docker/modules/dockerignore b/other/docker/modules/dockerignore new file mode 100644 index 0000000000..69816061a7 --- /dev/null +++ b/other/docker/modules/dockerignore @@ -0,0 +1,2 @@ +!other/docker/modules/check +!**/BUILD.bazel diff --git a/other/docker/modules/modules.Dockerfile b/other/docker/modules/modules.Dockerfile index ca4a7059c8..8bc8af5c71 100644 --- a/other/docker/modules/modules.Dockerfile +++ b/other/docker/modules/modules.Dockerfile @@ -1,5 +1,4 @@ -FROM toxchat/c-toxcore:sources AS sources -FROM alpine:3.19.0 +FROM alpine:3.21.0 RUN ["apk", "add", "--no-cache", \ "bash", \ @@ -15,7 +14,7 @@ RUN ["apk", "add", "--no-cache", \ "python3"] WORKDIR /work -COPY --from=sources /src/ /work/ +COPY . /work/ COPY toxcore/BUILD.bazel /work/toxcore/ COPY other/docker/modules/check /work/other/docker/modules/ diff --git a/other/docker/modules/modules.Dockerfile.dockerignore b/other/docker/modules/modules.Dockerfile.dockerignore new file mode 100644 index 0000000000..cef84a4375 --- /dev/null +++ b/other/docker/modules/modules.Dockerfile.dockerignore @@ -0,0 +1,25 @@ +# ===== common ===== +# Ignore everything ... +**/* +# ... except sources +!**/*.[ch] +!**/*.cc +!**/*.hh +!CHANGELOG.md +!LICENSE +!README.md +!auto_tests/data/* +!other/bootstrap_daemon/bash-completion/** +!other/bootstrap_daemon/tox-bootstrapd.* +!other/proxy/*.mod +!other/proxy/*.sum +!other/proxy/*.go +# ... and CMake build files (used by most builds). +!**/CMakeLists.txt +!.github/scripts/flags*.sh +!cmake/*.cmake +!other/pkgconfig/* +!other/rpm/* +!so.version +!other/docker/modules/check +!**/BUILD.bazel diff --git a/other/docker/modules/run b/other/docker/modules/run index cfe53a1eaa..5a0f34bc84 100755 --- a/other/docker/modules/run +++ b/other/docker/modules/run @@ -1,6 +1,3 @@ -#!/bin/sh +#!/usr/bin/env bash -set -eux -BUILD=modules -other/docker/sources/build -docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . +. "$(cd "$(dirname "${BASH_SOURCE[0]}")/../sources" && pwd)/run.sh" diff --git a/other/docker/pkgsrc/dockerignore b/other/docker/pkgsrc/dockerignore new file mode 100644 index 0000000000..67d10a9c8b --- /dev/null +++ b/other/docker/pkgsrc/dockerignore @@ -0,0 +1 @@ +!other/docker/pkgsrc/pkgsrc.patch diff --git a/other/docker/pkgsrc/pkgsrc.Dockerfile b/other/docker/pkgsrc/pkgsrc.Dockerfile index 3483bdfba4..58dd3ed75e 100644 --- a/other/docker/pkgsrc/pkgsrc.Dockerfile +++ b/other/docker/pkgsrc/pkgsrc.Dockerfile @@ -1,11 +1,14 @@ FROM toxchat/pkgsrc:latest WORKDIR /work -COPY . /work/c-toxcore-0.2.18 -RUN ["tar", "zcf", "c-toxcore.tar.gz", "c-toxcore-0.2.18"] +COPY . /work/c-toxcore-0.2.20 +RUN ["tar", "zcf", "c-toxcore.tar.gz", "c-toxcore-0.2.20"] + +WORKDIR /work/pkgsrc +COPY other/docker/pkgsrc/pkgsrc.patch /tmp/pkgsrc.patch +RUN ["patch", "-p1", "-i", "/tmp/pkgsrc.patch"] WORKDIR /work/pkgsrc/chat/toxcore -RUN ["sed", "-i", "-e", "s/libtoxcore.so.2.18.0/libtoxcore.so.2.20.0/g", "PLIST"] RUN ["bmake", "clean"] RUN ["bmake", "DISTFILES=c-toxcore.tar.gz", "DISTDIR=/work", "NO_CHECKSUM=yes"] RUN ["bmake", "install"] diff --git a/other/docker/pkgsrc/pkgsrc.Dockerfile.dockerignore b/other/docker/pkgsrc/pkgsrc.Dockerfile.dockerignore index 3a3643cba1..8d70daf0a4 100644 --- a/other/docker/pkgsrc/pkgsrc.Dockerfile.dockerignore +++ b/other/docker/pkgsrc/pkgsrc.Dockerfile.dockerignore @@ -21,3 +21,4 @@ !other/pkgconfig/* !other/rpm/* !so.version +!other/docker/pkgsrc/pkgsrc.patch diff --git a/other/docker/pkgsrc/pkgsrc.patch b/other/docker/pkgsrc/pkgsrc.patch new file mode 100644 index 0000000000..5db437e085 --- /dev/null +++ b/other/docker/pkgsrc/pkgsrc.patch @@ -0,0 +1,31 @@ +diff --git a/chat/toxcore/Makefile b/chat/toxcore/Makefile +index 70466704d..53a08ad08 100644 +--- a/chat/toxcore/Makefile ++++ b/chat/toxcore/Makefile +@@ -1,6 +1,6 @@ + # $NetBSD: Makefile,v 1.6 2024/01/22 13:16:56 ryoon Exp $ + +-DISTNAME= toxcore-0.2.18 ++DISTNAME= toxcore-0.2.20 + PKGREVISION= 2 + CATEGORIES= chat + MASTER_SITES= ${MASTER_SITE_GITHUB:=TokTok/} +diff --git a/chat/toxcore/PLIST b/chat/toxcore/PLIST +index f0a5e4f04..4122b0867 100644 +--- a/chat/toxcore/PLIST ++++ b/chat/toxcore/PLIST +@@ -4,11 +4,13 @@ bin/tox-bootstrapd + include/tox/tox.h + include/tox/tox_dispatch.h + include/tox/tox_events.h ++include/tox/tox_options.h ++include/tox/tox_types.h + include/tox/toxav.h + include/tox/toxencryptsave.h + lib/libtoxcore.a + lib/libtoxcore.so + lib/libtoxcore.so.2 +-lib/libtoxcore.so.2.18.0 ++lib/libtoxcore.so.2.20.0 + lib/pkgconfig/toxcore.pc + share/bash-completion/completions/tox-bootstrapd diff --git a/toxcore/BUILD.bazel b/toxcore/BUILD.bazel index 4ff75fa561..0a794bfe5b 100644 --- a/toxcore/BUILD.bazel +++ b/toxcore/BUILD.bazel @@ -6,7 +6,9 @@ exports_files( "tox.h", "tox_dispatch.h", "tox_events.h", + "tox_options.h", "tox_private.h", + "tox_types.h", ], visibility = ["//c-toxcore:__subpackages__"], ) @@ -1072,6 +1074,25 @@ cc_library( ], ) +cc_library( + name = "tox_types", + srcs = ["tox_types.c"], + hdrs = ["tox_types.h"], + visibility = ["//c-toxcore:__subpackages__"], +) + +cc_library( + name = "tox_options", + srcs = ["tox_options.c"], + hdrs = ["tox_options.h"], + copts = ["-UTOX_HIDE_DEPRECATED"], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":ccompat", + ":tox_types", + ], +) + cc_library( name = "tox", srcs = [ @@ -1104,6 +1125,8 @@ cc_library( ":network", ":onion_client", ":state", + ":tox_options", + ":tox_types", ":util", "//c-toxcore/toxencryptsave:defines", "@pthread", @@ -1117,6 +1140,7 @@ cc_test( deps = [ ":crypto_core", ":tox", + ":tox_options", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], diff --git a/toxcore/Makefile.inc b/toxcore/Makefile.inc index 2ee4a72f25..4deb496a59 100644 --- a/toxcore/Makefile.inc +++ b/toxcore/Makefile.inc @@ -1,19 +1,14 @@ lib_LTLIBRARIES += libtoxcore.la libtoxcore_la_include_HEADERS = \ - ../toxcore/tox.h + ../toxcore/tox.h \ + ../toxcore/tox_options.h \ + ../toxcore/tox_types.h libtoxcore_la_includedir = $(includedir)/tox libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \ ../third_party/cmp/cmp.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/events/conference_connected.c \ ../toxcore/events/conference_invite.c \ ../toxcore/events/conference_message.c \ @@ -56,97 +51,108 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \ ../toxcore/events/group_topic.c \ ../toxcore/events/group_topic_lock.c \ ../toxcore/events/group_voice_state.c \ - ../toxcore/DHT.h \ + ../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/mem.h \ + ../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/mono_time.h \ + ../toxcore/mem.h \ + ../toxcore/Messenger.c \ + ../toxcore/Messenger.h \ ../toxcore/mono_time.c \ - ../toxcore/network.h \ - ../toxcore/network.c \ - ../toxcore/crypto_core.h \ - ../toxcore/crypto_core.c \ - ../toxcore/crypto_core_pack.h \ - ../toxcore/crypto_core_pack.c \ - ../toxcore/timed_auth.h \ - ../toxcore/timed_auth.c \ - ../toxcore/ping_array.h \ - ../toxcore/ping_array.c \ - ../toxcore/net_crypto.h \ + ../toxcore/mono_time.h \ ../toxcore/net_crypto.c \ + ../toxcore/net_crypto.h \ ../toxcore/net_profile.c \ ../toxcore/net_profile.h \ - ../toxcore/friend_requests.h \ - ../toxcore/friend_requests.c \ - ../toxcore/LAN_discovery.h \ - ../toxcore/LAN_discovery.c \ - ../toxcore/friend_connection.h \ - ../toxcore/friend_connection.c \ - ../toxcore/Messenger.h \ - ../toxcore/Messenger.c \ - ../toxcore/ping.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/shared_key_cache.h \ + ../toxcore/ping.h \ ../toxcore/shared_key_cache.c \ - ../toxcore/sort.h \ + ../toxcore/shared_key_cache.h \ ../toxcore/sort.c \ - ../toxcore/state.h \ + ../toxcore/sort.h \ ../toxcore/state.c \ - ../toxcore/tox.h \ - ../toxcore/tox.c \ - ../toxcore/tox_dispatch.h \ + ../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_event.h \ + ../toxcore/tox_dispatch.h \ ../toxcore/tox_event.c \ - ../toxcore/tox_events.h \ + ../toxcore/tox_event.h \ ../toxcore/tox_events.c \ - ../toxcore/tox_pack.h \ + ../toxcore/tox_events.h \ + ../toxcore/tox_options.c \ + ../toxcore/tox_options.h \ ../toxcore/tox_pack.c \ - ../toxcore/tox_unpack.h \ - ../toxcore/tox_unpack.c \ + ../toxcore/tox_pack.h \ ../toxcore/tox_private.c \ ../toxcore/tox_private.h \ ../toxcore/tox_struct.h \ - ../toxcore/tox_api.c \ - ../toxcore/util.h \ + ../toxcore/tox_types.c \ + ../toxcore/tox_types.h \ + ../toxcore/tox_unpack.c \ + ../toxcore/tox_unpack.h \ + ../toxcore/tox.c \ + ../toxcore/tox.h \ ../toxcore/util.c \ - ../toxcore/group.h \ - ../toxcore/group.c \ - ../toxcore/group_announce.h \ - ../toxcore/group_announce.c \ - ../toxcore/group_onion_announce.c \ - ../toxcore/group_onion_announce.h \ - ../toxcore/group_chats.h \ - ../toxcore/group_chats.c \ - ../toxcore/group_common.h \ - ../toxcore/group_connection.c \ - ../toxcore/group_connection.h \ - ../toxcore/group_pack.c \ - ../toxcore/group_pack.h \ - ../toxcore/group_moderation.c \ - ../toxcore/group_moderation.h \ - ../toxcore/onion.h \ - ../toxcore/onion.c \ - ../toxcore/logger.h \ - ../toxcore/logger.c \ - ../toxcore/onion_announce.h \ - ../toxcore/onion_announce.c \ - ../toxcore/onion_client.h \ - ../toxcore/onion_client.c \ - ../toxcore/announce.h \ - ../toxcore/announce.c \ - ../toxcore/forwarding.h \ - ../toxcore/forwarding.c \ - ../toxcore/TCP_client.h \ - ../toxcore/TCP_client.c \ - ../toxcore/TCP_common.h \ - ../toxcore/TCP_common.c \ - ../toxcore/TCP_server.h \ - ../toxcore/TCP_server.c \ - ../toxcore/TCP_connection.h \ - ../toxcore/TCP_connection.c \ - ../toxcore/list.c \ - ../toxcore/list.h + ../toxcore/util.h libtoxcore_la_CFLAGS = -I$(top_srcdir) \ -I$(top_srcdir)/toxcore \ diff --git a/toxcore/tox.c b/toxcore/tox.c index 7349928e4d..14b820ad5f 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -32,6 +32,7 @@ #include "network.h" #include "onion_client.h" #include "state.h" +#include "tox_options.h" #include "tox_private.h" #include "tox_struct.h" // IWYU pragma: keep #include "util.h" diff --git a/toxcore/tox.h b/toxcore/tox.h index 4d3bd4805b..8a93244997 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -102,14 +102,15 @@ #include #include +#include "tox_options.h" // IWYU pragma: export +#include "tox_types.h" // IWYU pragma: export + #ifdef __cplusplus extern "C" { #endif /** @{ @namespace tox */ -#ifndef TOX_DEFINED -#define TOX_DEFINED /** * @brief The Tox instance type. * @@ -119,8 +120,7 @@ extern "C" { * device is limited. Note that this is not just a per-process limit, since the * limiting factor is the number of usable ports on a device. */ -typedef struct Tox Tox; -#endif /* TOX_DEFINED */ +struct Tox; /** @{ * @name API version @@ -393,471 +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 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); - -/** - * @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(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); - -/** @} */ - /** @{ * @name Creation and destruction */ diff --git a/toxcore/tox_api.c b/toxcore/tox_api.c index 567287b110..c5ee08ddd6 100644 --- a/toxcore/tox_api.c +++ b/toxcore/tox_api.c @@ -1,21 +1,11 @@ /* SPDX-License-Identifier: GPL-3.0-or-later * Copyright © 2016-2025 The TokTok team. */ -#include "tox.h" +#include "tox.h" // IWYU pragma: associated -#include // free, malloc -#include // memcpy, strlen - -#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; @@ -137,272 +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; -} -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); - } -} - const char *tox_user_status_to_string(Tox_User_Status value) { switch (value) { diff --git a/toxcore/tox_options.c b/toxcore/tox_options.c new file mode 100644 index 0000000000..d67a8aebd0 --- /dev/null +++ b/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 // free, malloc, calloc +#include // 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/toxcore/tox_options.h b/toxcore/tox_options.h new file mode 100644 index 0000000000..6cf6b93c2c --- /dev/null +++ b/toxcore/tox_options.h @@ -0,0 +1,484 @@ +/* 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 +#include +#include + +#include "tox_types.h" // IWYU pragma: export + +#ifdef __cplusplus +extern "C" { +#endif + +/** @{ + * @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 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); + +/** + * @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(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. + */ +struct 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/toxcore/tox_private.h b/toxcore/tox_private.h index cc8a085659..0b7116776d 100644 --- a/toxcore/tox_private.h +++ b/toxcore/tox_private.h @@ -11,6 +11,7 @@ #include #include "tox.h" +#include "tox_types.h" #ifdef __cplusplus extern "C" { diff --git a/toxcore/tox_struct.h b/toxcore/tox_struct.h index 88f74ead62..25bfcfe436 100644 --- a/toxcore/tox_struct.h +++ b/toxcore/tox_struct.h @@ -9,9 +9,9 @@ #include #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 diff --git a/toxcore/tox_test.cc b/toxcore/tox_test.cc index d3fe9bae8a..f4c289420a 100644 --- a/toxcore/tox_test.cc +++ b/toxcore/tox_test.cc @@ -6,6 +6,7 @@ #include #include "crypto_core.h" +#include "tox_options.h" #include "tox_private.h" namespace { diff --git a/toxcore/tox_types.c b/toxcore/tox_types.c new file mode 100644 index 0000000000..f9c16fe5f4 --- /dev/null +++ b/toxcore/tox_types.c @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2025 The TokTok team. + * Copyright © 2013 Tox project. + */ + +#include "tox_types.h" // IWYU pragma: keep diff --git a/toxcore/tox_types.h b/toxcore/tox_types.h new file mode 100644 index 0000000000..e471f0b45b --- /dev/null +++ b/toxcore/tox_types.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2025 The TokTok team. + * Copyright © 2013 Tox project. + */ + +/** @brief Typedefs for Tox types. + * + * This file contains typedefs for Tox structs. It's not necessary to include + * this file directly, as it's included and exported by other headers with + * functions. + * + * More documentation about the types is available in the respective header + * files, e.g. tox.h, tox_options.h, etc. linked in the comments. + */ +#ifndef C_TOXCORE_TOXCORE_TOX_TYPES_H +#define C_TOXCORE_TOXCORE_TOX_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @{ @namespace tox */ + +#ifndef TOX_DEFINED +#define TOX_DEFINED +typedef struct Tox Tox; // tox.h +#endif /* TOX_DEFINED */ + +#ifndef TOX_OPTIONS_DEFINED +#define TOX_OPTIONS_DEFINED +typedef struct Tox_Options Tox_Options; // tox_options.h +#endif /* TOX_OPTIONS_DEFINED */ + +/** @} */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_TYPES_H */