mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Make tox-bootstrapd free memory on SIGINT and SIGTERM
Useful for using memory analyzing tools.
This commit is contained in:
parent
700accb3c7
commit
1cbc9609a7
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
// system provided
|
// system provided
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <signal.h> // for POSIX sigaction(2)
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
// C
|
// C
|
||||||
|
@ -214,6 +215,13 @@ static void toxcore_logger_callback(void *context, Logger_Level level, const cha
|
||||||
log_write(log_level, "%s:%d(%s) %s\n", file, line, func, message);
|
log_write(log_level, "%s:%d(%s) %s\n", file, line, func, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static volatile sig_atomic_t caught_signal = 0;
|
||||||
|
|
||||||
|
static void handle_signal(int signum)
|
||||||
|
{
|
||||||
|
caught_signal = signum;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
umask(077);
|
umask(077);
|
||||||
|
@ -232,16 +240,17 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
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, *keys_file_path;
|
char *pid_file_path = nullptr;
|
||||||
|
char *keys_file_path = nullptr;
|
||||||
int port;
|
int port;
|
||||||
int enable_ipv6;
|
int enable_ipv6;
|
||||||
int enable_ipv4_fallback;
|
int enable_ipv4_fallback;
|
||||||
int enable_lan_discovery;
|
int enable_lan_discovery;
|
||||||
int enable_tcp_relay;
|
int enable_tcp_relay;
|
||||||
uint16_t *tcp_relay_ports;
|
uint16_t *tcp_relay_ports = nullptr;
|
||||||
int tcp_relay_port_count;
|
int tcp_relay_port_count;
|
||||||
int enable_motd;
|
int enable_motd;
|
||||||
char *motd;
|
char *motd = nullptr;
|
||||||
|
|
||||||
if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &port, &enable_ipv6, &enable_ipv4_fallback,
|
if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &port, &enable_ipv6, &enable_ipv4_fallback,
|
||||||
&enable_lan_discovery, &enable_tcp_relay, &tcp_relay_ports, &tcp_relay_port_count, &enable_motd, &motd)) {
|
&enable_lan_discovery, &enable_tcp_relay, &tcp_relay_ports, &tcp_relay_port_count, &enable_motd, &motd)) {
|
||||||
|
@ -254,6 +263,10 @@ int main(int argc, char *argv[])
|
||||||
if (port < MIN_ALLOWED_PORT || port > MAX_ALLOWED_PORT) {
|
if (port < MIN_ALLOWED_PORT || port > MAX_ALLOWED_PORT) {
|
||||||
log_write(LOG_LEVEL_ERROR, "Invalid port: %d, should be in [%d, %d]. Exiting.\n", port, MIN_ALLOWED_PORT,
|
log_write(LOG_LEVEL_ERROR, "Invalid port: %d, should be in [%d, %d]. Exiting.\n", port, MIN_ALLOWED_PORT,
|
||||||
MAX_ALLOWED_PORT);
|
MAX_ALLOWED_PORT);
|
||||||
|
free(motd);
|
||||||
|
free(tcp_relay_ports);
|
||||||
|
free(keys_file_path);
|
||||||
|
free(pid_file_path);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,11 +297,17 @@ int main(int argc, char *argv[])
|
||||||
if (net == 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);
|
logger_kill(logger);
|
||||||
|
free(motd);
|
||||||
|
free(tcp_relay_ports);
|
||||||
|
free(keys_file_path);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
logger_kill(logger);
|
||||||
|
free(motd);
|
||||||
|
free(tcp_relay_ports);
|
||||||
|
free(keys_file_path);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,7 +316,11 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (mono_time == 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);
|
logger_kill(logger);
|
||||||
|
free(motd);
|
||||||
|
free(tcp_relay_ports);
|
||||||
|
free(keys_file_path);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,64 +331,106 @@ int main(int argc, char *argv[])
|
||||||
if (dht == nullptr) {
|
if (dht == nullptr) {
|
||||||
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n");
|
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n");
|
||||||
mono_time_free(mono_time);
|
mono_time_free(mono_time);
|
||||||
|
kill_networking(net);
|
||||||
logger_kill(logger);
|
logger_kill(logger);
|
||||||
|
free(motd);
|
||||||
|
free(tcp_relay_ports);
|
||||||
|
free(keys_file_path);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Onion *onion = new_onion(mono_time, dht);
|
Onion *onion = new_onion(mono_time, dht);
|
||||||
|
|
||||||
|
if (!onion) {
|
||||||
|
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n");
|
||||||
|
kill_dht(dht);
|
||||||
|
mono_time_free(mono_time);
|
||||||
|
kill_networking(net);
|
||||||
|
logger_kill(logger);
|
||||||
|
free(motd);
|
||||||
|
free(tcp_relay_ports);
|
||||||
|
free(keys_file_path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
Onion_Announce *onion_a = new_onion_announce(mono_time, dht);
|
Onion_Announce *onion_a = new_onion_announce(mono_time, dht);
|
||||||
|
|
||||||
if (!(onion && onion_a)) {
|
if (!onion_a) {
|
||||||
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n");
|
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion Announce. Exiting.\n");
|
||||||
|
kill_onion(onion);
|
||||||
|
kill_dht(dht);
|
||||||
mono_time_free(mono_time);
|
mono_time_free(mono_time);
|
||||||
|
kill_networking(net);
|
||||||
logger_kill(logger);
|
logger_kill(logger);
|
||||||
|
free(motd);
|
||||||
|
free(tcp_relay_ports);
|
||||||
|
free(keys_file_path);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enable_motd) {
|
if (enable_motd) {
|
||||||
if (bootstrap_set_callbacks(dht_get_net(dht), DAEMON_VERSION_NUMBER, (uint8_t *)motd, strlen(motd) + 1) == 0) {
|
if (bootstrap_set_callbacks(dht_get_net(dht), DAEMON_VERSION_NUMBER, (uint8_t *)motd, strlen(motd) + 1) == 0) {
|
||||||
log_write(LOG_LEVEL_INFO, "Set MOTD successfully.\n");
|
log_write(LOG_LEVEL_INFO, "Set MOTD successfully.\n");
|
||||||
|
free(motd);
|
||||||
} else {
|
} 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_onion(onion);
|
||||||
|
kill_dht(dht);
|
||||||
mono_time_free(mono_time);
|
mono_time_free(mono_time);
|
||||||
|
kill_networking(net);
|
||||||
logger_kill(logger);
|
logger_kill(logger);
|
||||||
|
free(motd);
|
||||||
|
free(tcp_relay_ports);
|
||||||
|
free(keys_file_path);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(motd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (manage_keys(dht, keys_file_path)) {
|
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 {
|
} 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_onion(onion);
|
||||||
|
kill_dht(dht);
|
||||||
mono_time_free(mono_time);
|
mono_time_free(mono_time);
|
||||||
|
kill_networking(net);
|
||||||
logger_kill(logger);
|
logger_kill(logger);
|
||||||
|
free(tcp_relay_ports);
|
||||||
|
free(keys_file_path);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(keys_file_path);
|
|
||||||
|
|
||||||
TCP_Server *tcp_server = nullptr;
|
TCP_Server *tcp_server = nullptr;
|
||||||
|
|
||||||
if (enable_tcp_relay) {
|
if (enable_tcp_relay) {
|
||||||
if (tcp_relay_port_count == 0) {
|
if (tcp_relay_port_count == 0) {
|
||||||
log_write(LOG_LEVEL_ERROR, "No TCP relay ports read. Exiting.\n");
|
log_write(LOG_LEVEL_ERROR, "No TCP relay ports read. Exiting.\n");
|
||||||
|
kill_onion_announce(onion_a);
|
||||||
|
kill_onion(onion);
|
||||||
|
kill_dht(dht);
|
||||||
mono_time_free(mono_time);
|
mono_time_free(mono_time);
|
||||||
|
kill_networking(net);
|
||||||
logger_kill(logger);
|
logger_kill(logger);
|
||||||
|
free(tcp_relay_ports);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tcp_server = new_TCP_server(enable_ipv6, tcp_relay_port_count, tcp_relay_ports, dht_get_self_secret_key(dht), onion);
|
tcp_server = new_TCP_server(enable_ipv6, tcp_relay_port_count, tcp_relay_ports, dht_get_self_secret_key(dht), onion);
|
||||||
|
|
||||||
// tcp_relay_port_count != 0 at this point
|
|
||||||
free(tcp_relay_ports);
|
free(tcp_relay_ports);
|
||||||
|
|
||||||
if (tcp_server != nullptr) {
|
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");
|
||||||
} else {
|
} 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_onion(onion);
|
||||||
|
kill_dht(dht);
|
||||||
mono_time_free(mono_time);
|
mono_time_free(mono_time);
|
||||||
|
kill_networking(net);
|
||||||
logger_kill(logger);
|
logger_kill(logger);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -375,7 +440,12 @@ int main(int argc, char *argv[])
|
||||||
log_write(LOG_LEVEL_INFO, "List of bootstrap nodes read successfully.\n");
|
log_write(LOG_LEVEL_INFO, "List of bootstrap nodes read successfully.\n");
|
||||||
} else {
|
} else {
|
||||||
log_write(LOG_LEVEL_ERROR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path);
|
log_write(LOG_LEVEL_ERROR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path);
|
||||||
|
kill_TCP_server(tcp_server);
|
||||||
|
kill_onion_announce(onion_a);
|
||||||
|
kill_onion(onion);
|
||||||
|
kill_dht(dht);
|
||||||
mono_time_free(mono_time);
|
mono_time_free(mono_time);
|
||||||
|
kill_networking(net);
|
||||||
logger_kill(logger);
|
logger_kill(logger);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -392,7 +462,25 @@ int main(int argc, char *argv[])
|
||||||
log_write(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n");
|
log_write(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
struct sigaction sa;
|
||||||
|
|
||||||
|
sa.sa_handler = handle_signal;
|
||||||
|
|
||||||
|
// Try to restart interrupted system calls if they are restartable
|
||||||
|
sa.sa_flags = SA_RESTART;
|
||||||
|
|
||||||
|
// Prevent the signal handler from being called again before it returns
|
||||||
|
sigfillset(&sa.sa_mask);
|
||||||
|
|
||||||
|
if (sigaction(SIGINT, &sa, nullptr)) {
|
||||||
|
log_write(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGINT. Continuing without the signal handler set.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sigaction(SIGTERM, &sa, nullptr)) {
|
||||||
|
log_write(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGTERM. Continuing without the signal handler set.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!caught_signal) {
|
||||||
mono_time_update(mono_time);
|
mono_time_update(mono_time);
|
||||||
|
|
||||||
do_dht(dht);
|
do_dht(dht);
|
||||||
|
@ -415,4 +503,31 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
SLEEP_MILLISECONDS(30);
|
SLEEP_MILLISECONDS(30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (caught_signal) {
|
||||||
|
case 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);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
log_write(LOG_LEVEL_INFO, "Received (%d) signal. Exiting.\n", caught_signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enable_lan_discovery) {
|
||||||
|
lan_discovery_kill(dht);
|
||||||
|
}
|
||||||
|
|
||||||
|
kill_TCP_server(tcp_server);
|
||||||
|
kill_onion_announce(onion_a);
|
||||||
|
kill_onion(onion);
|
||||||
|
kill_dht(dht);
|
||||||
|
mono_time_free(mono_time);
|
||||||
|
kill_networking(net);
|
||||||
|
logger_kill(logger);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user