summaryrefslogtreecommitdiff
path: root/other
diff options
context:
space:
mode:
authorMaxim Biro <nurupo.contributions@gmail.com>2018-10-04 01:30:03 -0400
committerMaxim Biro <nurupo.contributions@gmail.com>2018-10-16 21:35:27 -0400
commit1cbc9609a7390cea06bfdd3b6558dfd8c72a56ae (patch)
treed62ed9668dbebe40b9e7ff29744774b927ca64c5 /other
parent700accb3c78eb919d9c05eacad12cf3cbdb1a8a5 (diff)
Make tox-bootstrapd free memory on SIGINT and SIGTERM
Useful for using memory analyzing tools.
Diffstat (limited to 'other')
-rw-r--r--other/bootstrap_daemon/src/tox-bootstrapd.c137
1 files changed, 126 insertions, 11 deletions
diff --git a/other/bootstrap_daemon/src/tox-bootstrapd.c b/other/bootstrap_daemon/src/tox-bootstrapd.c
index c26ef54f..5dba9dcc 100644
--- a/other/bootstrap_daemon/src/tox-bootstrapd.c
+++ b/other/bootstrap_daemon/src/tox-bootstrapd.c
@@ -28,6 +28,7 @@
28 28
29// system provided 29// system provided
30#include <sys/stat.h> 30#include <sys/stat.h>
31#include <signal.h> // for POSIX sigaction(2)
31#include <unistd.h> 32#include <unistd.h>
32 33
33// C 34// C
@@ -214,6 +215,13 @@ static void toxcore_logger_callback(void *context, Logger_Level level, const cha
214 log_write(log_level, "%s:%d(%s) %s\n", file, line, func, message); 215 log_write(log_level, "%s:%d(%s) %s\n", file, line, func, message);
215} 216}
216 217
218static volatile sig_atomic_t caught_signal = 0;
219
220static void handle_signal(int signum)
221{
222 caught_signal = signum;
223}
224
217int main(int argc, char *argv[]) 225int main(int argc, char *argv[])
218{ 226{
219 umask(077); 227 umask(077);
@@ -232,16 +240,17 @@ int main(int argc, char *argv[])
232 240
233 log_write(LOG_LEVEL_INFO, "Running \"%s\" version %lu.\n", DAEMON_NAME, DAEMON_VERSION_NUMBER); 241 log_write(LOG_LEVEL_INFO, "Running \"%s\" version %lu.\n", DAEMON_NAME, DAEMON_VERSION_NUMBER);
234 242
235 char *pid_file_path, *keys_file_path; 243 char *pid_file_path = nullptr;
244 char *keys_file_path = nullptr;
236 int port; 245 int port;
237 int enable_ipv6; 246 int enable_ipv6;
238 int enable_ipv4_fallback; 247 int enable_ipv4_fallback;
239 int enable_lan_discovery; 248 int enable_lan_discovery;
240 int enable_tcp_relay; 249 int enable_tcp_relay;
241 uint16_t *tcp_relay_ports; 250 uint16_t *tcp_relay_ports = nullptr;
242 int tcp_relay_port_count; 251 int tcp_relay_port_count;
243 int enable_motd; 252 int enable_motd;
244 char *motd; 253 char *motd = nullptr;
245 254
246 if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &port, &enable_ipv6, &enable_ipv4_fallback, 255 if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &port, &enable_ipv6, &enable_ipv4_fallback,
247 &enable_lan_discovery, &enable_tcp_relay, &tcp_relay_ports, &tcp_relay_port_count, &enable_motd, &motd)) { 256 &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[])
254 if (port < MIN_ALLOWED_PORT || port > MAX_ALLOWED_PORT) { 263 if (port < MIN_ALLOWED_PORT || port > MAX_ALLOWED_PORT) {
255 log_write(LOG_LEVEL_ERROR, "Invalid port: %d, should be in [%d, %d]. Exiting.\n", port, MIN_ALLOWED_PORT, 264 log_write(LOG_LEVEL_ERROR, "Invalid port: %d, should be in [%d, %d]. Exiting.\n", port, MIN_ALLOWED_PORT,
256 MAX_ALLOWED_PORT); 265 MAX_ALLOWED_PORT);
266 free(motd);
267 free(tcp_relay_ports);
268 free(keys_file_path);
269 free(pid_file_path);
257 return 1; 270 return 1;
258 } 271 }
259 272
@@ -284,11 +297,17 @@ int main(int argc, char *argv[])
284 if (net == nullptr) { 297 if (net == nullptr) {
285 log_write(LOG_LEVEL_ERROR, "Couldn't fallback to IPv4. Exiting.\n"); 298 log_write(LOG_LEVEL_ERROR, "Couldn't fallback to IPv4. Exiting.\n");
286 logger_kill(logger); 299 logger_kill(logger);
300 free(motd);
301 free(tcp_relay_ports);
302 free(keys_file_path);
287 return 1; 303 return 1;
288 } 304 }
289 } else { 305 } else {
290 log_write(LOG_LEVEL_ERROR, "Couldn't initialize networking. Exiting.\n"); 306 log_write(LOG_LEVEL_ERROR, "Couldn't initialize networking. Exiting.\n");
291 logger_kill(logger); 307 logger_kill(logger);
308 free(motd);
309 free(tcp_relay_ports);
310 free(keys_file_path);
292 return 1; 311 return 1;
293 } 312 }
294 } 313 }
@@ -297,7 +316,11 @@ int main(int argc, char *argv[])
297 316
298 if (mono_time == nullptr) { 317 if (mono_time == nullptr) {
299 log_write(LOG_LEVEL_ERROR, "Couldn't initialize monotonic timer. Exiting.\n"); 318 log_write(LOG_LEVEL_ERROR, "Couldn't initialize monotonic timer. Exiting.\n");
319 kill_networking(net);
300 logger_kill(logger); 320 logger_kill(logger);
321 free(motd);
322 free(tcp_relay_ports);
323 free(keys_file_path);
301 return 1; 324 return 1;
302 } 325 }
303 326
@@ -308,64 +331,106 @@ int main(int argc, char *argv[])
308 if (dht == nullptr) { 331 if (dht == nullptr) {
309 log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n"); 332 log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n");
310 mono_time_free(mono_time); 333 mono_time_free(mono_time);
334 kill_networking(net);
311 logger_kill(logger); 335 logger_kill(logger);
336 free(motd);
337 free(tcp_relay_ports);
338 free(keys_file_path);
312 return 1; 339 return 1;
313 } 340 }
314 341
315 Onion *onion = new_onion(mono_time, dht); 342 Onion *onion = new_onion(mono_time, dht);
316 Onion_Announce *onion_a = new_onion_announce(mono_time, dht);
317 343
318 if (!(onion && onion_a)) { 344 if (!onion) {
319 log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n"); 345 log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n");
346 kill_dht(dht);
320 mono_time_free(mono_time); 347 mono_time_free(mono_time);
348 kill_networking(net);
321 logger_kill(logger); 349 logger_kill(logger);
350 free(motd);
351 free(tcp_relay_ports);
352 free(keys_file_path);
353 return 1;
354 }
355
356 Onion_Announce *onion_a = new_onion_announce(mono_time, dht);
357
358 if (!onion_a) {
359 log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion Announce. Exiting.\n");
360 kill_onion(onion);
361 kill_dht(dht);
362 mono_time_free(mono_time);
363 kill_networking(net);
364 logger_kill(logger);
365 free(motd);
366 free(tcp_relay_ports);
367 free(keys_file_path);
322 return 1; 368 return 1;
323 } 369 }
324 370
325 if (enable_motd) { 371 if (enable_motd) {
326 if (bootstrap_set_callbacks(dht_get_net(dht), DAEMON_VERSION_NUMBER, (uint8_t *)motd, strlen(motd) + 1) == 0) { 372 if (bootstrap_set_callbacks(dht_get_net(dht), DAEMON_VERSION_NUMBER, (uint8_t *)motd, strlen(motd) + 1) == 0) {
327 log_write(LOG_LEVEL_INFO, "Set MOTD successfully.\n"); 373 log_write(LOG_LEVEL_INFO, "Set MOTD successfully.\n");
374 free(motd);
328 } else { 375 } else {
329 log_write(LOG_LEVEL_ERROR, "Couldn't set MOTD: %s. Exiting.\n", motd); 376 log_write(LOG_LEVEL_ERROR, "Couldn't set MOTD: %s. Exiting.\n", motd);
377 kill_onion_announce(onion_a);
378 kill_onion(onion);
379 kill_dht(dht);
330 mono_time_free(mono_time); 380 mono_time_free(mono_time);
381 kill_networking(net);
331 logger_kill(logger); 382 logger_kill(logger);
383 free(motd);
384 free(tcp_relay_ports);
385 free(keys_file_path);
332 return 1; 386 return 1;
333 } 387 }
334
335 free(motd);
336 } 388 }
337 389
338 if (manage_keys(dht, keys_file_path)) { 390 if (manage_keys(dht, keys_file_path)) {
339 log_write(LOG_LEVEL_INFO, "Keys are managed successfully.\n"); 391 log_write(LOG_LEVEL_INFO, "Keys are managed successfully.\n");
392 free(keys_file_path);
340 } else { 393 } else {
341 log_write(LOG_LEVEL_ERROR, "Couldn't read/write: %s. Exiting.\n", keys_file_path); 394 log_write(LOG_LEVEL_ERROR, "Couldn't read/write: %s. Exiting.\n", keys_file_path);
395 kill_onion_announce(onion_a);
396 kill_onion(onion);
397 kill_dht(dht);
342 mono_time_free(mono_time); 398 mono_time_free(mono_time);
399 kill_networking(net);
343 logger_kill(logger); 400 logger_kill(logger);
401 free(tcp_relay_ports);
402 free(keys_file_path);
344 return 1; 403 return 1;
345 } 404 }
346 405
347 free(keys_file_path);
348
349 TCP_Server *tcp_server = nullptr; 406 TCP_Server *tcp_server = nullptr;
350 407
351 if (enable_tcp_relay) { 408 if (enable_tcp_relay) {
352 if (tcp_relay_port_count == 0) { 409 if (tcp_relay_port_count == 0) {
353 log_write(LOG_LEVEL_ERROR, "No TCP relay ports read. Exiting.\n"); 410 log_write(LOG_LEVEL_ERROR, "No TCP relay ports read. Exiting.\n");
411 kill_onion_announce(onion_a);
412 kill_onion(onion);
413 kill_dht(dht);
354 mono_time_free(mono_time); 414 mono_time_free(mono_time);
415 kill_networking(net);
355 logger_kill(logger); 416 logger_kill(logger);
417 free(tcp_relay_ports);
356 return 1; 418 return 1;
357 } 419 }
358 420
359 tcp_server = new_TCP_server(enable_ipv6, tcp_relay_port_count, tcp_relay_ports, dht_get_self_secret_key(dht), onion); 421 tcp_server = new_TCP_server(enable_ipv6, tcp_relay_port_count, tcp_relay_ports, dht_get_self_secret_key(dht), onion);
360 422
361 // tcp_relay_port_count != 0 at this point
362 free(tcp_relay_ports); 423 free(tcp_relay_ports);
363 424
364 if (tcp_server != nullptr) { 425 if (tcp_server != nullptr) {
365 log_write(LOG_LEVEL_INFO, "Initialized Tox TCP server successfully.\n"); 426 log_write(LOG_LEVEL_INFO, "Initialized Tox TCP server successfully.\n");
366 } else { 427 } else {
367 log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox TCP server. Exiting.\n"); 428 log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox TCP server. Exiting.\n");
429 kill_onion_announce(onion_a);
430 kill_onion(onion);
431 kill_dht(dht);
368 mono_time_free(mono_time); 432 mono_time_free(mono_time);
433 kill_networking(net);
369 logger_kill(logger); 434 logger_kill(logger);
370 return 1; 435 return 1;
371 } 436 }
@@ -375,7 +440,12 @@ int main(int argc, char *argv[])
375 log_write(LOG_LEVEL_INFO, "List of bootstrap nodes read successfully.\n"); 440 log_write(LOG_LEVEL_INFO, "List of bootstrap nodes read successfully.\n");
376 } else { 441 } else {
377 log_write(LOG_LEVEL_ERROR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path); 442 log_write(LOG_LEVEL_ERROR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path);
443 kill_TCP_server(tcp_server);
444 kill_onion_announce(onion_a);
445 kill_onion(onion);
446 kill_dht(dht);
378 mono_time_free(mono_time); 447 mono_time_free(mono_time);
448 kill_networking(net);
379 logger_kill(logger); 449 logger_kill(logger);
380 return 1; 450 return 1;
381 } 451 }
@@ -392,7 +462,25 @@ int main(int argc, char *argv[])
392 log_write(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n"); 462 log_write(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n");
393 } 463 }
394 464
395 while (1) { 465 struct sigaction sa;
466
467 sa.sa_handler = handle_signal;
468
469 // Try to restart interrupted system calls if they are restartable
470 sa.sa_flags = SA_RESTART;
471
472 // Prevent the signal handler from being called again before it returns
473 sigfillset(&sa.sa_mask);
474
475 if (sigaction(SIGINT, &sa, nullptr)) {
476 log_write(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGINT. Continuing without the signal handler set.\n");
477 }
478
479 if (sigaction(SIGTERM, &sa, nullptr)) {
480 log_write(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGTERM. Continuing without the signal handler set.\n");
481 }
482
483 while (!caught_signal) {
396 mono_time_update(mono_time); 484 mono_time_update(mono_time);
397 485
398 do_dht(dht); 486 do_dht(dht);
@@ -415,4 +503,31 @@ int main(int argc, char *argv[])
415 503
416 SLEEP_MILLISECONDS(30); 504 SLEEP_MILLISECONDS(30);
417 } 505 }
506
507 switch (caught_signal) {
508 case SIGINT:
509 log_write(LOG_LEVEL_INFO, "Received SIGINT (%d) signal. Exiting.\n", SIGINT);
510 break;
511
512 case SIGTERM:
513 log_write(LOG_LEVEL_INFO, "Received SIGTERM (%d) signal. Exiting.\n", SIGTERM);
514 break;
515
516 default:
517 log_write(LOG_LEVEL_INFO, "Received (%d) signal. Exiting.\n", caught_signal);
518 }
519
520 if (enable_lan_discovery) {
521 lan_discovery_kill(dht);
522 }
523
524 kill_TCP_server(tcp_server);
525 kill_onion_announce(onion_a);
526 kill_onion(onion);
527 kill_dht(dht);
528 mono_time_free(mono_time);
529 kill_networking(net);
530 logger_kill(logger);
531
532 return 0;
418} 533}