TurnServer::~TurnServer() { restund_tcp_close(turnd); mem_deref(turnd); mem_deref(us); }
int main(int argc, char *argv[]) { bool daemon = true; int err = 0; struct pl opt; (void)sys_coredump_set(true); #ifdef HAVE_GETOPT for (;;) { const int c = getopt(argc, argv, "dhnf:"); if (0 > c) break; switch (c) { case 'd': force_debug = true; restund_log_enable_debug(true); break; case 'f': configfile = optarg; break; case 'n': daemon = false; break; case '?': err = EINVAL; /*@fallthrough@*/ case 'h': usage(); return err; } } #else (void)argc; (void)argv; #endif restund_cmd_subscribe(&cmd_reload); err = fd_setsize(4096); if (err) { restund_warning("fd_setsize error: %m\n", err); goto out; } err = libre_init(); if (err) { restund_error("re init failed: %m\n", err); goto out; } /* configuration file */ err = conf_alloc(&conf, configfile); if (err) { restund_error("error loading configuration: %s: %m\n", configfile, err); goto out; } /* debug config */ if (!conf_get(conf, "debug", &opt) && !pl_strcasecmp(&opt, "yes")) restund_log_enable_debug(true); /* udp */ err = restund_udp_init(); if (err) goto out; /* tcp */ err = restund_tcp_init(); if (err) goto out; /* daemon config */ if (!conf_get(conf, "daemon", &opt) && !pl_strcasecmp(&opt, "no")) daemon = false; /* module config */ if (conf_get(conf, "module_path", &opt)) pl_set_str(&opt, "."); err = conf_apply(conf, "module", module_handler, &opt); if (err) goto out; /* daemon */ if (daemon) { err = sys_daemon(); if (err) { restund_error("daemon error: %m\n", err); goto out; } restund_log_enable_stderr(false); } /* database */ err = restund_db_init(); if (err) { restund_warning("database error: %m\n", err); goto out; } restund_info("stun server ready\n"); /* main loop */ err = re_main(signal_handler); out: restund_db_close(); mod_close(); restund_udp_close(); restund_tcp_close(); conf = mem_deref(conf); libre_close(); restund_cmd_unsubscribe(&cmd_reload); /* check for memory leaks */ tmr_debug(); mem_debug(); return err; }