Merge commit '596ea37298252ce239cfb6fd9c0f459574bd54e3'
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android-23]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android-23]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android-23]) (push) Has been cancelled
ContinuousDelivery / windows (windows-2022, ) (push) Has been cancelled
ContinuousDelivery / windows (windows-2022, asan) (push) Has been cancelled
ContinuousDelivery / dumpsyms (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
ContinuousIntegration / on ubuntu-24.04-arm (push) Has been cancelled
ContinuousIntegration / asan on ubuntu-24.04-arm (push) Has been cancelled
ContinuousIntegration / on ubuntu-latest (push) Has been cancelled
ContinuousIntegration / asan on ubuntu-latest (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android-23]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android-23]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android-23]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled

This commit is contained in:
Green Sky
2025-11-04 21:18:05 +01:00
117 changed files with 1409 additions and 697 deletions

View File

@@ -26,6 +26,8 @@
#include "../toxcore/network.h"
#include "../toxcore/onion.h"
#include "../toxcore/onion_announce.h"
#include "../toxcore/os_memory.h"
#include "../toxcore/os_random.h"
#include "../toxcore/tox.h"
#define TCP_RELAY_ENABLED
@@ -157,14 +159,15 @@ int main(int argc, char *argv[])
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
const uint16_t start_port = PORT;
const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM);
DHT *dht = new_dht(logger, mem, rng, ns, mono_time, new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr), true, true);
Onion *onion = new_onion(logger, mem, mono_time, rng, dht);
Forwarding *forwarding = new_forwarding(logger, mem, rng, mono_time, dht);
Networking_Core *net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr);
DHT *dht = new_dht(logger, mem, rng, ns, mono_time, net, true, true);
Onion *onion = new_onion(logger, mem, mono_time, rng, dht, net);
Forwarding *forwarding = new_forwarding(logger, mem, rng, mono_time, dht, net);
GC_Announces_List *gc_announces_list = new_gca_list(mem);
Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht);
Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht, net);
#ifdef DHT_NODE_EXTRA_PACKETS
bootstrap_set_callbacks(dht_get_net(dht), (uint32_t)DAEMON_VERSION_NUMBER, (const uint8_t *) motd_str, strlen(motd_str) + 1);
bootstrap_set_callbacks(net, (uint32_t)DAEMON_VERSION_NUMBER, (const uint8_t *) motd_str, strlen(motd_str) + 1);
#endif
if (onion == nullptr || forwarding == nullptr || onion_a == nullptr) {
@@ -214,7 +217,7 @@ int main(int argc, char *argv[])
fclose(file);
printf("\n");
printf("Port: %u\n", net_ntohs(net_port(dht_get_net(dht))));
printf("Port: %u\n", net_ntohs(net_port(net)));
if (argc > argvoffset + 3) {
printf("Trying to bootstrap into the network...\n");
@@ -258,7 +261,7 @@ int main(int argc, char *argv[])
do_dht(dht);
if (mono_time_is_timeout(mono_time, last_lan_discovery, is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL)) {
lan_discovery_send(dht_get_net(dht), broadcast, dht_get_self_public_key(dht), net_htons(PORT));
lan_discovery_send(net, broadcast, dht_get_self_public_key(dht), net_htons(PORT));
last_lan_discovery = mono_time_get(mono_time);
}
@@ -267,7 +270,7 @@ int main(int argc, char *argv[])
#ifdef TCP_RELAY_ENABLED
do_tcp_server(tcp_s, mono_time);
#endif
networking_poll(dht_get_net(dht), nullptr);
networking_poll(net, nullptr);
c_sleep(1);
}

View File

@@ -24,6 +24,8 @@ CPPCHECK+=("--suppress=knownConditionTrueFalse")
CPPCHECK+=("--suppress=missingIncludeSystem")
# TODO(iphydf): Maybe fix?
CPPCHECK+=("--suppress=signConversion")
# We have suppressions in the code for the misra extension.
CPPCHECK+=("--suppress=unmatchedSuppression")
# We use this for VLAs.
CPPCHECK_CXX+=("--suppress=allocaCalled")

View File

@@ -25,6 +25,7 @@ cc_binary(
"//c-toxcore/toxcore:network",
"//c-toxcore/toxcore:onion",
"//c-toxcore/toxcore:onion_announce",
"//c-toxcore/toxcore:os_random",
"//c-toxcore/toxcore:tox",
"@libconfig",
],

View File

@@ -1,6 +1,6 @@
###########################################################
# Builder image: we compile the code here (static build)
FROM alpine:3.19.0 AS build
FROM alpine:3.21.0 AS build
RUN ["apk", "--no-cache", "add",\
"clang",\
@@ -26,33 +26,32 @@ COPY other/bootstrap_node_packets.[ch] other/
COPY other/DHT_bootstrap.c other/
COPY other/pkgconfig other/pkgconfig
COPY other/rpm other/rpm
COPY testing/misc_tools.[ch] testing/
COPY testing testing
COPY toxcore toxcore
COPY toxencryptsave toxencryptsave
COPY third_party third_party
COPY CMakeLists.txt so.version ./
COPY other/bootstrap_daemon/CMakeLists.txt other/bootstrap_daemon/CMakeLists.txt
COPY testing/CMakeLists.txt testing/CMakeLists.txt
RUN CC=clang cmake -B_build -H. \
-GNinja \
-DCMAKE_C_FLAGS="-DTCP_SERVER_USE_EPOLL -fsanitize=alignment,return,returns-nonnull-attribute,vla-bound,unreachable,float-cast-overflow,null -fsanitize-trap=all -fstack-protector-all" \
-DCMAKE_UNITY_BUILD=ON \
-DCMAKE_BUILD_TYPE=Release \
-DFULLY_STATIC=ON \
-DMIN_LOGGER_LEVEL=DEBUG \
-DBUILD_TOXAV=OFF \
-DBOOTSTRAP_DAEMON=ON && \
cmake --build _build --target install
-GNinja \
-DCMAKE_C_FLAGS="-DTCP_SERVER_USE_EPOLL -fsanitize=alignment,return,returns-nonnull-attribute,vla-bound,unreachable,float-cast-overflow,null -fsanitize-trap=all -fstack-protector-all" \
-DCMAKE_UNITY_BUILD=ON \
-DCMAKE_BUILD_TYPE=Release \
-DFULLY_STATIC=ON \
-DMIN_LOGGER_LEVEL=TRACE \
-DBUILD_TOXAV=OFF \
-DBOOTSTRAP_DAEMON=ON \
&& cmake --build _build --target install
# Verify checksum from dev-built binary, so we can be sure Docker Hub doesn't
# mess with your binaries.
COPY other/bootstrap_daemon/docker/tox-bootstrapd.sha256 other/bootstrap_daemon/docker/
ARG CHECK=sha256sum
RUN SHA256="$("$CHECK" /usr/local/bin/tox-bootstrapd)" && \
("$CHECK" -c other/bootstrap_daemon/docker/tox-bootstrapd.sha256 || \
(echo "::error file=other/bootstrap_daemon/docker/tox-bootstrapd.sha256,line=1::$SHA256" && \
false))
RUN SHA256="$("$CHECK" /usr/local/bin/tox-bootstrapd)" \
&& ("$CHECK" -c other/bootstrap_daemon/docker/tox-bootstrapd.sha256 || \
(echo "::error file=other/bootstrap_daemon/docker/tox-bootstrapd.sha256,line=1::$SHA256" \
&& false))
# Remove all the example bootstrap nodes from the config file.
COPY other/bootstrap_daemon/tox-bootstrapd.conf other/bootstrap_daemon/
@@ -69,12 +68,14 @@ FROM debian:bookworm-slim
COPY --from=build /usr/local/bin/tox-bootstrapd /usr/local/bin/
COPY --from=build /src/c-toxcore/other/bootstrap_daemon/tox-bootstrapd.conf /etc/tox-bootstrapd.conf
RUN useradd --home-dir /var/lib/tox-bootstrapd --create-home \
--system --shell /sbin/nologin \
--comment "Account to run the Tox DHT bootstrap daemon" \
--user-group tox-bootstrapd && \
chmod 644 /etc/tox-bootstrapd.conf && \
chmod 700 /var/lib/tox-bootstrapd
RUN useradd \
--home-dir /var/lib/tox-bootstrapd \
--create-home \
--system --shell /sbin/nologin \
--comment "Account to run the Tox DHT bootstrap daemon" \
--user-group tox-bootstrapd \
&& chmod 644 /etc/tox-bootstrapd.conf \
&& chmod 700 /var/lib/tox-bootstrapd
WORKDIR /var/lib/tox-bootstrapd

View File

@@ -0,0 +1,22 @@
# Very selectively add files to the image, because we may have random stuff
# lying around. In particular, we don't need to rebuild the docker image when
# toxav changes or the Dockerfile changes down from the build.
**/*
!cmake/*
!other/bootstrap_daemon/bash-completion/*
!other/bootstrap_daemon/docker/get-nodes.py
!other/bootstrap_daemon/docker/tox-bootstrapd.sha256
!other/bootstrap_daemon/src/*
!other/bootstrap_daemon/tox-bootstrapd.conf
!other/bootstrap_node_packets.[ch]
!other/DHT_bootstrap.c
!other/pkgconfig/*
!other/rpm/*
!testing/misc_tools.[ch]
!toxcore/**/*
!toxencryptsave/**/*
!third_party/cmp/cmp.[ch]
!CMakeLists.txt
!so.version
!other/bootstrap_daemon/CMakeLists.txt
!testing/CMakeLists.txt

View File

@@ -0,0 +1,12 @@
#!/bin/sh
set -eux -o pipefail
GIT_ROOT="$(git rev-parse --show-toplevel)"
cd "$GIT_ROOT"
docker build \
-t toxchat/bootstrap-node \
-f other/bootstrap_daemon/docker/Dockerfile \
--build-arg CHECK=true \
.

View File

@@ -9,7 +9,7 @@
*/
#include "command_line_arguments.h"
#include "global.h"
#include "global.h" // IWYU pragma: keep
#include "log.h"
#include "../../../toxcore/ccompat.h"
@@ -26,7 +26,7 @@ static void print_help(void)
// 2 space indent
// Make sure all lines fit into 80 columns
// Make sure options are listed in alphabetical order
log_write(LOG_LEVEL_INFO,
LOG_WRITE(LOG_LEVEL_INFO,
"Usage: tox-bootstrapd [OPTION]... --config=FILE_PATH\n"
"\n"
"Options:\n"
@@ -43,6 +43,7 @@ static void print_help(void)
" Default option when no --log-backend is\n"
" specified.\n"
" stdout Writes log messages to stdout/stderr.\n"
" --trace Enable verbose network trace logging in toxcore.\n"
" --version Print version information.\n");
}
@@ -51,7 +52,7 @@ Cli_Status handle_command_line_arguments(
bool *run_in_foreground)
{
if (argc < 2) {
log_write(LOG_LEVEL_ERROR, "Error: No arguments provided.\n\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Error: No arguments provided.\n\n");
print_help();
return CLI_STATUS_ERROR;
}
@@ -64,6 +65,7 @@ Cli_Status handle_command_line_arguments(
{"help", no_argument, nullptr, 'h'},
{"log-backend", required_argument, nullptr, 'l'}, // optional, defaults to syslog
{"version", no_argument, nullptr, 'v'},
{"trace", no_argument, nullptr, 't'},
{nullptr, 0, nullptr, 0 }
};
@@ -99,7 +101,7 @@ Cli_Status handle_command_line_arguments(
*log_backend = LOG_BACKEND_STDOUT;
log_backend_set = true;
} else {
log_write(LOG_LEVEL_ERROR, "Error: Invalid BACKEND value for --log-backend option passed: %s\n\n", optarg);
LOG_WRITE(LOG_LEVEL_ERROR, "Error: Invalid BACKEND value for --log-backend option passed: %s\n\n", optarg);
print_help();
return CLI_STATUS_ERROR;
}
@@ -107,16 +109,21 @@ Cli_Status handle_command_line_arguments(
break;
case 'v':
log_write(LOG_LEVEL_INFO, "Version: %lu\n", DAEMON_VERSION_NUMBER);
LOG_WRITE(LOG_LEVEL_INFO, "Version: %lu\n", DAEMON_VERSION_NUMBER);
return CLI_STATUS_DONE;
case 't':
LOG_WRITE(LOG_LEVEL_INFO, "Enabling trace logging in toxcore.\n");
log_enable_trace(true);
break;
case '?':
log_write(LOG_LEVEL_ERROR, "Error: Unrecognized option %s\n\n", argv[optind - 1]);
LOG_WRITE(LOG_LEVEL_ERROR, "Error: Unrecognized option %s\n\n", argv[optind - 1]);
print_help();
return CLI_STATUS_ERROR;
case ':':
log_write(LOG_LEVEL_ERROR, "Error: No argument provided for option %s\n\n", argv[optind - 1]);
LOG_WRITE(LOG_LEVEL_ERROR, "Error: No argument provided for option %s\n\n", argv[optind - 1]);
print_help();
return CLI_STATUS_ERROR;
}
@@ -127,7 +134,7 @@ Cli_Status handle_command_line_arguments(
}
if (!cfg_file_path_set) {
log_write(LOG_LEVEL_ERROR, "Error: The required --config option wasn't specified\n\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Error: The required --config option wasn't specified\n\n");
print_help();
return CLI_STATUS_ERROR;
}

View File

@@ -41,8 +41,8 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
config_setting_t *ports_array = config_lookup(cfg, NAME_TCP_RELAY_PORTS);
if (ports_array == nullptr) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in the configuration file.\n", NAME_TCP_RELAY_PORTS);
log_write(LOG_LEVEL_WARNING, "Using default '%s':\n", NAME_TCP_RELAY_PORTS);
LOG_WRITE(LOG_LEVEL_WARNING, "No '%s' setting in the configuration file.\n", NAME_TCP_RELAY_PORTS);
LOG_WRITE(LOG_LEVEL_WARNING, "Using default '%s':\n", NAME_TCP_RELAY_PORTS);
const uint16_t default_ports[] = {DEFAULT_TCP_RELAY_PORTS};
@@ -53,13 +53,13 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
const size_t default_ports_count = sizeof(default_ports) / sizeof(*default_ports);
for (size_t i = 0; i < default_ports_count; ++i) {
log_write(LOG_LEVEL_INFO, "Port #%zu: %u\n", i, default_ports[i]);
LOG_WRITE(LOG_LEVEL_INFO, "Port #%zu: %u\n", i, default_ports[i]);
}
// Similar procedure to the one of reading config file below
*tcp_relay_ports = (uint16_t *)malloc(default_ports_count * sizeof(uint16_t));
if (*tcp_relay_ports == nullptr) {
log_write(LOG_LEVEL_ERROR, "Allocation failure.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Allocation failure.\n");
return;
}
@@ -69,7 +69,7 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
if ((*tcp_relay_ports)[*tcp_relay_port_count] < MIN_ALLOWED_PORT
|| (*tcp_relay_ports)[*tcp_relay_port_count] > MAX_ALLOWED_PORT) {
log_write(LOG_LEVEL_WARNING, "Port #%zu: Invalid port: %u, should be in [%d, %d]. Skipping.\n", i,
LOG_WRITE(LOG_LEVEL_WARNING, "Port #%zu: Invalid port: %u, should be in [%d, %d]. Skipping.\n", i,
(*tcp_relay_ports)[*tcp_relay_port_count], MIN_ALLOWED_PORT, MAX_ALLOWED_PORT);
continue;
}
@@ -87,7 +87,7 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
}
if (config_setting_is_array(ports_array) == CONFIG_FALSE) {
log_write(LOG_LEVEL_ERROR, "'%s' setting should be an array. Array syntax: 'setting = [value1, value2, ...]'.\n",
LOG_WRITE(LOG_LEVEL_ERROR, "'%s' setting should be an array. Array syntax: 'setting = [value1, value2, ...]'.\n",
NAME_TCP_RELAY_PORTS);
return;
}
@@ -95,13 +95,13 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
const int config_port_count = config_setting_length(ports_array);
if (config_port_count == 0) {
log_write(LOG_LEVEL_ERROR, "'%s' is empty.\n", NAME_TCP_RELAY_PORTS);
LOG_WRITE(LOG_LEVEL_ERROR, "'%s' is empty.\n", NAME_TCP_RELAY_PORTS);
return;
}
*tcp_relay_ports = (uint16_t *)malloc(config_port_count * sizeof(uint16_t));
if (*tcp_relay_ports == nullptr) {
log_write(LOG_LEVEL_ERROR, "Allocation failure.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Allocation failure.\n");
return;
}
@@ -110,12 +110,12 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
if (elem == nullptr) {
// It's NULL if `ports_array` is not an array (we have that check earlier) or if `i` is out of range, which should not be
log_write(LOG_LEVEL_WARNING, "Port #%d: Something went wrong while parsing the port. Stopping reading ports.\n", i);
LOG_WRITE(LOG_LEVEL_WARNING, "Port #%d: Something went wrong while parsing the port. Stopping reading ports.\n", i);
break;
}
if (config_setting_is_number(elem) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "Port #%d: Not a number. Skipping.\n", i);
LOG_WRITE(LOG_LEVEL_WARNING, "Port #%d: Not a number. Skipping.\n", i);
continue;
}
@@ -123,7 +123,7 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
if ((*tcp_relay_ports)[*tcp_relay_port_count] < MIN_ALLOWED_PORT
|| (*tcp_relay_ports)[*tcp_relay_port_count] > MAX_ALLOWED_PORT) {
log_write(LOG_LEVEL_WARNING, "Port #%d: Invalid port: %u, should be in [%d, %d]. Skipping.\n", i,
LOG_WRITE(LOG_LEVEL_WARNING, "Port #%d: Invalid port: %u, should be in [%d, %d]. Skipping.\n", i,
(*tcp_relay_ports)[*tcp_relay_port_count], MIN_ALLOWED_PORT, MAX_ALLOWED_PORT);
continue;
}
@@ -169,15 +169,15 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
// Read the file. If there is an error, report it and exit.
if (config_read_file(&cfg, cfg_file_path) == CONFIG_FALSE) {
log_write(LOG_LEVEL_ERROR, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
LOG_WRITE(LOG_LEVEL_ERROR, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
config_destroy(&cfg);
return false;
}
// Get port
if (config_lookup_int(&cfg, NAME_PORT, port) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_PORT);
log_write(LOG_LEVEL_WARNING, "Using default '%s': %d\n", NAME_PORT, DEFAULT_PORT);
LOG_WRITE(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_PORT);
LOG_WRITE(LOG_LEVEL_WARNING, "Using default '%s': %d\n", NAME_PORT, DEFAULT_PORT);
*port = DEFAULT_PORT;
}
@@ -185,15 +185,15 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
const char *tmp_pid_file;
if (config_lookup_string(&cfg, NAME_PID_FILE_PATH, &tmp_pid_file) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_PID_FILE_PATH);
log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_PID_FILE_PATH, DEFAULT_PID_FILE_PATH);
LOG_WRITE(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_PID_FILE_PATH);
LOG_WRITE(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_PID_FILE_PATH, DEFAULT_PID_FILE_PATH);
tmp_pid_file = DEFAULT_PID_FILE_PATH;
}
const size_t pid_file_path_len = strlen(tmp_pid_file) + 1;
*pid_file_path = (char *)malloc(pid_file_path_len);
if (*pid_file_path == nullptr) {
log_write(LOG_LEVEL_ERROR, "Allocation failure.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Allocation failure.\n");
return false;
}
memcpy(*pid_file_path, tmp_pid_file, pid_file_path_len);
@@ -202,15 +202,15 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
const char *tmp_keys_file;
if (config_lookup_string(&cfg, NAME_KEYS_FILE_PATH, &tmp_keys_file) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_KEYS_FILE_PATH);
log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_KEYS_FILE_PATH, DEFAULT_KEYS_FILE_PATH);
LOG_WRITE(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_KEYS_FILE_PATH);
LOG_WRITE(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_KEYS_FILE_PATH, DEFAULT_KEYS_FILE_PATH);
tmp_keys_file = DEFAULT_KEYS_FILE_PATH;
}
const size_t keys_file_path_len = strlen(tmp_keys_file) + 1;
*keys_file_path = (char *)malloc(keys_file_path_len);
if (*keys_file_path == nullptr) {
log_write(LOG_LEVEL_ERROR, "Allocation failure.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Allocation failure.\n");
free(*pid_file_path);
*pid_file_path = nullptr;
return false;
@@ -219,31 +219,31 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
// Get IPv6 option
if (tox_config_lookup_bool(&cfg, NAME_ENABLE_IPV6, enable_ipv6) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_IPV6);
log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_IPV6, DEFAULT_ENABLE_IPV6 ? "true" : "false");
LOG_WRITE(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_IPV6);
LOG_WRITE(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_IPV6, DEFAULT_ENABLE_IPV6 ? "true" : "false");
*enable_ipv6 = DEFAULT_ENABLE_IPV6;
}
// Get IPv4 fallback option
if (tox_config_lookup_bool(&cfg, NAME_ENABLE_IPV4_FALLBACK, enable_ipv4_fallback) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_IPV4_FALLBACK);
log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_IPV4_FALLBACK,
LOG_WRITE(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_IPV4_FALLBACK);
LOG_WRITE(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_IPV4_FALLBACK,
DEFAULT_ENABLE_IPV4_FALLBACK ? "true" : "false");
*enable_ipv4_fallback = DEFAULT_ENABLE_IPV4_FALLBACK;
}
// Get LAN discovery option
if (tox_config_lookup_bool(&cfg, NAME_ENABLE_LAN_DISCOVERY, enable_lan_discovery) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_LAN_DISCOVERY);
log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_LAN_DISCOVERY,
LOG_WRITE(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_LAN_DISCOVERY);
LOG_WRITE(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_LAN_DISCOVERY,
DEFAULT_ENABLE_LAN_DISCOVERY ? "true" : "false");
*enable_lan_discovery = DEFAULT_ENABLE_LAN_DISCOVERY;
}
// Get TCP relay option
if (tox_config_lookup_bool(&cfg, NAME_ENABLE_TCP_RELAY, enable_tcp_relay) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_TCP_RELAY);
log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_TCP_RELAY,
LOG_WRITE(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_TCP_RELAY);
LOG_WRITE(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_TCP_RELAY,
DEFAULT_ENABLE_TCP_RELAY ? "true" : "false");
*enable_tcp_relay = DEFAULT_ENABLE_TCP_RELAY;
}
@@ -256,8 +256,8 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
// Get MOTD option
if (tox_config_lookup_bool(&cfg, NAME_ENABLE_MOTD, enable_motd) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_MOTD);
log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_MOTD,
LOG_WRITE(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_MOTD);
LOG_WRITE(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_MOTD,
DEFAULT_ENABLE_MOTD ? "true" : "false");
*enable_motd = DEFAULT_ENABLE_MOTD;
}
@@ -267,8 +267,8 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
const char *tmp_motd;
if (config_lookup_string(&cfg, NAME_MOTD, &tmp_motd) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_MOTD);
log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_MOTD, DEFAULT_MOTD);
LOG_WRITE(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_MOTD);
LOG_WRITE(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_MOTD, DEFAULT_MOTD);
tmp_motd = DEFAULT_MOTD;
}
@@ -280,33 +280,33 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
config_destroy(&cfg);
log_write(LOG_LEVEL_INFO, "Successfully read:\n");
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_PID_FILE_PATH, *pid_file_path);
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_KEYS_FILE_PATH, *keys_file_path);
log_write(LOG_LEVEL_INFO, "'%s': %d\n", NAME_PORT, *port);
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV6, *enable_ipv6 ? "true" : "false");
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV4_FALLBACK, *enable_ipv4_fallback ? "true" : "false");
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, *enable_lan_discovery ? "true" : "false");
LOG_WRITE(LOG_LEVEL_INFO, "Successfully read:\n");
LOG_WRITE(LOG_LEVEL_INFO, "'%s': %s\n", NAME_PID_FILE_PATH, *pid_file_path);
LOG_WRITE(LOG_LEVEL_INFO, "'%s': %s\n", NAME_KEYS_FILE_PATH, *keys_file_path);
LOG_WRITE(LOG_LEVEL_INFO, "'%s': %d\n", NAME_PORT, *port);
LOG_WRITE(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV6, *enable_ipv6 ? "true" : "false");
LOG_WRITE(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV4_FALLBACK, *enable_ipv4_fallback ? "true" : "false");
LOG_WRITE(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, *enable_lan_discovery ? "true" : "false");
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_TCP_RELAY, *enable_tcp_relay ? "true" : "false");
LOG_WRITE(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_TCP_RELAY, *enable_tcp_relay ? "true" : "false");
// Show info about tcp ports only if tcp relay is enabled
if (*enable_tcp_relay) {
if (*tcp_relay_port_count == 0) {
log_write(LOG_LEVEL_ERROR, "No TCP ports could be read.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "No TCP ports could be read.\n");
} else {
log_write(LOG_LEVEL_INFO, "Read %d TCP ports:\n", *tcp_relay_port_count);
LOG_WRITE(LOG_LEVEL_INFO, "Read %d TCP ports:\n", *tcp_relay_port_count);
for (int i = 0; i < *tcp_relay_port_count; ++i) {
log_write(LOG_LEVEL_INFO, "Port #%d: %u\n", i, (*tcp_relay_ports)[i]);
LOG_WRITE(LOG_LEVEL_INFO, "Port #%d: %u\n", i, (*tcp_relay_ports)[i]);
}
}
}
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_MOTD, *enable_motd ? "true" : "false");
LOG_WRITE(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_MOTD, *enable_motd ? "true" : "false");
if (*enable_motd) {
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_MOTD, *motd);
LOG_WRITE(LOG_LEVEL_INFO, "'%s': %s\n", NAME_MOTD, *motd);
}
return true;
@@ -330,7 +330,7 @@ static uint8_t *bootstrap_hex_string_to_bin(const char *hex_string)
const size_t len = strlen(hex_string) / 2;
uint8_t *ret = (uint8_t *)malloc(len);
if (ret == nullptr) {
log_write(LOG_LEVEL_ERROR, "Allocation failure.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Allocation failure.\n");
return nullptr;
}
@@ -358,7 +358,7 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6
config_init(&cfg);
if (config_read_file(&cfg, cfg_file_path) == CONFIG_FALSE) {
log_write(LOG_LEVEL_ERROR, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
LOG_WRITE(LOG_LEVEL_ERROR, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
config_destroy(&cfg);
return false;
}
@@ -366,14 +366,14 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6
config_setting_t *node_list = config_lookup(&cfg, NAME_BOOTSTRAP_NODES);
if (node_list == nullptr) {
log_write(LOG_LEVEL_WARNING, "No '%s' setting in the configuration file. Skipping bootstrapping.\n",
LOG_WRITE(LOG_LEVEL_WARNING, "No '%s' setting in the configuration file. Skipping bootstrapping.\n",
NAME_BOOTSTRAP_NODES);
config_destroy(&cfg);
return true;
}
if (config_setting_length(node_list) == 0) {
log_write(LOG_LEVEL_WARNING, "No bootstrap nodes found. Skipping bootstrapping.\n");
LOG_WRITE(LOG_LEVEL_WARNING, "No bootstrap nodes found. Skipping bootstrapping.\n");
config_destroy(&cfg);
return true;
}
@@ -402,30 +402,30 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6
// Check that all settings are present
if (config_setting_lookup_string(node, NAME_PUBLIC_KEY, &bs_public_key) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "Bootstrap node #%d: Couldn't find '%s' setting. Skipping the node.\n", i,
LOG_WRITE(LOG_LEVEL_WARNING, "Bootstrap node #%d: Couldn't find '%s' setting. Skipping the node.\n", i,
NAME_PUBLIC_KEY);
goto next;
}
if (config_setting_lookup_int(node, NAME_PORT, &bs_port) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "Bootstrap node #%d: Couldn't find '%s' setting. Skipping the node.\n", i, NAME_PORT);
LOG_WRITE(LOG_LEVEL_WARNING, "Bootstrap node #%d: Couldn't find '%s' setting. Skipping the node.\n", i, NAME_PORT);
goto next;
}
if (config_setting_lookup_string(node, NAME_ADDRESS, &bs_address) == CONFIG_FALSE) {
log_write(LOG_LEVEL_WARNING, "Bootstrap node #%d: Couldn't find '%s' setting. Skipping the node.\n", i, NAME_ADDRESS);
LOG_WRITE(LOG_LEVEL_WARNING, "Bootstrap node #%d: Couldn't find '%s' setting. Skipping the node.\n", i, NAME_ADDRESS);
goto next;
}
// Process settings
if (strlen(bs_public_key) != CRYPTO_PUBLIC_KEY_SIZE * 2) {
log_write(LOG_LEVEL_WARNING, "Bootstrap node #%d: Invalid '%s': %s. Skipping the node.\n", i, NAME_PUBLIC_KEY,
LOG_WRITE(LOG_LEVEL_WARNING, "Bootstrap node #%d: Invalid '%s': %s. Skipping the node.\n", i, NAME_PUBLIC_KEY,
bs_public_key);
goto next;
}
if (bs_port < MIN_ALLOWED_PORT || bs_port > MAX_ALLOWED_PORT) {
log_write(LOG_LEVEL_WARNING, "Bootstrap node #%d: Invalid '%s': %d, should be in [%d, %d]. Skipping the node.\n", i,
LOG_WRITE(LOG_LEVEL_WARNING, "Bootstrap node #%d: Invalid '%s': %d, should be in [%d, %d]. Skipping the node.\n", i,
NAME_PORT,
bs_port, MIN_ALLOWED_PORT, MAX_ALLOWED_PORT);
goto next;
@@ -437,11 +437,11 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6
free(bs_public_key_bin);
if (!address_resolved) {
log_write(LOG_LEVEL_WARNING, "Bootstrap node #%d: Invalid '%s': %s. Skipping the node.\n", i, NAME_ADDRESS, bs_address);
LOG_WRITE(LOG_LEVEL_WARNING, "Bootstrap node #%d: Invalid '%s': %s. Skipping the node.\n", i, NAME_ADDRESS, bs_address);
goto next;
}
log_write(LOG_LEVEL_INFO, "Successfully added bootstrap node #%d: %s:%d %s\n", i, bs_address, bs_port, bs_public_key);
LOG_WRITE(LOG_LEVEL_INFO, "Successfully added bootstrap node #%d: %s:%d %s\n", i, bs_address, bs_port, bs_public_key);
next:
// config_setting_lookup_string() allocates string inside and doesn't allow us to free it directly

View File

@@ -15,6 +15,12 @@
#define INVALID_BACKEND ((LOG_BACKEND)-1u)
static LOG_BACKEND current_backend = INVALID_BACKEND;
static bool log_toxcore_trace = false;
void log_enable_trace(bool enable)
{
log_toxcore_trace = enable;
}
bool log_open(LOG_BACKEND backend)
{
@@ -58,22 +64,27 @@ bool log_close(void)
return true;
}
bool log_write(LOG_LEVEL level, const char *format, ...)
bool log_write(LOG_LEVEL level, const char *category, const char *file, int line, const char *format, ...)
{
if (current_backend == INVALID_BACKEND) {
return false;
}
if (level == LOG_LEVEL_TRACE && !log_toxcore_trace) {
// By default, no trace logging.
return true;
}
va_list args;
va_start(args, format);
switch (current_backend) {
case LOG_BACKEND_STDOUT:
log_backend_stdout_write(level, format, args);
log_backend_stdout_write(level, category, file, line, format, args);
break;
case LOG_BACKEND_SYSLOG:
log_backend_syslog_write(level, format, args);
log_backend_syslog_write(level, category, file, line, format, args);
break;
}

View File

@@ -20,11 +20,18 @@ typedef enum LOG_BACKEND {
} LOG_BACKEND;
typedef enum LOG_LEVEL {
LOG_LEVEL_TRACE,
LOG_LEVEL_INFO,
LOG_LEVEL_WARNING,
LOG_LEVEL_ERROR
} LOG_LEVEL;
/**
* Enables or disables logging of trace messages from toxcore.
* @param enable true to enable, false to disable.
*/
void log_enable_trace(bool enable);
/**
* Initializes logger.
* @param backend Specifies which backend to use.
@@ -45,6 +52,13 @@ bool log_close(void);
* @param ... Zero or more arguments, similar to printf function.
* @return true on success, false if log is closed.
*/
bool log_write(LOG_LEVEL level, const char *format, ...) GNU_PRINTF(2, 3);
bool log_write(LOG_LEVEL level, const char *category, const char *file, int line, const char *format, ...) GNU_PRINTF(5, 6);
enum {
LOG_PATH_PREFIX = sizeof(__FILE__) - sizeof("log.h")
};
#define LOG_WRITEC(level, category, ...) log_write(level, category, &__FILE__[LOG_PATH_PREFIX], __LINE__, __VA_ARGS__)
#define LOG_WRITE(level, ...) LOG_WRITEC(level, "tox.bootstrap", __VA_ARGS__)
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_H

View File

@@ -11,12 +11,15 @@
#include <stdarg.h>
#include <stdio.h>
#include <sys/time.h>
#include "../../../toxcore/ccompat.h"
#include "log.h"
static FILE *log_backend_stdout_level(LOG_LEVEL level)
{
switch (level) {
case LOG_LEVEL_TRACE: // intentional fallthrough
case LOG_LEVEL_INFO:
return stdout;
@@ -28,8 +31,36 @@ static FILE *log_backend_stdout_level(LOG_LEVEL level)
return stdout;
}
void log_backend_stdout_write(LOG_LEVEL level, const char *format, va_list args)
static const char *log_level_string(LOG_LEVEL level)
{
vfprintf(log_backend_stdout_level(level), format, args);
fflush(log_backend_stdout_level(level));
switch (level) {
case LOG_LEVEL_TRACE:
return "Debug";
case LOG_LEVEL_INFO:
return "Info";
case LOG_LEVEL_WARNING:
return "Warning";
case LOG_LEVEL_ERROR:
return "Critical"; // Qt-compatible.
}
return "Debug"; // Just in case. Shouldn't happen.
}
// Output bootstrap node log messages in the standard Tox log format:
// [15:02:46.433 UTC] (tox.bootstrap) config.c:444 : Info: Successfully added bootstrap node ...
void log_backend_stdout_write(LOG_LEVEL level, const char *category, const char *file, int line, const char *format, va_list args)
{
struct timeval tv = {0};
gettimeofday(&tv, nullptr);
FILE *stream = log_backend_stdout_level(level);
fprintf(stream, "[%02d:%02d:%02d.%03d UTC] (%s) %s:%d : %s: ",
(int)(tv.tv_sec / 3600 % 24), (int)(tv.tv_sec / 60 % 60), (int)(tv.tv_sec % 60), (int)(tv.tv_usec / 1000),
category, file, line, log_level_string(level));
vfprintf(stream, format, args);
fflush(stream);
}

View File

@@ -15,6 +15,6 @@
#include "../../../toxcore/attributes.h"
#include "log.h"
void log_backend_stdout_write(LOG_LEVEL level, const char *format, va_list args) GNU_PRINTF(2, 0);
void log_backend_stdout_write(LOG_LEVEL level, const char *category, const char *file, int line, const char *format, va_list args) GNU_PRINTF(5, 0);
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_STDOUT_H

View File

@@ -33,6 +33,9 @@ void log_backend_syslog_close(void)
static int log_backend_syslog_level(LOG_LEVEL level)
{
switch (level) {
case LOG_LEVEL_TRACE:
return LOG_DEBUG;
case LOG_LEVEL_INFO:
return LOG_INFO;
@@ -46,7 +49,7 @@ static int log_backend_syslog_level(LOG_LEVEL level)
return LOG_INFO;
}
void log_backend_syslog_write(LOG_LEVEL level, const char *format, va_list args)
void log_backend_syslog_write(LOG_LEVEL level, const char *category, const char *file, int line, const char *format, va_list args)
{
va_list args2;
@@ -66,6 +69,6 @@ void log_backend_syslog_write(LOG_LEVEL level, const char *format, va_list args)
}
vsnprintf(buf, size + 1, format, args);
syslog(log_backend_syslog_level(level), "%s", buf);
syslog(log_backend_syslog_level(level), "(%s) %s", category, buf);
free(buf);
}

View File

@@ -17,6 +17,6 @@
void log_backend_syslog_open(void);
void log_backend_syslog_close(void);
void log_backend_syslog_write(LOG_LEVEL level, const char *format, va_list args) GNU_PRINTF(2, 0);
void log_backend_syslog_write(LOG_LEVEL level, const char *category, const char *file, int line, const char *format, va_list args) GNU_PRINTF(5, 0);
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_SYSLOG_H

View File

@@ -36,11 +36,12 @@
#include "../../../toxcore/group_announce.h"
#include "../../../toxcore/group_onion_announce.h"
#include "../../../toxcore/logger.h"
#include "../../../toxcore/mem.h"
#include "../../../toxcore/mono_time.h"
#include "../../../toxcore/network.h"
#include "../../../toxcore/onion.h"
#include "../../../toxcore/onion_announce.h"
#include "../../../toxcore/os_memory.h"
#include "../../../toxcore/os_random.h"
// misc
#include "../../bootstrap_node_packets.h"
@@ -116,7 +117,7 @@ static void print_public_key(const uint8_t *public_key)
index += snprintf(buffer + index, sizeof(buffer) - index, "%02X", public_key[i]);
}
log_write(LOG_LEVEL_INFO, "Public Key: %s\n", buffer);
LOG_WRITE(LOG_LEVEL_INFO, "Public Key: %s\n", buffer);
}
// Demonizes the process, appending PID to the PID file and closing file descriptors based on log backend
@@ -128,7 +129,7 @@ static Cli_Status daemonize(LOG_BACKEND log_backend, char *pid_file_path)
FILE *pid_file = fopen(pid_file_path, "r");
if (pid_file != nullptr) {
log_write(LOG_LEVEL_WARNING, "Another instance of the daemon is already running, PID file %s exists.\n", pid_file_path);
LOG_WRITE(LOG_LEVEL_WARNING, "Another instance of the daemon is already running, PID file %s exists.\n", pid_file_path);
fclose(pid_file);
}
@@ -136,7 +137,7 @@ static Cli_Status daemonize(LOG_BACKEND log_backend, char *pid_file_path)
pid_file = fopen(pid_file_path, "a+");
if (pid_file == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't open the PID file for writing: %s. Exiting.\n", pid_file_path);
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't open the PID file for writing: %s. Exiting.\n", pid_file_path);
return CLI_STATUS_ERROR;
}
@@ -146,26 +147,26 @@ static Cli_Status daemonize(LOG_BACKEND log_backend, char *pid_file_path)
if (pid > 0) {
fprintf(pid_file, "%d", pid);
fclose(pid_file);
log_write(LOG_LEVEL_INFO, "Forked successfully: PID: %d.\n", pid);
LOG_WRITE(LOG_LEVEL_INFO, "Forked successfully: PID: %d.\n", pid);
return CLI_STATUS_DONE;
} else {
fclose(pid_file);
}
if (pid < 0) {
log_write(LOG_LEVEL_ERROR, "Forking failed. Exiting.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Forking failed. Exiting.\n");
return CLI_STATUS_ERROR;
}
// Create a new SID for the child process
if (setsid() < 0) {
log_write(LOG_LEVEL_ERROR, "SID creation failure. Exiting.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "SID creation failure. Exiting.\n");
return CLI_STATUS_ERROR;
}
// Change the current working directory
if ((chdir("/")) < 0) {
log_write(LOG_LEVEL_ERROR, "Couldn't change working directory to '/'. Exiting.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't change working directory to '/'. Exiting.\n");
return CLI_STATUS_ERROR;
}
@@ -185,6 +186,8 @@ static LOG_LEVEL logger_level_to_log_level(Logger_Level level)
{
switch (level) {
case LOGGER_LEVEL_TRACE:
return LOG_LEVEL_TRACE;
case LOGGER_LEVEL_DEBUG:
case LOGGER_LEVEL_INFO:
return LOG_LEVEL_INFO;
@@ -203,7 +206,11 @@ static LOG_LEVEL logger_level_to_log_level(Logger_Level level)
static void toxcore_logger_callback(void *context, Logger_Level level, const char *file, uint32_t line,
const char *func, const char *message, void *userdata)
{
log_write(logger_level_to_log_level(level), "%s:%u(%s) %s\n", file, line, func, message);
const char *category = "tox.core";
if (level == LOGGER_LEVEL_TRACE) {
category = "tox.trace";
}
log_write(logger_level_to_log_level(level), category, file, line, "%s\n", message);
}
static volatile sig_atomic_t caught_signal = 0;
@@ -235,7 +242,7 @@ int main(int argc, char *argv[])
log_open(log_backend);
log_write(LOG_LEVEL_INFO, "Running \"%s\" version %lu.\n", DAEMON_NAME, DAEMON_VERSION_NUMBER);
LOG_WRITE(LOG_LEVEL_INFO, "Running \"%s\" version %lu.\n", DAEMON_NAME, DAEMON_VERSION_NUMBER);
char *pid_file_path = nullptr;
char *keys_file_path = nullptr;
@@ -251,14 +258,14 @@ int main(int argc, char *argv[])
if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &start_port, &enable_ipv6, &enable_ipv4_fallback,
&enable_lan_discovery, &enable_tcp_relay, &tcp_relay_ports, &tcp_relay_port_count, &enable_motd, &motd)) {
log_write(LOG_LEVEL_INFO, "General config read successfully\n");
LOG_WRITE(LOG_LEVEL_INFO, "General config read successfully\n");
} else {
log_write(LOG_LEVEL_ERROR, "Couldn't read config file: %s. Exiting.\n", cfg_file_path);
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't read config file: %s. Exiting.\n", cfg_file_path);
return 1;
}
if (start_port < MIN_ALLOWED_PORT || start_port > MAX_ALLOWED_PORT) {
log_write(LOG_LEVEL_ERROR, "Invalid port: %d, should be in [%d, %d]. Exiting.\n", start_port, MIN_ALLOWED_PORT,
LOG_WRITE(LOG_LEVEL_ERROR, "Invalid port: %d, should be in [%d, %d]. Exiting.\n", start_port, MIN_ALLOWED_PORT,
MAX_ALLOWED_PORT);
free(motd);
free(tcp_relay_ports);
@@ -283,28 +290,26 @@ int main(int argc, char *argv[])
IP ip;
ip_init(&ip, enable_ipv6);
const Memory *mem = os_memory();
const Random *rng = os_random();
const Tox_Memory *mem = os_memory();
const Tox_Random *rng = os_random();
const Network *ns = os_network();
Logger *logger = logger_new(mem);
if (MIN_LOGGER_LEVEL <= LOGGER_LEVEL_DEBUG) {
logger_callback_log(logger, toxcore_logger_callback, nullptr, nullptr);
}
logger_callback_log(logger, toxcore_logger_callback, nullptr, nullptr);
const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM);
Networking_Core *net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr);
if (net == nullptr) {
if (enable_ipv6 && enable_ipv4_fallback) {
log_write(LOG_LEVEL_WARNING, "Couldn't initialize IPv6 networking. Falling back to using IPv4.\n");
LOG_WRITE(LOG_LEVEL_WARNING, "Couldn't initialize IPv6 networking. Falling back to using IPv4.\n");
enable_ipv6 = false;
ip_init(&ip, enable_ipv6);
net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr);
if (net == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't fallback to IPv4. Exiting.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't fallback to IPv4. Exiting.\n");
logger_kill(logger);
free(motd);
free(tcp_relay_ports);
@@ -312,7 +317,7 @@ int main(int argc, char *argv[])
return 1;
}
} else {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize networking. Exiting.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't initialize networking. Exiting.\n");
logger_kill(logger);
free(motd);
free(tcp_relay_ports);
@@ -324,7 +329,7 @@ int main(int argc, char *argv[])
Mono_Time *const mono_time = mono_time_new(mem, nullptr, nullptr);
if (mono_time == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize monotonic timer. Exiting.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't initialize monotonic timer. Exiting.\n");
kill_networking(net);
logger_kill(logger);
free(motd);
@@ -338,7 +343,7 @@ int main(int argc, char *argv[])
DHT *const dht = new_dht(logger, mem, rng, ns, mono_time, net, true, enable_lan_discovery);
if (dht == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n");
mono_time_free(mem, mono_time);
kill_networking(net);
logger_kill(logger);
@@ -348,10 +353,10 @@ int main(int argc, char *argv[])
return 1;
}
Forwarding *forwarding = new_forwarding(logger, mem, rng, mono_time, dht);
Forwarding *forwarding = new_forwarding(logger, mem, rng, mono_time, dht, net);
if (forwarding == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize forwarding. Exiting.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't initialize forwarding. Exiting.\n");
kill_dht(dht);
mono_time_free(mem, mono_time);
kill_networking(net);
@@ -362,10 +367,10 @@ int main(int argc, char *argv[])
return 1;
}
Announcements *announce = new_announcements(logger, mem, rng, mono_time, forwarding);
Announcements *announce = new_announcements(logger, mem, rng, mono_time, forwarding, dht, net);
if (announce == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize DHT announcements. Exiting.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't initialize DHT announcements. Exiting.\n");
kill_forwarding(forwarding);
kill_dht(dht);
mono_time_free(mem, mono_time);
@@ -380,7 +385,7 @@ int main(int argc, char *argv[])
GC_Announces_List *group_announce = new_gca_list(mem);
if (group_announce == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize group announces. Exiting.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't initialize group announces. Exiting.\n");
kill_announcements(announce);
kill_forwarding(forwarding);
kill_dht(dht);
@@ -393,10 +398,10 @@ int main(int argc, char *argv[])
return 1;
}
Onion *onion = new_onion(logger, mem, mono_time, rng, dht);
Onion *onion = new_onion(logger, mem, mono_time, rng, dht, net);
if (onion == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n");
kill_gca(group_announce);
kill_announcements(announce);
kill_forwarding(forwarding);
@@ -410,10 +415,10 @@ int main(int argc, char *argv[])
return 1;
}
Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht);
Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht, net);
if (onion_a == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion Announce. Exiting.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion Announce. Exiting.\n");
kill_gca(group_announce);
kill_onion(onion);
kill_announcements(announce);
@@ -431,11 +436,11 @@ int main(int argc, char *argv[])
gca_onion_init(group_announce, onion_a);
if (enable_motd) {
if (bootstrap_set_callbacks(dht_get_net(dht), DAEMON_VERSION_NUMBER, (uint8_t *)motd, strlen(motd) + 1) == 0) {
log_write(LOG_LEVEL_INFO, "Set MOTD successfully.\n");
if (bootstrap_set_callbacks(net, DAEMON_VERSION_NUMBER, (uint8_t *)motd, strlen(motd) + 1) == 0) {
LOG_WRITE(LOG_LEVEL_INFO, "Set MOTD successfully.\n");
free(motd);
} else {
log_write(LOG_LEVEL_ERROR, "Couldn't set MOTD: %s. Exiting.\n", motd);
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't set MOTD: %s. Exiting.\n", motd);
kill_onion_announce(onion_a);
kill_gca(group_announce);
kill_onion(onion);
@@ -453,10 +458,10 @@ int main(int argc, char *argv[])
}
if (manage_keys(dht, keys_file_path)) {
log_write(LOG_LEVEL_INFO, "Keys are managed successfully.\n");
LOG_WRITE(LOG_LEVEL_INFO, "Keys are managed successfully.\n");
free(keys_file_path);
} else {
log_write(LOG_LEVEL_ERROR, "Couldn't read/write: %s. Exiting.\n", keys_file_path);
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't read/write: %s. Exiting.\n", keys_file_path);
kill_onion_announce(onion_a);
kill_gca(group_announce);
kill_onion(onion);
@@ -475,7 +480,7 @@ int main(int argc, char *argv[])
if (enable_tcp_relay) {
if (tcp_relay_port_count == 0) {
log_write(LOG_LEVEL_ERROR, "No TCP relay ports read. Exiting.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "No TCP relay ports read. Exiting.\n");
kill_onion_announce(onion_a);
kill_gca(group_announce);
kill_announcements(announce);
@@ -496,7 +501,7 @@ int main(int argc, char *argv[])
free(tcp_relay_ports);
if (tcp_server != nullptr) {
log_write(LOG_LEVEL_INFO, "Initialized Tox TCP server successfully.\n");
LOG_WRITE(LOG_LEVEL_INFO, "Initialized Tox TCP server successfully.\n");
struct rlimit limit;
@@ -515,14 +520,14 @@ int main(int argc, char *argv[])
}
if (getrlimit(RLIMIT_NOFILE, &limit) == 0 && limit.rlim_cur < rlim_min) {
log_write(LOG_LEVEL_WARNING,
LOG_WRITE(LOG_LEVEL_WARNING,
"Current limit on the number of files this process can open (%ju) is rather low for the proper functioning of the TCP server. "
"Consider raising the limit to at least %ju or the recommended %ju. "
"Continuing using the current limit (%ju).\n",
(uintmax_t)limit.rlim_cur, (uintmax_t)rlim_min, (uintmax_t)rlim_suggested, (uintmax_t)limit.rlim_cur);
}
} else {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox TCP server. Exiting.\n");
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't initialize Tox TCP server. Exiting.\n");
kill_onion_announce(onion_a);
kill_gca(group_announce);
kill_onion(onion);
@@ -537,9 +542,9 @@ int main(int argc, char *argv[])
}
if (bootstrap_from_config(cfg_file_path, dht, enable_ipv6)) {
log_write(LOG_LEVEL_INFO, "List of bootstrap nodes read successfully.\n");
LOG_WRITE(LOG_LEVEL_INFO, "List of bootstrap nodes read successfully.\n");
} else {
log_write(LOG_LEVEL_ERROR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path);
LOG_WRITE(LOG_LEVEL_ERROR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path);
kill_tcp_server(tcp_server);
kill_onion_announce(onion_a);
kill_gca(group_announce);
@@ -564,7 +569,7 @@ int main(int argc, char *argv[])
if (enable_lan_discovery) {
broadcast = lan_discovery_init(mem, ns);
log_write(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n");
LOG_WRITE(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n");
}
struct sigaction sa;
@@ -578,11 +583,11 @@ int main(int argc, char *argv[])
sigfillset(&sa.sa_mask);
if (sigaction(SIGINT, &sa, nullptr) != 0) {
log_write(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGINT. Continuing without the signal handler set.\n");
LOG_WRITE(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGINT. Continuing without the signal handler set.\n");
}
if (sigaction(SIGTERM, &sa, nullptr) != 0) {
log_write(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGTERM. Continuing without the signal handler set.\n");
LOG_WRITE(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGTERM. Continuing without the signal handler set.\n");
}
while (caught_signal == 0) {
@@ -591,7 +596,7 @@ int main(int argc, char *argv[])
do_dht(dht);
if (enable_lan_discovery && mono_time_is_timeout(mono_time, last_lan_discovery, LAN_DISCOVERY_INTERVAL)) {
lan_discovery_send(dht_get_net(dht), broadcast, dht_get_self_public_key(dht), net_htons_port);
lan_discovery_send(net, broadcast, dht_get_self_public_key(dht), net_htons_port);
last_lan_discovery = mono_time_get(mono_time);
}
@@ -601,10 +606,10 @@ int main(int argc, char *argv[])
do_tcp_server(tcp_server, mono_time);
}
networking_poll(dht_get_net(dht), nullptr);
networking_poll(net, nullptr);
if (waiting_for_dht_connection && dht_isconnected(dht)) {
log_write(LOG_LEVEL_INFO, "Connected to another bootstrap node successfully.\n");
LOG_WRITE(LOG_LEVEL_INFO, "Connected to another bootstrap node successfully.\n");
waiting_for_dht_connection = false;
}
@@ -613,15 +618,15 @@ int main(int argc, char *argv[])
switch (caught_signal) {
case SIGINT:
log_write(LOG_LEVEL_INFO, "Received SIGINT (%d) signal. Exiting.\n", SIGINT);
LOG_WRITE(LOG_LEVEL_INFO, "Received SIGINT (%d) signal. Exiting.\n", SIGINT);
break;
case SIGTERM:
log_write(LOG_LEVEL_INFO, "Received SIGTERM (%d) signal. Exiting.\n", SIGTERM);
LOG_WRITE(LOG_LEVEL_INFO, "Received SIGTERM (%d) signal. Exiting.\n", SIGTERM);
break;
default:
log_write(LOG_LEVEL_INFO, "Received (%ld) signal. Exiting.\n", (long)caught_signal);
LOG_WRITE(LOG_LEVEL_INFO, "Received (%ld) signal. Exiting.\n", (long)caught_signal);
}
lan_discovery_kill(broadcast);

View File

@@ -1,6 +1,6 @@
# Stage 1 - Compile websockify.
FROM toxchat/bootstrap-node:latest AS tox
FROM golang:1.17-alpine AS websockify
FROM golang:1.23-alpine3.21 AS websockify
COPY websockify /work/websockify
RUN cd /work/websockify && go mod download github.com/gorilla/websocket && go install
@@ -25,5 +25,7 @@ USER tox
#RUN /usr/local/bin/tox-bootstrapd --config /etc/tox-bootstrapd.conf --log-backend stdout \
# && sleep 1
COPY tox-bootstrapd.conf /etc/
WORKDIR /web
CMD ["/entrypoint.sh"]

View File

@@ -0,0 +1,12 @@
#!/bin/sh
set -eux -o pipefail
GIT_ROOT="$(git rev-parse --show-toplevel)"
# Build bootstrap daemon first.
"$GIT_ROOT/other/bootstrap_daemon/docker/build.sh"
# Build websocket server.
cd "$GIT_ROOT/other/bootstrap_daemon/websocket"
docker build -t toxchat/bootstrap-node:latest-websocket .

View File

@@ -2,5 +2,5 @@
set -eux
/usr/local/bin/tox-bootstrapd --config /etc/tox-bootstrapd.conf --log-backend stdout
/usr/local/bin/tox-bootstrapd --config /etc/tox-bootstrapd.conf --log-backend stdout --trace
/usr/local/bin/websockify -l "0.0.0.0:$PORT" -t 127.0.0.1:33445

View File

@@ -0,0 +1,21 @@
# Tox WebSocket bootstrap daemon configuration file.
port = 33445
keys_file_path = "/var/lib/tox-bootstrapd/keys"
pid_file_path = "/var/run/tox-bootstrapd/tox-bootstrapd.pid"
enable_ipv6 = false
enable_ipv4_fallback = true
enable_lan_discovery = false
enable_tcp_relay = true
tcp_relay_ports = [443, 3389, 33445]
enable_motd = true
motd = "tox-bootstrapd"
# No bootstrap nodes for now, since none of them support WebSocket.
bootstrap_nodes = ()

View File

@@ -2,5 +2,5 @@
set -eux
BUILD=autotools
other/docker/sources/build
other/docker/sources/build.sh
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .

View File

@@ -2,5 +2,5 @@
set -eux
BUILD=clang-tidy
other/docker/sources/build
other/docker/sources/build.sh
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .

View File

@@ -2,5 +2,5 @@
set -eux
BUILD=compcert
other/docker/sources/build
other/docker/sources/build.sh
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .

View File

@@ -5,7 +5,7 @@ set -eux
read -a ci_env <<<"$(bash <(curl -s https://codecov.io/env))"
BUILD=coverage
other/docker/sources/build
other/docker/sources/build.sh
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .
docker run "${ci_env[@]}" -e CI=true --name toxcore-coverage --rm -t toxchat/c-toxcore:coverage /usr/local/bin/codecov

View File

@@ -2,5 +2,5 @@
set -eux
BUILD=cppcheck
other/docker/sources/build
other/docker/sources/build.sh
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .

View File

@@ -2,5 +2,5 @@
set -eux
BUILD=goblint
other/docker/sources/build
other/docker/sources/build.sh
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .

View File

@@ -2,5 +2,5 @@
set -eux
BUILD=infer
other/docker/sources/build
other/docker/sources/build.sh
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .

View File

@@ -2,5 +2,5 @@
set -eux
BUILD=misra
other/docker/sources/build
other/docker/sources/build.sh
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .

View File

@@ -6,7 +6,7 @@ PROJECT_COMMIT_ID="$(git rev-parse HEAD)"
PROJECT_COMMIT_ID_SHORT="$(git rev-parse --short HEAD)"
BUILD=rpm
other/docker/sources/build
other/docker/sources/build.sh
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" . \
--build-arg="PROJECT_VERSION=$PROJECT_VERSION" \
--build-arg="PROJECT_COMMIT_ID=$PROJECT_COMMIT_ID" \

View File

@@ -2,5 +2,5 @@
set -eux
BUILD=slimcc
other/docker/sources/build
other/docker/sources/build.sh
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .

View File

@@ -2,5 +2,5 @@
set -eux
BUILD=sparse
other/docker/sources/build
other/docker/sources/build.sh
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .

View File

@@ -2,5 +2,5 @@
set -eux
BUILD=tcc
other/docker/sources/build
other/docker/sources/build.sh
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .

View File

@@ -2,5 +2,5 @@
set -eux
BUILD=tokstyle
other/docker/sources/build
other/docker/sources/build.sh
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .