diff options
author | sss <sss@dark-alexandr.net> | 2023-01-17 00:38:19 +0300 |
---|---|---|
committer | sss <sss@dark-alexandr.net> | 2023-01-17 00:38:19 +0300 |
commit | cc3f33db7a8d3c4ad373e646b199808e01bc5d9b (patch) | |
tree | ec09d690c7656ab5f2cc72607e05fb359c24d8b2 /src/core/main.c |
added webrdp public code
Diffstat (limited to 'src/core/main.c')
-rw-r--r-- | src/core/main.c | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/src/core/main.c b/src/core/main.c new file mode 100644 index 0000000..6572938 --- /dev/null +++ b/src/core/main.c @@ -0,0 +1,220 @@ +/* BSD-2-Clause license + * + * Copyright (c) 2018-2023 NST <www.newinfosec.ru>, sss <sss at dark-alexandr dot net>. + * + */ + +#include <limits.h> +#include <stdbool.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> +#include <ev.h> + +#include <stdio.h> +#include <execinfo.h> +#include <libunwind.h> + +#include "cmdline.h" +#include "config_file.h" +#include "ev_loop.h" +#include "exports.h" +#include "globals.h" +#include "thread_impl.h" +#include "utilities.h" +#include "wrdp_thpool.h" +#include "ws_session.h" +#include "remote_control.h" +#include "curl_helpers.h" +#include "thread_sync.h" + +globals g_globals; + +static void +custom_thread_init(void *user_pool_data, wrdp_thpool_thread *t) +{ + per_thread_curl_init(user_pool_data, t); +} + +static void +init_internals() +{ + if (g_globals.settings.thread_count <= 0) + { + g_globals.settings.thread_count = sysconf(_SC_NPROCESSORS_ONLN); + } + if (g_globals.settings.thread_count <= 0) + { + g_globals.settings.thread_count = 2; + } + if (!init_exports()) + { + printf("error: failed to initialize core exports\n"); + exit(EXIT_FAILURE); + } + /* random seed */ + srand(time(0) + 13); + + LIST_INIT(&(g_globals.backends_head)); + + void *c = init_curl_global(); + g_globals.thpool = wrdp_thpool_create(g_globals.settings.thread_count, + g_globals.settings.tasks_per_thread, custom_thread_init, 0, 0, 0, + pool_message_handler, thread_message_handler, EV_DEFAULT, c); +} + +static void +settings_load_default() +{ + memset(&g_globals, 0, sizeof(globals)); + memset(&g_globals.settings, 0, sizeof(global_settings)); + g_globals.settings.secret_key_verify[0] = 0; + g_globals.settings.secret_key_sign[0] = 0; + g_globals.settings.thread_count = -1; +} + +static void +settings_validate() +{ + bool failure = false; + if (!g_globals.settings.ws_port) + g_globals.settings.ws_port = 8080; + if (!g_globals.settings.ctl_port) + g_globals.settings.ctl_port = 13666; + if (!g_globals.settings.tasks_per_thread) + g_globals.settings.tasks_per_thread = 1024; + if (!g_globals.settings.secret_key_verify[0]) + { + printf("\"secret_key_verify\" must be set\n"); + failure = true; + } + if (!g_globals.settings.secret_key_sign[0]) + { + strcpy(g_globals.settings.secret_key_sign, + g_globals.settings.secret_key_verify); + } + if (!g_globals.settings.ctl_ssl_cert) + { + printf("\"ctl_ssl_cert\" must be set\n"); + failure = true; + } + if (!g_globals.settings.ctl_ssl_key) + { + printf("\"ctl_ssl_key\" must be set\n"); + failure = true; + } + if (failure) + { + exit(EXIT_FAILURE); + } +} + +void +shutdown_core() +{ + free(g_globals.exports); +} + +static void +daemonize() +{ + pid_t p = fork(); + if (p) + { + printf("child process forked, exiting parent\n"); + exit(EXIT_SUCCESS); + } + /* TODO: */ +} + +/* https://stackoverflow.com/questions/77005/how-to-automatically + * -generate-a-stacktrace-when-my-program-crashes */ +/*static void +sigsegv_handler(int sig) { + void *array[100]; + size_t size; + + // get void*'s for all entries on the stack + size = backtrace (array, 100); + + // print out all the frames to stderr + fprintf(stderr, "Error: signal %d:\n", sig); + backtrace_symbols_fd (array, size, STDERR_FILENO); + exit (EXIT_FAILURE); +} */ + +#ifdef DEBUG +/* https://github.com/cslarsen/libunwind-examples/blob/master/backtrace.cpp */ +static void +sigsegv_handler(int sig) +{ + unw_cursor_t cursor; + unw_context_t context; + + unw_getcontext(&context); + unw_init_local(&cursor, &context); + + int n = 0; + while (unw_step(&cursor) > 0) + { + unw_word_t ip, sp, off; + + unw_get_reg(&cursor, UNW_REG_IP, &ip); + unw_get_reg(&cursor, UNW_REG_SP, &sp); + + char symbol[256] = {"<unknown>"}; + char *name = symbol; + + unw_get_proc_name(&cursor, symbol, sizeof(symbol), &off); + + printf("#%-2d 0x%016" PRIxPTR " sp=0x%016" PRIxPTR + " %s + 0x%" PRIxPTR "\n", + ++n, ip, sp, name, off); + + if (name != symbol) + free(name); + } + exit(EXIT_FAILURE); +} + +/* this is required to generate gprof profile */ +static void +sigusr2_handler(int sif) +{ + exit(EXIT_SUCCESS); +} + +#endif + +int +main(int argc, char **argv) +{ +#ifdef DEBUG + signal(SIGSEGV, sigsegv_handler); + signal(SIGUSR2, sigusr2_handler); +#endif + settings_load_default(); + handle_cmdline_args(argc, argv); + if (g_globals.settings.daemon) + { + daemonize(); + } + settings_validate(); + + init_internals(); + + { + int ws_tcp_sock = ws_server_init(); + int ws_unix_sock = ws_server_init_unix(); + int ctl_server_tcp_sock = ctl_server_init_tcp(); + int ctl_server_unix_sock = ctl_server_init_unix(); + + //init_remote_control(); + + run_ev_loop_main(ws_tcp_sock, ws_unix_sock, ctl_server_tcp_sock, + ctl_server_unix_sock); + } + + shutdown_core(); + return 0; +} |