diff options
author | Maxim Biro <nurupo.contributions@gmail.com> | 2018-10-04 01:30:03 -0400 |
---|---|---|
committer | Maxim Biro <nurupo.contributions@gmail.com> | 2018-10-16 21:35:27 -0400 |
commit | 1cbc9609a7390cea06bfdd3b6558dfd8c72a56ae (patch) | |
tree | d62ed9668dbebe40b9e7ff29744774b927ca64c5 /other/bootstrap_daemon/src | |
parent | 700accb3c78eb919d9c05eacad12cf3cbdb1a8a5 (diff) |
Make tox-bootstrapd free memory on SIGINT and SIGTERM
Useful for using memory analyzing tools.
Diffstat (limited to 'other/bootstrap_daemon/src')
-rw-r--r-- | other/bootstrap_daemon/src/tox-bootstrapd.c | 137 |
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 | ||
218 | static volatile sig_atomic_t caught_signal = 0; | ||
219 | |||
220 | static void handle_signal(int signum) | ||
221 | { | ||
222 | caught_signal = signum; | ||
223 | } | ||
224 | |||
217 | int main(int argc, char *argv[]) | 225 | int 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 | } |