mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-06-26 04:34:38 +08:00
Centralize runtime config defaults
This commit is contained in:
parent
0da5f51e2e
commit
d4b260c160
15 changed files with 271 additions and 81 deletions
2
Makefile
2
Makefile
|
|
@ -26,7 +26,7 @@ OBJECTS = $(SOURCES:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
|
|||
DEPS = $(OBJECTS:.o=.d) $(CTL_OBJECTS:.o=.d)
|
||||
TARGET = tnt
|
||||
CTL_TARGET = tntctl
|
||||
CTL_OBJECTS = $(OBJ_DIR)/tntctl.o $(OBJ_DIR)/tntctl_text.o $(OBJ_DIR)/exec_catalog.o $(OBJ_DIR)/common.o $(OBJ_DIR)/i18n.o
|
||||
CTL_OBJECTS = $(OBJ_DIR)/tntctl.o $(OBJ_DIR)/tntctl_text.o $(OBJ_DIR)/exec_catalog.o $(OBJ_DIR)/common.o $(OBJ_DIR)/config_defaults.o $(OBJ_DIR)/i18n.o
|
||||
TARGETS = $(TARGET) $(CTL_TARGET)
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
`vX.Y.Z` tag must match `TNT_VERSION` before release assets are built.
|
||||
- Added `make package-publish-check` for verifying Arch/Homebrew source
|
||||
checksums against the final GitHub source archive after a tag exists.
|
||||
- Added a `config_defaults` module and unit coverage for runtime default
|
||||
values, env keys, and accepted numeric ranges.
|
||||
- Added a dedicated `tntctl_text` module with unit coverage for local
|
||||
`tntctl` help and validation diagnostics.
|
||||
- Documented the stable SSH exec interface contract, including exit statuses
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "config_defaults.h"
|
||||
|
||||
/* Project Metadata */
|
||||
#define TNT_VERSION "1.0.1"
|
||||
|
||||
|
|
@ -23,7 +25,6 @@
|
|||
#define TNT_EXIT_CONFIG 78
|
||||
|
||||
/* Configuration constants */
|
||||
#define DEFAULT_PORT 2222
|
||||
#define MAX_MESSAGES 100
|
||||
#define MAX_USERNAME_LEN 64
|
||||
#define MAX_MESSAGE_LEN 1024
|
||||
|
|
@ -31,13 +32,17 @@
|
|||
#define MAX_COMMAND_OUTPUT_LEN 8192
|
||||
#define CLIENT_OUTBOX_CAPACITY (128 * 1024)
|
||||
#define CLIENT_OUTBOX_FLUSH_BUDGET 32768
|
||||
#define DEFAULT_MAX_CLIENTS 64
|
||||
#define MAX_CONFIGURED_CLIENTS 1024
|
||||
#define LOG_FILE "messages.log"
|
||||
#define MAX_LOG_SIZE (10 * 1024 * 1024) /* 10 MiB */
|
||||
#define HOST_KEY_FILE "host_key"
|
||||
#define TNT_DEFAULT_STATE_DIR "."
|
||||
#define DEFAULT_IDLE_TIMEOUT 1800 /* 30 minutes */
|
||||
|
||||
/* Backward-compatible names for older modules while config_defaults owns the
|
||||
* actual runtime defaults and accepted ranges. */
|
||||
#define DEFAULT_PORT TNT_DEFAULT_PORT
|
||||
#define DEFAULT_MAX_CLIENTS TNT_DEFAULT_MAX_CONNECTIONS
|
||||
#define MAX_CONFIGURED_CLIENTS TNT_MAX_CONFIGURED_CLIENTS
|
||||
#define DEFAULT_IDLE_TIMEOUT TNT_DEFAULT_IDLE_TIMEOUT
|
||||
|
||||
/* ANSI color codes */
|
||||
#define ANSI_RESET "\033[0m"
|
||||
|
|
|
|||
47
include/config_defaults.h
Normal file
47
include/config_defaults.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef CONFIG_DEFAULTS_H
|
||||
#define CONFIG_DEFAULTS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define TNT_STRINGIFY_VALUE(value) #value
|
||||
#define TNT_STRINGIFY(value) TNT_STRINGIFY_VALUE(value)
|
||||
|
||||
#define TNT_DEFAULT_PORT 2222
|
||||
#define TNT_DEFAULT_PORT_TEXT TNT_STRINGIFY(TNT_DEFAULT_PORT)
|
||||
#define TNT_DEFAULT_MAX_CONNECTIONS 64
|
||||
#define TNT_DEFAULT_MAX_CONN_PER_IP 5
|
||||
#define TNT_DEFAULT_MAX_CONN_RATE_PER_IP 10
|
||||
#define TNT_DEFAULT_RATE_LIMIT_ENABLED 1
|
||||
#define TNT_DEFAULT_IDLE_TIMEOUT 1800
|
||||
|
||||
#define TNT_MIN_PORT 1
|
||||
#define TNT_MAX_PORT 65535
|
||||
#define TNT_MIN_CONFIGURED_CLIENTS 1
|
||||
#define TNT_MAX_CONFIGURED_CLIENTS 1024
|
||||
#define TNT_MIN_RATE_LIMIT_ENABLED 0
|
||||
#define TNT_MAX_RATE_LIMIT_ENABLED 1
|
||||
#define TNT_MIN_IDLE_TIMEOUT 0
|
||||
#define TNT_MAX_IDLE_TIMEOUT 86400
|
||||
#define TNT_MIN_SSH_LOG_LEVEL 0
|
||||
#define TNT_MAX_SSH_LOG_LEVEL 4
|
||||
|
||||
typedef struct {
|
||||
const char *env_name;
|
||||
int fallback;
|
||||
int min_value;
|
||||
int max_value;
|
||||
} tnt_int_config_spec_t;
|
||||
|
||||
extern const tnt_int_config_spec_t TNT_CONFIG_PORT;
|
||||
extern const tnt_int_config_spec_t TNT_CONFIG_MAX_CONNECTIONS;
|
||||
extern const tnt_int_config_spec_t TNT_CONFIG_MAX_CONN_PER_IP;
|
||||
extern const tnt_int_config_spec_t TNT_CONFIG_MAX_CONN_RATE_PER_IP;
|
||||
extern const tnt_int_config_spec_t TNT_CONFIG_RATE_LIMIT;
|
||||
extern const tnt_int_config_spec_t TNT_CONFIG_IDLE_TIMEOUT;
|
||||
extern const tnt_int_config_spec_t TNT_CONFIG_SSH_LOG_LEVEL;
|
||||
|
||||
int tnt_config_env_int(const tnt_int_config_spec_t *spec);
|
||||
bool tnt_config_parse_int(const char *value, const tnt_int_config_spec_t *spec,
|
||||
int *out);
|
||||
|
||||
#endif /* CONFIG_DEFAULTS_H */
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
#include "chat_room.h"
|
||||
#include "config_defaults.h"
|
||||
|
||||
/* Global chat room instance */
|
||||
chat_room_t *g_room = NULL;
|
||||
|
||||
static int room_capacity_from_env(void) {
|
||||
return env_int("TNT_MAX_CONNECTIONS", DEFAULT_MAX_CLIENTS, 1,
|
||||
MAX_CONFIGURED_CLIENTS);
|
||||
return tnt_config_env_int(&TNT_CONFIG_MAX_CONNECTIONS);
|
||||
}
|
||||
|
||||
/* Initialize chat room */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "cli_text.h"
|
||||
|
||||
#include "config_defaults.h"
|
||||
#include "i18n.h"
|
||||
|
||||
void cli_text_append_help(char *buffer, size_t buf_size, size_t *pos,
|
||||
|
|
@ -12,7 +13,7 @@ void cli_text_append_help(char *buffer, size_t buf_size, size_t *pos,
|
|||
" -d, --state-dir DIR Store host key and logs in DIR\n"
|
||||
" --bind ADDR Bind to ADDR (default: 0.0.0.0)\n"
|
||||
" --public-host HOST Show HOST in startup connection hints\n"
|
||||
" --max-connections N Global connection limit (default: 64)\n"
|
||||
" --max-connections N Global connection limit (default: %d)\n"
|
||||
" --max-conn-per-ip N Per-IP concurrent session limit\n"
|
||||
" --max-conn-rate-per-ip N Per-IP connection-rate limit\n"
|
||||
" --rate-limit 0|1 Disable/enable rate-based blocking\n"
|
||||
|
|
@ -28,9 +29,9 @@ void cli_text_append_help(char *buffer, size_t buf_size, size_t *pos,
|
|||
" TNT_STATE_DIR State directory\n"
|
||||
" TNT_ACCESS_TOKEN Require this password for SSH auth\n"
|
||||
" TNT_LANG UI language: en or zh (default: locale)\n"
|
||||
" TNT_MAX_CONNECTIONS Global connection limit (default: 64)\n"
|
||||
" TNT_MAX_CONNECTIONS Global connection limit (default: %d)\n"
|
||||
" TNT_RATE_LIMIT Set to 0 to disable rate limiting\n"
|
||||
" TNT_IDLE_TIMEOUT Idle disconnect timeout in seconds (default: 1800)\n",
|
||||
" TNT_IDLE_TIMEOUT Idle disconnect timeout in seconds (default: %d)\n",
|
||||
"tnt %s - 匿名 SSH 聊天服务器\n\n"
|
||||
"用法: %s [options]\n\n"
|
||||
"选项:\n"
|
||||
|
|
@ -38,7 +39,7 @@ void cli_text_append_help(char *buffer, size_t buf_size, size_t *pos,
|
|||
" -d, --state-dir DIR 将主机密钥和日志存放在 DIR\n"
|
||||
" --bind ADDR 绑定到 ADDR (默认: 0.0.0.0)\n"
|
||||
" --public-host HOST 在启动提示中显示 HOST\n"
|
||||
" --max-connections N 全局连接数限制 (默认: 64)\n"
|
||||
" --max-connections N 全局连接数限制 (默认: %d)\n"
|
||||
" --max-conn-per-ip N 单 IP 并发会话限制\n"
|
||||
" --max-conn-rate-per-ip N 单 IP 连接速率限制\n"
|
||||
" --rate-limit 0|1 禁用/启用速率封禁\n"
|
||||
|
|
@ -54,16 +55,19 @@ void cli_text_append_help(char *buffer, size_t buf_size, size_t *pos,
|
|||
" TNT_STATE_DIR 状态目录\n"
|
||||
" TNT_ACCESS_TOKEN 要求 SSH 认证使用此密码\n"
|
||||
" TNT_LANG UI 语言: en 或 zh (默认跟随 locale)\n"
|
||||
" TNT_MAX_CONNECTIONS 全局连接数限制 (默认: 64)\n"
|
||||
" TNT_MAX_CONNECTIONS 全局连接数限制 (默认: %d)\n"
|
||||
" TNT_RATE_LIMIT 设为 0 可禁用速率限制\n"
|
||||
" TNT_IDLE_TIMEOUT 空闲断开时间,单位秒 (默认: 1800)\n"
|
||||
" TNT_IDLE_TIMEOUT 空闲断开时间,单位秒 (默认: %d)\n"
|
||||
);
|
||||
const char *program = (program_name && program_name[0] != '\0')
|
||||
? program_name
|
||||
: "tnt";
|
||||
|
||||
buffer_appendf(buffer, buf_size, pos, i18n_string(help_format, lang),
|
||||
TNT_VERSION, program, DEFAULT_PORT);
|
||||
TNT_VERSION, program, TNT_DEFAULT_PORT,
|
||||
TNT_DEFAULT_MAX_CONNECTIONS,
|
||||
TNT_DEFAULT_MAX_CONNECTIONS,
|
||||
TNT_DEFAULT_IDLE_TIMEOUT);
|
||||
}
|
||||
|
||||
const char *cli_text_invalid_port_format(ui_lang_t lang) {
|
||||
|
|
|
|||
80
src/config_defaults.c
Normal file
80
src/config_defaults.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#include "config_defaults.h"
|
||||
#include "common.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
const tnt_int_config_spec_t TNT_CONFIG_PORT = {
|
||||
"PORT",
|
||||
TNT_DEFAULT_PORT,
|
||||
TNT_MIN_PORT,
|
||||
TNT_MAX_PORT,
|
||||
};
|
||||
|
||||
const tnt_int_config_spec_t TNT_CONFIG_MAX_CONNECTIONS = {
|
||||
"TNT_MAX_CONNECTIONS",
|
||||
TNT_DEFAULT_MAX_CONNECTIONS,
|
||||
TNT_MIN_CONFIGURED_CLIENTS,
|
||||
TNT_MAX_CONFIGURED_CLIENTS,
|
||||
};
|
||||
|
||||
const tnt_int_config_spec_t TNT_CONFIG_MAX_CONN_PER_IP = {
|
||||
"TNT_MAX_CONN_PER_IP",
|
||||
TNT_DEFAULT_MAX_CONN_PER_IP,
|
||||
TNT_MIN_CONFIGURED_CLIENTS,
|
||||
TNT_MAX_CONFIGURED_CLIENTS,
|
||||
};
|
||||
|
||||
const tnt_int_config_spec_t TNT_CONFIG_MAX_CONN_RATE_PER_IP = {
|
||||
"TNT_MAX_CONN_RATE_PER_IP",
|
||||
TNT_DEFAULT_MAX_CONN_RATE_PER_IP,
|
||||
TNT_MIN_CONFIGURED_CLIENTS,
|
||||
TNT_MAX_CONFIGURED_CLIENTS,
|
||||
};
|
||||
|
||||
const tnt_int_config_spec_t TNT_CONFIG_RATE_LIMIT = {
|
||||
"TNT_RATE_LIMIT",
|
||||
TNT_DEFAULT_RATE_LIMIT_ENABLED,
|
||||
TNT_MIN_RATE_LIMIT_ENABLED,
|
||||
TNT_MAX_RATE_LIMIT_ENABLED,
|
||||
};
|
||||
|
||||
const tnt_int_config_spec_t TNT_CONFIG_IDLE_TIMEOUT = {
|
||||
"TNT_IDLE_TIMEOUT",
|
||||
TNT_DEFAULT_IDLE_TIMEOUT,
|
||||
TNT_MIN_IDLE_TIMEOUT,
|
||||
TNT_MAX_IDLE_TIMEOUT,
|
||||
};
|
||||
|
||||
const tnt_int_config_spec_t TNT_CONFIG_SSH_LOG_LEVEL = {
|
||||
"TNT_SSH_LOG_LEVEL",
|
||||
0,
|
||||
TNT_MIN_SSH_LOG_LEVEL,
|
||||
TNT_MAX_SSH_LOG_LEVEL,
|
||||
};
|
||||
|
||||
int tnt_config_env_int(const tnt_int_config_spec_t *spec) {
|
||||
if (!spec) {
|
||||
return 0;
|
||||
}
|
||||
return env_int(spec->env_name, spec->fallback, spec->min_value,
|
||||
spec->max_value);
|
||||
}
|
||||
|
||||
bool tnt_config_parse_int(const char *value, const tnt_int_config_spec_t *spec,
|
||||
int *out) {
|
||||
char *end = NULL;
|
||||
long val;
|
||||
|
||||
if (!value || value[0] == '\0' || !spec || !out) {
|
||||
return false;
|
||||
}
|
||||
|
||||
val = strtol(value, &end, 10);
|
||||
if (!end || *end != '\0' || val < spec->min_value ||
|
||||
val > spec->max_value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*out = (int)val;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
#include "chat_room.h"
|
||||
#include "client.h"
|
||||
#include "commands.h"
|
||||
#include "config_defaults.h"
|
||||
#include "common.h"
|
||||
#include "exec.h"
|
||||
#include "history_view.h"
|
||||
|
|
@ -20,11 +21,11 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
static int g_idle_timeout = DEFAULT_IDLE_TIMEOUT;
|
||||
static int g_idle_timeout = TNT_DEFAULT_IDLE_TIMEOUT;
|
||||
static ui_lang_t g_default_ui_lang = UI_LANG_EN;
|
||||
|
||||
void input_init(void) {
|
||||
g_idle_timeout = env_int("TNT_IDLE_TIMEOUT", DEFAULT_IDLE_TIMEOUT, 0, 86400);
|
||||
g_idle_timeout = tnt_config_env_int(&TNT_CONFIG_IDLE_TIMEOUT);
|
||||
g_default_ui_lang = i18n_default_ui_lang();
|
||||
}
|
||||
|
||||
|
|
|
|||
70
src/main.c
70
src/main.c
|
|
@ -1,5 +1,6 @@
|
|||
#include "chat_room.h"
|
||||
#include "cli_text.h"
|
||||
#include "config_defaults.h"
|
||||
#include "common.h"
|
||||
#include "i18n.h"
|
||||
#include "message.h"
|
||||
|
|
@ -19,24 +20,6 @@ static void signal_handler(int sig) {
|
|||
_exit(0);
|
||||
}
|
||||
|
||||
static bool parse_int_arg(const char *value, int min_val, int max_val,
|
||||
int *out) {
|
||||
char *end = NULL;
|
||||
long val;
|
||||
|
||||
if (!value || value[0] == '\0' || !out) {
|
||||
return false;
|
||||
}
|
||||
|
||||
val = strtol(value, &end, 10);
|
||||
if (!end || *end != '\0' || val < min_val || val > max_val) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*out = (int)val;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_config_token(const char *value) {
|
||||
const unsigned char *p = (const unsigned char *)value;
|
||||
|
||||
|
|
@ -60,16 +43,16 @@ static int set_env_option(const char *name, const char *value) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int set_numeric_env_option(const char *env_name, const char *opt_name,
|
||||
const char *value, int min_val,
|
||||
int max_val, ui_lang_t lang) {
|
||||
static int set_numeric_env_option(const tnt_int_config_spec_t *spec,
|
||||
const char *opt_name, const char *value,
|
||||
ui_lang_t lang) {
|
||||
int parsed;
|
||||
|
||||
if (!parse_int_arg(value, min_val, max_val, &parsed)) {
|
||||
if (!tnt_config_parse_int(value, spec, &parsed)) {
|
||||
fprintf(stderr, cli_text_invalid_value_format(lang), opt_name, value);
|
||||
return TNT_EXIT_USAGE;
|
||||
}
|
||||
if (set_env_option(env_name, value) != 0) {
|
||||
if (set_env_option(spec->env_name, value) != 0) {
|
||||
return TNT_EXIT_ERROR;
|
||||
}
|
||||
return TNT_EXIT_OK;
|
||||
|
|
@ -86,21 +69,11 @@ static bool require_option_arg(int argc, char **argv, int index,
|
|||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int port = DEFAULT_PORT;
|
||||
int port = tnt_config_env_int(&TNT_CONFIG_PORT);
|
||||
ui_lang_t lang = i18n_default_ui_lang();
|
||||
const char *log_check_path = NULL;
|
||||
const char *log_recover_path = NULL;
|
||||
|
||||
/* Environment provides defaults; command-line flags override it. */
|
||||
const char *port_env = getenv("PORT");
|
||||
if (port_env && port_env[0] != '\0') {
|
||||
char *end;
|
||||
long val = strtol(port_env, &end, 10);
|
||||
if (*end == '\0' && val > 0 && val <= 65535) {
|
||||
port = (int)val;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse command line arguments */
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--port") == 0) {
|
||||
|
|
@ -108,7 +81,7 @@ int main(int argc, char **argv) {
|
|||
if (!require_option_arg(argc, argv, i, lang)) {
|
||||
return TNT_EXIT_USAGE;
|
||||
}
|
||||
if (!parse_int_arg(argv[i + 1], 1, 65535, &val)) {
|
||||
if (!tnt_config_parse_int(argv[i + 1], &TNT_CONFIG_PORT, &val)) {
|
||||
fprintf(stderr, cli_text_invalid_port_format(lang),
|
||||
argv[i + 1]);
|
||||
return TNT_EXIT_USAGE;
|
||||
|
|
@ -154,9 +127,8 @@ int main(int argc, char **argv) {
|
|||
if (!require_option_arg(argc, argv, i, lang)) {
|
||||
return TNT_EXIT_USAGE;
|
||||
}
|
||||
int rc = set_numeric_env_option("TNT_MAX_CONNECTIONS", argv[i],
|
||||
argv[i + 1], 1,
|
||||
MAX_CONFIGURED_CLIENTS, lang);
|
||||
int rc = set_numeric_env_option(&TNT_CONFIG_MAX_CONNECTIONS,
|
||||
argv[i], argv[i + 1], lang);
|
||||
if (rc != TNT_EXIT_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -165,9 +137,8 @@ int main(int argc, char **argv) {
|
|||
if (!require_option_arg(argc, argv, i, lang)) {
|
||||
return TNT_EXIT_USAGE;
|
||||
}
|
||||
int rc = set_numeric_env_option("TNT_MAX_CONN_PER_IP", argv[i],
|
||||
argv[i + 1], 1,
|
||||
MAX_CONFIGURED_CLIENTS, lang);
|
||||
int rc = set_numeric_env_option(&TNT_CONFIG_MAX_CONN_PER_IP,
|
||||
argv[i], argv[i + 1], lang);
|
||||
if (rc != TNT_EXIT_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -176,9 +147,8 @@ int main(int argc, char **argv) {
|
|||
if (!require_option_arg(argc, argv, i, lang)) {
|
||||
return TNT_EXIT_USAGE;
|
||||
}
|
||||
int rc = set_numeric_env_option("TNT_MAX_CONN_RATE_PER_IP",
|
||||
argv[i], argv[i + 1], 1,
|
||||
MAX_CONFIGURED_CLIENTS, lang);
|
||||
int rc = set_numeric_env_option(&TNT_CONFIG_MAX_CONN_RATE_PER_IP,
|
||||
argv[i], argv[i + 1], lang);
|
||||
if (rc != TNT_EXIT_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -187,8 +157,8 @@ int main(int argc, char **argv) {
|
|||
if (!require_option_arg(argc, argv, i, lang)) {
|
||||
return TNT_EXIT_USAGE;
|
||||
}
|
||||
int rc = set_numeric_env_option("TNT_RATE_LIMIT", argv[i],
|
||||
argv[i + 1], 0, 1, lang);
|
||||
int rc = set_numeric_env_option(&TNT_CONFIG_RATE_LIMIT, argv[i],
|
||||
argv[i + 1], lang);
|
||||
if (rc != TNT_EXIT_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -197,8 +167,8 @@ int main(int argc, char **argv) {
|
|||
if (!require_option_arg(argc, argv, i, lang)) {
|
||||
return TNT_EXIT_USAGE;
|
||||
}
|
||||
int rc = set_numeric_env_option("TNT_IDLE_TIMEOUT", argv[i],
|
||||
argv[i + 1], 0, 86400, lang);
|
||||
int rc = set_numeric_env_option(&TNT_CONFIG_IDLE_TIMEOUT, argv[i],
|
||||
argv[i + 1], lang);
|
||||
if (rc != TNT_EXIT_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -207,8 +177,8 @@ int main(int argc, char **argv) {
|
|||
if (!require_option_arg(argc, argv, i, lang)) {
|
||||
return TNT_EXIT_USAGE;
|
||||
}
|
||||
int rc = set_numeric_env_option("TNT_SSH_LOG_LEVEL", argv[i],
|
||||
argv[i + 1], 0, 4, lang);
|
||||
int rc = set_numeric_env_option(&TNT_CONFIG_SSH_LOG_LEVEL,
|
||||
argv[i], argv[i + 1], lang);
|
||||
if (rc != TNT_EXIT_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "ratelimit.h"
|
||||
#include "config_defaults.h"
|
||||
#include "common.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <pthread.h>
|
||||
|
|
@ -27,16 +28,20 @@ static pthread_mutex_t g_rate_limit_lock = PTHREAD_MUTEX_INITIALIZER;
|
|||
static int g_total_connections = 0;
|
||||
static pthread_mutex_t g_conn_count_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static int g_max_connections = 64;
|
||||
static int g_max_conn_per_ip = 5;
|
||||
static int g_max_conn_rate_per_ip = 10;
|
||||
static int g_rate_limit_enabled = 1;
|
||||
static int g_max_connections = TNT_DEFAULT_MAX_CONNECTIONS;
|
||||
static int g_max_conn_per_ip = TNT_DEFAULT_MAX_CONN_PER_IP;
|
||||
static int g_max_conn_rate_per_ip = TNT_DEFAULT_MAX_CONN_RATE_PER_IP;
|
||||
static int g_rate_limit_enabled = TNT_DEFAULT_RATE_LIMIT_ENABLED;
|
||||
|
||||
void ratelimit_init(void) {
|
||||
g_max_connections = env_int("TNT_MAX_CONNECTIONS", 64, 1, 1024);
|
||||
g_max_conn_per_ip = env_int("TNT_MAX_CONN_PER_IP", 5, 1, 1024);
|
||||
g_max_conn_rate_per_ip = env_int("TNT_MAX_CONN_RATE_PER_IP", 10, 1, 1024);
|
||||
g_rate_limit_enabled = env_int("TNT_RATE_LIMIT", 1, 0, 1);
|
||||
g_max_connections =
|
||||
tnt_config_env_int(&TNT_CONFIG_MAX_CONNECTIONS);
|
||||
g_max_conn_per_ip =
|
||||
tnt_config_env_int(&TNT_CONFIG_MAX_CONN_PER_IP);
|
||||
g_max_conn_rate_per_ip =
|
||||
tnt_config_env_int(&TNT_CONFIG_MAX_CONN_RATE_PER_IP);
|
||||
g_rate_limit_enabled =
|
||||
tnt_config_env_int(&TNT_CONFIG_RATE_LIMIT);
|
||||
}
|
||||
|
||||
/* Caller MUST hold g_rate_limit_lock. */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "ssh_server.h"
|
||||
#include "bootstrap.h"
|
||||
#include "commands.h"
|
||||
#include "config_defaults.h"
|
||||
#include "exec.h"
|
||||
#include "input.h"
|
||||
#include "ratelimit.h"
|
||||
|
|
@ -23,7 +24,7 @@
|
|||
|
||||
/* Global SSH bind instance */
|
||||
static ssh_bind g_sshbind = NULL;
|
||||
static int g_listen_port = DEFAULT_PORT;
|
||||
static int g_listen_port = TNT_DEFAULT_PORT;
|
||||
|
||||
static time_t g_server_start_time = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "common.h"
|
||||
#include "config_defaults.h"
|
||||
#include "exec_catalog.h"
|
||||
#include "i18n.h"
|
||||
#include "tntctl_text.h"
|
||||
|
|
@ -145,7 +146,7 @@ static int run_ssh(char **ssh_argv) {
|
|||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
const char *port = "2222";
|
||||
const char *port = TNT_DEFAULT_PORT_TEXT;
|
||||
const char *login = NULL;
|
||||
const char *host_key_checking = NULL;
|
||||
const char *known_hosts = NULL;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "tntctl_text.h"
|
||||
|
||||
#include "config_defaults.h"
|
||||
#include "exec_catalog.h"
|
||||
#include "i18n.h"
|
||||
|
||||
|
|
@ -61,7 +62,7 @@ void tntctl_text_append_usage(char *buffer, size_t buf_size, size_t *pos,
|
|||
"Usage: tntctl [options] host command [args...]\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" -p, --port PORT SSH port (default: 2222)\n"
|
||||
" -p, --port PORT SSH port (default: " TNT_DEFAULT_PORT_TEXT ")\n"
|
||||
" -l, --login USER SSH login name for exec identity\n"
|
||||
" --host-key-checking MODE\n"
|
||||
" OpenSSH host-key mode: yes, accept-new, no\n"
|
||||
|
|
@ -74,7 +75,7 @@ void tntctl_text_append_usage(char *buffer, size_t buf_size, size_t *pos,
|
|||
"用法: tntctl [options] host command [args...]\n"
|
||||
"\n"
|
||||
"选项:\n"
|
||||
" -p, --port PORT SSH 端口 (默认: 2222)\n"
|
||||
" -p, --port PORT SSH 端口 (默认: " TNT_DEFAULT_PORT_TEXT ")\n"
|
||||
" -l, --login USER SSH 登录名,用作 exec 身份\n"
|
||||
" --host-key-checking MODE\n"
|
||||
" OpenSSH 主机密钥模式: yes, accept-new, no\n"
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ UTF8_SRC = ../../src/utf8.c
|
|||
MESSAGE_SRC = ../../src/message.c
|
||||
MESSAGE_LOG_SRC = ../../src/message_log.c
|
||||
COMMON_SRC = ../../src/common.c
|
||||
CONFIG_DEFAULTS_SRC = ../../src/config_defaults.c
|
||||
COMMAND_CATALOG_SRC = ../../src/command_catalog.c
|
||||
CLI_TEXT_SRC = ../../src/cli_text.c
|
||||
TNTCTL_TEXT_SRC = ../../src/tntctl_text.c
|
||||
|
|
@ -27,7 +28,7 @@ HELP_TEXT_SRC = ../../src/help_text.c
|
|||
MANUAL_TEXT_SRC = ../../src/manual_text.c
|
||||
RATELIMIT_SRC = ../../src/ratelimit.c
|
||||
|
||||
TESTS = test_utf8 test_message test_chat_room test_history_view test_i18n test_system_message test_command_catalog test_exec_catalog test_help_text test_manual_text test_cli_text test_tntctl_text test_ratelimit
|
||||
TESTS = test_utf8 test_message test_chat_room test_history_view test_i18n test_system_message test_command_catalog test_exec_catalog test_help_text test_manual_text test_cli_text test_tntctl_text test_ratelimit test_config_defaults
|
||||
|
||||
.PHONY: all clean run
|
||||
|
||||
|
|
@ -39,7 +40,7 @@ test_utf8: test_utf8.c $(UTF8_SRC)
|
|||
test_message: test_message.c $(MESSAGE_SRC) $(MESSAGE_LOG_SRC) $(UTF8_SRC) $(COMMON_SRC)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
test_chat_room: test_chat_room.c $(CHAT_ROOM_SRC) $(MESSAGE_SRC) $(MESSAGE_LOG_SRC) $(UTF8_SRC) $(COMMON_SRC)
|
||||
test_chat_room: test_chat_room.c $(CHAT_ROOM_SRC) $(MESSAGE_SRC) $(MESSAGE_LOG_SRC) $(UTF8_SRC) $(COMMON_SRC) $(CONFIG_DEFAULTS_SRC)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
test_history_view: test_history_view.c $(HISTORY_VIEW_SRC)
|
||||
|
|
@ -69,7 +70,10 @@ test_cli_text: test_cli_text.c $(CLI_TEXT_SRC) $(COMMON_SRC)
|
|||
test_tntctl_text: test_tntctl_text.c $(TNTCTL_TEXT_SRC) $(EXEC_CATALOG_SRC) $(COMMON_SRC)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
test_ratelimit: test_ratelimit.c $(RATELIMIT_SRC) $(COMMON_SRC)
|
||||
test_ratelimit: test_ratelimit.c $(RATELIMIT_SRC) $(COMMON_SRC) $(CONFIG_DEFAULTS_SRC)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
test_config_defaults: test_config_defaults.c $(CONFIG_DEFAULTS_SRC) $(COMMON_SRC)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
run: all
|
||||
|
|
@ -111,6 +115,9 @@ run: all
|
|||
@echo ""
|
||||
@echo "=== Running Rate Limit Tests ==="
|
||||
./test_ratelimit
|
||||
@echo ""
|
||||
@echo "=== Running Config Defaults Tests ==="
|
||||
./test_config_defaults
|
||||
|
||||
clean:
|
||||
rm -f $(TESTS) *.o test_messages.log
|
||||
|
|
|
|||
66
tests/unit/test_config_defaults.c
Normal file
66
tests/unit/test_config_defaults.c
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#include "config_defaults.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define TEST(name) static void test_##name(void)
|
||||
#define RUN_TEST(name) do { \
|
||||
printf("Running %s... ", #name); \
|
||||
test_##name(); \
|
||||
printf("ok\n"); \
|
||||
} while (0)
|
||||
|
||||
TEST(specs_expose_runtime_defaults) {
|
||||
assert(TNT_CONFIG_PORT.fallback == TNT_DEFAULT_PORT);
|
||||
assert(TNT_CONFIG_MAX_CONNECTIONS.fallback ==
|
||||
TNT_DEFAULT_MAX_CONNECTIONS);
|
||||
assert(TNT_CONFIG_MAX_CONN_PER_IP.fallback ==
|
||||
TNT_DEFAULT_MAX_CONN_PER_IP);
|
||||
assert(TNT_CONFIG_MAX_CONN_RATE_PER_IP.fallback ==
|
||||
TNT_DEFAULT_MAX_CONN_RATE_PER_IP);
|
||||
assert(TNT_CONFIG_RATE_LIMIT.fallback ==
|
||||
TNT_DEFAULT_RATE_LIMIT_ENABLED);
|
||||
assert(TNT_CONFIG_IDLE_TIMEOUT.fallback == TNT_DEFAULT_IDLE_TIMEOUT);
|
||||
assert(TNT_CONFIG_PORT.min_value == TNT_MIN_PORT);
|
||||
assert(TNT_CONFIG_PORT.max_value == TNT_MAX_PORT);
|
||||
}
|
||||
|
||||
TEST(parse_uses_spec_ranges) {
|
||||
int out = 0;
|
||||
|
||||
assert(tnt_config_parse_int("2222", &TNT_CONFIG_PORT, &out));
|
||||
assert(out == 2222);
|
||||
assert(!tnt_config_parse_int("0", &TNT_CONFIG_PORT, &out));
|
||||
assert(!tnt_config_parse_int("65536", &TNT_CONFIG_PORT, &out));
|
||||
assert(!tnt_config_parse_int("abc", &TNT_CONFIG_PORT, &out));
|
||||
assert(!tnt_config_parse_int("", &TNT_CONFIG_PORT, &out));
|
||||
|
||||
assert(tnt_config_parse_int("0", &TNT_CONFIG_IDLE_TIMEOUT, &out));
|
||||
assert(out == 0);
|
||||
assert(!tnt_config_parse_int("86401", &TNT_CONFIG_IDLE_TIMEOUT, &out));
|
||||
}
|
||||
|
||||
TEST(env_reader_uses_fallback_and_range) {
|
||||
unsetenv(TNT_CONFIG_MAX_CONNECTIONS.env_name);
|
||||
assert(tnt_config_env_int(&TNT_CONFIG_MAX_CONNECTIONS) ==
|
||||
TNT_DEFAULT_MAX_CONNECTIONS);
|
||||
|
||||
setenv(TNT_CONFIG_MAX_CONNECTIONS.env_name, "128", 1);
|
||||
assert(tnt_config_env_int(&TNT_CONFIG_MAX_CONNECTIONS) == 128);
|
||||
|
||||
setenv(TNT_CONFIG_MAX_CONNECTIONS.env_name, "0", 1);
|
||||
assert(tnt_config_env_int(&TNT_CONFIG_MAX_CONNECTIONS) ==
|
||||
TNT_DEFAULT_MAX_CONNECTIONS);
|
||||
|
||||
unsetenv(TNT_CONFIG_MAX_CONNECTIONS.env_name);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
printf("Running config defaults unit tests...\n\n");
|
||||
RUN_TEST(specs_expose_runtime_defaults);
|
||||
RUN_TEST(parse_uses_spec_ranges);
|
||||
RUN_TEST(env_reader_uses_fallback_and_range);
|
||||
printf("\nAll 3 tests passed!\n");
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in a new issue