--- lbbs/src/net_server.c 2025/06/07 08:33:08 1.57 +++ lbbs/src/net_server.c 2025/06/29 03:32:39 1.70 @@ -14,38 +14,39 @@ * * ***************************************************************************/ -#define _XOPEN_SOURCE 500 -#define _POSIX_C_SOURCE 200809L -#define _GNU_SOURCE - -#include "net_server.h" -#include "common.h" -#include "bbs_main.h" #include "bbs.h" -#include "log.h" +#include "bbs_main.h" +#include "common.h" +#include "database.h" +#include "file_loader.h" #include "io.h" #include "init.h" -#include "menu.h" -#include "database.h" +#include "log.h" #include "login.h" -#include "file_loader.h" +#include "menu.h" +#include "net_server.h" +#include "section_list.h" #include "section_list_loader.h" #include #include -#include #include #include +#include #include -#include -#include -#include -#include #include -#include -#include +#include #include #include -#include +#include +#include +#include +#include +#include +#include +#include + +#define WAIT_CHILD_PROCESS_EXIT_TIMEOUT 5 // second +#define WAIT_CHILD_PROCESS_KILL_TIMEOUT 1 // second struct process_sockaddr_t { @@ -56,7 +57,7 @@ typedef struct process_sockaddr_t PROCES static PROCESS_SOCKADDR process_sockaddr_pool[MAX_CLIENT_LIMIT]; -#define SSH_AUTH_MAX_DURATION 60 // seconds +#define SSH_AUTH_MAX_DURATION (60 * 1000) // milliseconds struct ssl_server_cb_data_t { @@ -185,9 +186,9 @@ static int fork_server(void) event = ssh_event_new(); ssh_event_add_session(event, SSH_session); - for (i = 0; i < SSH_AUTH_MAX_DURATION && !SYS_server_exit && !cb_data.error && SSH_channel == NULL; i++) + for (i = 0; i < SSH_AUTH_MAX_DURATION && !SYS_server_exit && !cb_data.error && SSH_channel == NULL; i += 100) { - ret = ssh_event_dopoll(event, 1000); // 1 second + ret = ssh_event_dopoll(event, 100); // 0.1 second if (ret == SSH_ERROR) { log_error("ssh_event_dopoll() error: %s\n", ssh_get_error(SSH_session)); @@ -260,8 +261,10 @@ int net_server(const char *hostaddr, in_ struct epoll_event ev, events[MAX_EVENTS]; int nfds, epollfd; siginfo_t siginfo; + int notify_child_exit = 0; + time_t tm_notify_child_exit = time(NULL); int sd_notify_stopping = 0; - MENU_SET *p_bbs_menu_new; + MENU_SET bbs_menu_new; int i, j; pid_t pid; int ssh_log_level = SSH_LOG_NOLOG; @@ -273,6 +276,7 @@ int net_server(const char *hostaddr, in_ if (ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, hostaddr) < 0 || ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT, &port) < 0 || ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, SSH_HOST_KEYFILE) < 0 || + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY_ALGORITHMS, "ssh-rsa,rsa-sha2-512,rsa-sha2-256") < 0 || ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY, &ssh_log_level) < 0) { log_error("Error setting SSH bind options: %s\n", ssh_get_error(sshbind)); @@ -401,13 +405,43 @@ int net_server(const char *hostaddr, in_ if (SYS_server_exit && !SYS_child_exit && SYS_child_process_count > 0) { - log_common("Notify %d child process to exit\n", SYS_child_process_count); - if (kill(0, SIGTERM) < 0) + if (notify_child_exit == 0) { - log_error("Send SIGTERM signal failed (%d)\n", errno); + sd_notifyf(0, "STATUS=Notify %d child process to exit", SYS_child_process_count); + log_common("Notify %d child process to exit\n", SYS_child_process_count); + + if (kill(0, SIGTERM) < 0) + { + log_error("Send SIGTERM signal failed (%d)\n", errno); + } + + notify_child_exit = 1; + tm_notify_child_exit = time(NULL); } + else if (notify_child_exit == 1 && time(NULL) - tm_notify_child_exit >= WAIT_CHILD_PROCESS_EXIT_TIMEOUT) + { + sd_notifyf(0, "STATUS=Kill %d child process", SYS_child_process_count); - sd_notifyf(0, "STATUS=Waiting for %d child process to exit", SYS_child_process_count); + for (i = 0; i < BBS_max_client; i++) + { + if (process_sockaddr_pool[i].pid != 0) + { + log_error("Kill child process (pid=%d)\n", process_sockaddr_pool[i].pid); + if (kill(process_sockaddr_pool[i].pid, SIGKILL) < 0) + { + log_error("Send SIGKILL signal failed (%d)\n", errno); + } + } + } + + notify_child_exit = 2; + tm_notify_child_exit = time(NULL); + } + else if (notify_child_exit == 2 && time(NULL) - tm_notify_child_exit >= WAIT_CHILD_PROCESS_KILL_TIMEOUT) + { + log_error("Main process prepare to exit without waiting for %d child process any longer\n", SYS_child_process_count); + SYS_child_process_count = 0; + } } if (SYS_conf_reload && !SYS_server_exit) @@ -421,38 +455,18 @@ int net_server(const char *hostaddr, in_ log_error("Reload conf failed\n"); } - p_bbs_menu_new = calloc(1, sizeof(MENU_SET)); - if (p_bbs_menu_new == NULL) + if (load_menu(&bbs_menu_new, CONF_MENU) < 0) { - log_error("OOM: calloc(MENU_SET)\n"); - } - else if (load_menu(p_bbs_menu_new, CONF_MENU) < 0) - { - unload_menu(p_bbs_menu_new); - free(p_bbs_menu_new); - p_bbs_menu_new = NULL; - + unload_menu(&bbs_menu_new); log_error("Reload menu failed\n"); } else { - unload_menu(p_bbs_menu); - free(p_bbs_menu); - - p_bbs_menu = p_bbs_menu_new; - p_bbs_menu_new = NULL; - + unload_menu(&bbs_menu); + memcpy(&bbs_menu, &bbs_menu_new, sizeof(bbs_menu_new)); log_common("Reload menu successfully\n"); } - sd_notify(0, "READY=1"); - } - - if (SYS_data_file_reload && !SYS_server_exit) - { - SYS_data_file_reload = 0; - sd_notify(0, "RELOADING=1"); - for (int i = 0; i < data_files_load_startup_count; i++) { if (load_file(data_files_load_startup[i]) < 0) @@ -460,19 +474,19 @@ int net_server(const char *hostaddr, in_ log_error("load_file_mmap(%s) error\n", data_files_load_startup[i]); } } - log_common("Reload data files successfully\n"); - sd_notify(0, "READY=1"); - } - - if (SYS_section_list_reload && !SYS_server_exit) - { - SYS_section_list_reload = 0; - if (section_list_loader_reload() < 0) + // Load section config and gen_ex + if (load_section_config_from_db(1) < 0) + { + log_error("load_section_config_from_db(1) error\n"); + } + else { - log_error("ksection_list_loader_reload() failed\n"); + log_common("Reload section config and gen_ex successfully\n"); } + + sd_notify(0, "READY=1"); } nfds = epoll_wait(epollfd, events, MAX_EVENTS, 100); // 0.1 second @@ -525,7 +539,7 @@ int net_server(const char *hostaddr, in_ port_client = ntohs(sin.sin_port); - log_common("Accept %sconnection from %s:%d\n", (SSH_v2 ? "" : "SSH2 "), hostaddr_client, port_client); + log_common("Accept %s connection from %s:%d\n", (SSH_v2 ? "SSH" : "telnet"), hostaddr_client, port_client); if (SYS_child_process_count - 1 < BBS_max_client) {