summaryrefslogtreecommitdiff
path: root/src/core/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/main.c')
-rw-r--r--src/core/main.c220
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;
+}