/* BSD-2-Clause license * * Copyright (c) 2018-2023 NST , sss . * */ #include #include #include #include #include #include #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); }