diff options
Diffstat (limited to 'src/core/ev_loop.c')
-rw-r--r-- | src/core/ev_loop.c | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/src/core/ev_loop.c b/src/core/ev_loop.c new file mode 100644 index 0000000..e084e81 --- /dev/null +++ b/src/core/ev_loop.c @@ -0,0 +1,206 @@ +/* BSD-2-Clause license + * + * Copyright (c) 2018-2023 NST <www.newinfosec.ru>, sss <sss at dark-alexandr dot net>. + * + */ + +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <ev.h> + +#include <webrdp_module_api.h> + +#include "globals.h" +#include "remote_control.h" +#include "thread_impl.h" +#include "wrdp_thpool.h" +#include "wrdp_thpool_internals.h" +#include "ws_session.h" +#include "socket_helpers.h" +#include "task.h" +#include "remote_control.h" + +#include "log.h" + +static ws_session * +ws_create_session(int connection_fd) +{ + ws_session *session = 0; + task_info *info = 0; + session = calloc(1, sizeof(ws_session)); + if (!session) + { + perror("calloc"); + goto error; + } + info = calloc(1, sizeof(task_info)); + if (!info) + { + perror("calloc"); + goto error; + } + session->task_info = info; + session->session_state = ws_session_initial; + session->connection_fd = connection_fd; + SLIST_INIT(&(session->backend_settings_head)); + return session; +error: + if (session) + { + if (session->task_info) + { + free(session->task_info); + } + free(session); + } + return 0; +} + +static void +ws_server_cb(EV_P_ ev_io *w, int revents) +{ + int *sock = w->data; + int con = accept_new_connection(*sock); + if (con != -1) + { + ws_session *session = 0; + { + const char *msg = "accepting new ws connection"; + log_msg((const uint8_t *)msg, strlen(msg), + wrdp_log_level_trace, 0); + } + session = ws_create_session(con); + if (!session) + { + close(con); + return; + } + if (!wrdp_thread_pool_add_task(g_globals.thpool, ws_run_session, + ws_session_init_cb, session)) + { + const char *msg + = "Failed to move task to pool: pool is full"; + log_msg((const uint8_t *)msg, strlen(msg), + wrdp_log_level_error, 0); + return; + } + } +} + +static void +ctl_server_cb(EV_P_ ev_io *w, int revents) +{ + int *sock = w->data; + int con = accept_new_connection(*sock); + if (con != -1) + { + const char *msg = "accepting new ctl connection"; + log_msg( + (const uint8_t *)msg, strlen(msg), wrdp_log_level_trace, 0); + ctl_task_info *info = ctl_create_task(con); + if (!info) + { + close(con); + return; + } + if (!wrdp_thread_pool_add_task( + g_globals.thpool, ctl_run_task, 0, info)) + { + const char *msg + = "Failed to move task to pool: pool is full"; + log_msg((const uint8_t *)msg, strlen(msg), + wrdp_log_level_error, 0); + return; + } + /* TODO: */ + } +} + +void +run_ev_loop_main(int ws_tcp_sock, int ws_unix_sock, int ctl_server_sock_tcp, + int ctl_server_sock_unix) +{ + if (ws_tcp_sock == -1 && ws_unix_sock == -1) + { + const char *msg + = "ws: both tcp port and unix socket does not set"; + log_msg( + (const uint8_t *)msg, strlen(msg), wrdp_log_level_error, 0); + exit(EXIT_FAILURE); + } + if (ctl_server_sock_tcp == -1 && ctl_server_sock_unix == -1) + { + const char *msg + = "ctl: both tcp port and unix socket does not set"; + log_msg( + (const uint8_t *)msg, strlen(msg), wrdp_log_level_error, 0); + exit(EXIT_FAILURE); + } + struct ev_loop *ev_loop = EV_DEFAULT; + ev_io *ws_ev_sock_acceptor, *ws_ev_unix_acceptor, *ctl_ev_sock_acceptor, + *ctl_ev_unix_acceptor; + if (ws_tcp_sock != -1) + { + int *sock = calloc(1, sizeof(int)); + if (!sock) + { + perror("calloc"); + exit(EXIT_FAILURE); + } + ws_ev_sock_acceptor = calloc(1, sizeof(ev_io)); + *sock = ws_tcp_sock; + ev_io_init( + ws_ev_sock_acceptor, ws_server_cb, ws_tcp_sock, EV_READ); + ws_ev_sock_acceptor->data = sock; + ev_io_start(ev_loop, ws_ev_sock_acceptor); + } + if (ws_unix_sock != -1) + { + int *sock = calloc(1, sizeof(int)); + if (!sock) + { + perror("calloc"); + exit(EXIT_FAILURE); + } + ws_ev_unix_acceptor = calloc(1, sizeof(ev_io)); + *sock = ws_unix_sock; + ev_io_init( + ws_ev_unix_acceptor, ws_server_cb, ws_unix_sock, EV_READ); + ws_ev_unix_acceptor->data = sock; + ev_io_start(ev_loop, ws_ev_unix_acceptor); + } + if (ctl_server_sock_tcp != -1) + { + int *sock = calloc(1, sizeof(int)); + if (!sock) + { + perror("calloc"); + exit(EXIT_FAILURE); + } + ctl_ev_sock_acceptor = calloc(1, sizeof(ev_io)); + *sock = ctl_server_sock_tcp; + ev_io_init(ctl_ev_sock_acceptor, ctl_server_cb, + ctl_server_sock_tcp, EV_READ); + ctl_ev_sock_acceptor->data = sock; + ev_io_start(ev_loop, ctl_ev_sock_acceptor); + } + if (ctl_server_sock_unix != -1) + { + int *sock = calloc(1, sizeof(int)); + if (!sock) + { + perror("calloc"); + exit(EXIT_FAILURE); + } + ctl_ev_unix_acceptor = calloc(1, sizeof(ev_io)); + *sock = ctl_server_sock_unix; + ev_io_init(ctl_ev_unix_acceptor, ctl_server_cb, + ctl_server_sock_unix, EV_READ); + ctl_ev_unix_acceptor->data = sock; + ev_io_start(ev_loop, ctl_ev_unix_acceptor); + } + ev_run(ev_loop, 0); +} |