docs: 为 config.c、log.c、tls.c 添加函数级 Doxygen 注释
- config.c: 为 JSON 解析器内部函数和公共 API 添加完整注释 - log.c: 为日志级别转换和输出函数添加注释 - tls.c: 为 TLS 连接管理、Memory BIO 操作和 ALPN 回调添加注释 - http2.c: 移除过时的 TODO 占位注释(请求体收集已实现)
This commit is contained in:
parent
3762343889
commit
9da9bd9449
92
config.c
92
config.c
@ -51,6 +51,13 @@ typedef struct {
|
|||||||
|
|
||||||
/* === 内部:parser 辅助函数 === */
|
/* === 内部:parser 辅助函数 === */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parser_init - 初始化 JSON 解析器
|
||||||
|
*
|
||||||
|
* @param p 解析器状态结构
|
||||||
|
* @param src JSON 源字符串
|
||||||
|
* @param len 源字符串长度
|
||||||
|
*/
|
||||||
static void parser_init(parser_t *p, const char *src, size_t len) {
|
static void parser_init(parser_t *p, const char *src, size_t len) {
|
||||||
p->src = src;
|
p->src = src;
|
||||||
p->pos = 0;
|
p->pos = 0;
|
||||||
@ -58,6 +65,13 @@ static void parser_init(parser_t *p, const char *src, size_t len) {
|
|||||||
p->line = 1;
|
p->line = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parser_skip_ws - 跳过空白字符和注释
|
||||||
|
*
|
||||||
|
* 支持空格、制表符、换行,以及 // 行注释。
|
||||||
|
*
|
||||||
|
* @param p 解析器状态结构
|
||||||
|
*/
|
||||||
static void parser_skip_ws(parser_t *p) {
|
static void parser_skip_ws(parser_t *p) {
|
||||||
while (p->pos < p->len) {
|
while (p->pos < p->len) {
|
||||||
char c = p->src[p->pos];
|
char c = p->src[p->pos];
|
||||||
@ -76,6 +90,15 @@ static void parser_skip_ws(parser_t *p) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parser_next_token - 读取下一个 JSON token
|
||||||
|
*
|
||||||
|
* 支持的 token 类型:字符串、数字、true、false、
|
||||||
|
* 以及各种分隔符({ } [ ] , :)。
|
||||||
|
*
|
||||||
|
* @param p 解析器状态结构
|
||||||
|
* @return 下一个 token
|
||||||
|
*/
|
||||||
static token_t parser_next_token(parser_t *p) {
|
static token_t parser_next_token(parser_t *p) {
|
||||||
parser_skip_ws(p);
|
parser_skip_ws(p);
|
||||||
token_t t = {TOKEN_INVALID, NULL, 0, p->line};
|
token_t t = {TOKEN_INVALID, NULL, 0, p->line};
|
||||||
@ -139,12 +162,26 @@ static token_t parser_next_token(parser_t *p) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* token_expect - 期望下一个 token 为指定类型
|
||||||
|
*
|
||||||
|
* @param p 解析器状态结构
|
||||||
|
* @param expected 期望的 token 类型
|
||||||
|
* @return true 匹配,false 不匹配
|
||||||
|
*/
|
||||||
static bool token_expect(parser_t *p, token_type_t expected) {
|
static bool token_expect(parser_t *p, token_type_t expected) {
|
||||||
token_t t = parser_next_token(p);
|
token_t t = parser_next_token(p);
|
||||||
return t.type == expected;
|
return t.type == expected;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 复制 token 内容为 C 字符串(处理转义) */
|
/**
|
||||||
|
* token_str_dup - 将字符串 token 复制为 C 字符串
|
||||||
|
*
|
||||||
|
* 处理 JSON 字符串中的转义序列(\n \t \r \\ \")。
|
||||||
|
*
|
||||||
|
* @param t 字符串 token
|
||||||
|
* @return 新分配的 C 字符串,调用者负责释放;失败返回 NULL
|
||||||
|
*/
|
||||||
static char *token_str_dup(const token_t *t) {
|
static char *token_str_dup(const token_t *t) {
|
||||||
char *buf = (char *)malloc(t->len + 1);
|
char *buf = (char *)malloc(t->len + 1);
|
||||||
if (!buf) return NULL;
|
if (!buf) return NULL;
|
||||||
@ -169,6 +206,12 @@ static char *token_str_dup(const token_t *t) {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* token_to_long - 将数字 token 转换为长整型
|
||||||
|
*
|
||||||
|
* @param t 数字 token
|
||||||
|
* @return 转换后的数值
|
||||||
|
*/
|
||||||
static long token_to_long(const token_t *t) {
|
static long token_to_long(const token_t *t) {
|
||||||
char buf[32] = {0};
|
char buf[32] = {0};
|
||||||
size_t n = t->len < 31 ? t->len : 31;
|
size_t n = t->len < 31 ? t->len : 31;
|
||||||
@ -176,6 +219,12 @@ static long token_to_long(const token_t *t) {
|
|||||||
return strtol(buf, NULL, 10);
|
return strtol(buf, NULL, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* str_to_log_level - 将字符串转换为日志级别
|
||||||
|
*
|
||||||
|
* @param str 日志级别字符串(error/warn/info/debug)
|
||||||
|
* @return 对应的日志级别枚举值,无效时返回 LOG_LEVEL_INFO
|
||||||
|
*/
|
||||||
static log_level_t str_to_log_level(const char *str) {
|
static log_level_t str_to_log_level(const char *str) {
|
||||||
if (strcmp(str, "error") == 0) return LOG_LEVEL_ERROR;
|
if (strcmp(str, "error") == 0) return LOG_LEVEL_ERROR;
|
||||||
if (strcmp(str, "warn") == 0) return LOG_LEVEL_WARN;
|
if (strcmp(str, "warn") == 0) return LOG_LEVEL_WARN;
|
||||||
@ -186,6 +235,21 @@ static log_level_t str_to_log_level(const char *str) {
|
|||||||
|
|
||||||
/* === 公共 API === */
|
/* === 公共 API === */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* config_load_from_file - 从 JSON 配置文件加载配置
|
||||||
|
*
|
||||||
|
* 解析 cocoon.json 格式,支持以下字段:
|
||||||
|
* root_dir, port, threaded, num_workers, max_connections, timeout_ms,
|
||||||
|
* log_level, gzip_enabled, brotli_enabled, tls_cert, tls_key, tls_enabled,
|
||||||
|
* access_log, cors_enabled, auth_user, auth_pass, rate_limit,
|
||||||
|
* plugins(字符串或数组), proxies(对象数组)
|
||||||
|
*
|
||||||
|
* 未知字段将被静默忽略,便于向后兼容。
|
||||||
|
*
|
||||||
|
* @param path 配置文件路径
|
||||||
|
* @param config 输出配置结构体
|
||||||
|
* @return true 成功,false 失败(会输出错误信息到 stderr)
|
||||||
|
*/
|
||||||
bool config_load_from_file(const char *path, cocoon_config_t *config) {
|
bool config_load_from_file(const char *path, cocoon_config_t *config) {
|
||||||
if (!path || !config) return false;
|
if (!path || !config) return false;
|
||||||
|
|
||||||
@ -423,6 +487,32 @@ bool config_load_from_file(const char *path, cocoon_config_t *config) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* config_merge - 将命令行参数合并到基础配置
|
||||||
|
*
|
||||||
|
* 命令行显式指定的值覆盖配置文件中的值。
|
||||||
|
* 对于字符串字段,会释放旧值并复制新值。
|
||||||
|
*
|
||||||
|
* @param base 基础配置(通常来自配置文件)
|
||||||
|
* @param cmdline 命令行配置
|
||||||
|
* @param has_root_dir 是否显式指定 root_dir
|
||||||
|
* @param has_port 是否显式指定 port
|
||||||
|
* @param has_workers 是否显式指定 num_workers
|
||||||
|
* @param has_max_conn 是否显式指定 max_connections
|
||||||
|
* @param has_timeout 是否显式指定 timeout_ms
|
||||||
|
* @param has_log_level 是否显式指定 log_level
|
||||||
|
* @param has_gzip_enabled 是否显式指定 gzip_enabled
|
||||||
|
* @param has_brotli_enabled 是否显式指定 brotli_enabled
|
||||||
|
* @param has_tls_cert 是否显式指定 tls_cert
|
||||||
|
* @param has_tls_key 是否显式指定 tls_key
|
||||||
|
* @param has_tls_enabled 是否显式指定 tls_enabled
|
||||||
|
* @param has_access_log 是否显式指定 access_log
|
||||||
|
* @param has_cors_enabled 是否显式指定 cors_enabled
|
||||||
|
* @param has_auth_user 是否显式指定 auth_user
|
||||||
|
* @param has_auth_pass 是否显式指定 auth_pass
|
||||||
|
* @param has_rate_limit 是否显式指定 rate_limit
|
||||||
|
* @param has_plugins 是否显式指定 plugins
|
||||||
|
*/
|
||||||
void config_merge(cocoon_config_t *base, const cocoon_config_t *cmdline,
|
void config_merge(cocoon_config_t *base, const cocoon_config_t *cmdline,
|
||||||
bool has_root_dir, bool has_port, bool has_workers,
|
bool has_root_dir, bool has_port, bool has_workers,
|
||||||
bool has_max_conn, bool has_timeout, bool has_log_level,
|
bool has_max_conn, bool has_timeout, bool has_log_level,
|
||||||
|
|||||||
2
http2.c
2
http2.c
@ -689,7 +689,7 @@ static int on_stream_close_callback(nghttp2_session *session __attribute__((unus
|
|||||||
/**
|
/**
|
||||||
* on_data_chunk_recv_callback - DATA 帧数据块接收回调
|
* on_data_chunk_recv_callback - DATA 帧数据块接收回调
|
||||||
*
|
*
|
||||||
* 目前为占位实现,TODO:将请求体数据追加到流缓冲区。
|
* 将请求体数据追加到流缓冲区。支持 Content-Length 和分块传输。
|
||||||
*
|
*
|
||||||
* @param session nghttp2 会话(未使用)
|
* @param session nghttp2 会话(未使用)
|
||||||
* @param flags 标志(未使用)
|
* @param flags 标志(未使用)
|
||||||
|
|||||||
49
log.c
49
log.c
@ -13,6 +13,12 @@
|
|||||||
static log_level_t g_level = LOG_LEVEL_INFO;
|
static log_level_t g_level = LOG_LEVEL_INFO;
|
||||||
static const char *g_prefix = "[Cocoon]";
|
static const char *g_prefix = "[Cocoon]";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* level_str - 将日志级别转换为字符串
|
||||||
|
*
|
||||||
|
* @param level 日志级别
|
||||||
|
* @return 级别名称(ERROR/WARN/INFO/DEBUG/UNKNOWN)
|
||||||
|
*/
|
||||||
static const char *level_str(log_level_t level) {
|
static const char *level_str(log_level_t level) {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case LOG_LEVEL_ERROR: return "ERROR";
|
case LOG_LEVEL_ERROR: return "ERROR";
|
||||||
@ -23,18 +29,45 @@ static const char *level_str(log_level_t level) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* log_set_level - 设置全局日志级别
|
||||||
|
*
|
||||||
|
* 低于此级别的日志消息将被忽略。
|
||||||
|
*
|
||||||
|
* @param level 日志级别
|
||||||
|
*/
|
||||||
void log_set_level(log_level_t level) {
|
void log_set_level(log_level_t level) {
|
||||||
g_level = level;
|
g_level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* log_set_prefix - 设置日志前缀
|
||||||
|
*
|
||||||
|
* @param prefix 前缀字符串,设为 NULL 则无前缀
|
||||||
|
*/
|
||||||
void log_set_prefix(const char *prefix) {
|
void log_set_prefix(const char *prefix) {
|
||||||
g_prefix = prefix;
|
g_prefix = prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* log_get_level - 获取当前日志级别
|
||||||
|
*
|
||||||
|
* @return 当前日志级别
|
||||||
|
*/
|
||||||
log_level_t log_get_level(void) {
|
log_level_t log_get_level(void) {
|
||||||
return g_level;
|
return g_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* log_output - 日志输出核心函数
|
||||||
|
*
|
||||||
|
* 格式化时间戳、前缀、级别和消息,输出到 stderr。
|
||||||
|
* 若日志级别低于全局级别则直接返回。
|
||||||
|
*
|
||||||
|
* @param level 日志级别
|
||||||
|
* @param fmt 格式字符串
|
||||||
|
* @param args 可变参数列表
|
||||||
|
*/
|
||||||
static void log_output(log_level_t level, const char *fmt, va_list args) {
|
static void log_output(log_level_t level, const char *fmt, va_list args) {
|
||||||
if (level > g_level) return;
|
if (level > g_level) return;
|
||||||
|
|
||||||
@ -52,6 +85,10 @@ static void log_output(log_level_t level, const char *fmt, va_list args) {
|
|||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* log_error - 输出 ERROR 级别日志
|
||||||
|
* @param fmt 格式字符串
|
||||||
|
*/
|
||||||
void log_error(const char *fmt, ...) {
|
void log_error(const char *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
@ -59,6 +96,10 @@ void log_error(const char *fmt, ...) {
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* log_warn - 输出 WARN 级别日志
|
||||||
|
* @param fmt 格式字符串
|
||||||
|
*/
|
||||||
void log_warn(const char *fmt, ...) {
|
void log_warn(const char *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
@ -66,6 +107,10 @@ void log_warn(const char *fmt, ...) {
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* log_info - 输出 INFO 级别日志
|
||||||
|
* @param fmt 格式字符串
|
||||||
|
*/
|
||||||
void log_info(const char *fmt, ...) {
|
void log_info(const char *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
@ -73,6 +118,10 @@ void log_info(const char *fmt, ...) {
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* log_debug - 输出 DEBUG 级别日志
|
||||||
|
* @param fmt 格式字符串
|
||||||
|
*/
|
||||||
void log_debug(const char *fmt, ...) {
|
void log_debug(const char *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
|||||||
134
tls.c
134
tls.c
@ -33,12 +33,27 @@ static tls_conn_t **g_map = NULL;
|
|||||||
static int g_map_cap = 0;
|
static int g_map_cap = 0;
|
||||||
static SSL_CTX *g_ctx = NULL;
|
static SSL_CTX *g_ctx = NULL;
|
||||||
|
|
||||||
/* 内部:O(1) fd 查表 */
|
/**
|
||||||
|
* tls_lookup - 根据 fd 查找 TLS 连接
|
||||||
|
*
|
||||||
|
* O(1) 查表,使用动态数组索引。
|
||||||
|
*
|
||||||
|
* @param fd socket 文件描述符
|
||||||
|
* @return TLS 连接结构,未找到返回 NULL
|
||||||
|
*/
|
||||||
static tls_conn_t* tls_lookup(int fd) {
|
static tls_conn_t* tls_lookup(int fd) {
|
||||||
if (fd >= 0 && fd < g_map_cap) return g_map[fd];
|
if (fd >= 0 && fd < g_map_cap) return g_map[fd];
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tls_map_set - 将 fd 与 TLS 连接关联
|
||||||
|
*
|
||||||
|
* 若数组容量不足则自动扩容。
|
||||||
|
*
|
||||||
|
* @param fd socket 文件描述符
|
||||||
|
* @param t TLS 连接结构
|
||||||
|
*/
|
||||||
static void tls_map_set(int fd, tls_conn_t *t) {
|
static void tls_map_set(int fd, tls_conn_t *t) {
|
||||||
if (fd >= g_map_cap) {
|
if (fd >= g_map_cap) {
|
||||||
int old_cap = g_map_cap;
|
int old_cap = g_map_cap;
|
||||||
@ -49,11 +64,25 @@ static void tls_map_set(int fd, tls_conn_t *t) {
|
|||||||
g_map[fd] = t;
|
g_map[fd] = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tls_map_clear - 清除 fd 与 TLS 连接的关联
|
||||||
|
*
|
||||||
|
* @param fd socket 文件描述符
|
||||||
|
*/
|
||||||
static void tls_map_clear(int fd) {
|
static void tls_map_clear(int fd) {
|
||||||
if (fd >= 0 && fd < g_map_cap) g_map[fd] = NULL;
|
if (fd >= 0 && fd < g_map_cap) g_map[fd] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 内部:从 socket 读取原始数据(协程感知) */
|
/**
|
||||||
|
* socket_read - 从 socket 读取原始数据(协程感知)
|
||||||
|
*
|
||||||
|
* 若当前在协程调度器中则使用 coco_read,否则使用标准 read。
|
||||||
|
*
|
||||||
|
* @param fd socket 文件描述符
|
||||||
|
* @param buf 读取缓冲区
|
||||||
|
* @param len 最大读取长度
|
||||||
|
* @return 实际读取字节数,失败返回 -1
|
||||||
|
*/
|
||||||
static ssize_t socket_read(int fd, void *buf, size_t len) {
|
static ssize_t socket_read(int fd, void *buf, size_t len) {
|
||||||
if (coco_sched_get_current() != NULL) {
|
if (coco_sched_get_current() != NULL) {
|
||||||
return coco_read(fd, buf, len);
|
return coco_read(fd, buf, len);
|
||||||
@ -61,7 +90,16 @@ static ssize_t socket_read(int fd, void *buf, size_t len) {
|
|||||||
return read(fd, buf, len);
|
return read(fd, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 内部:向 socket 写入原始数据 */
|
/**
|
||||||
|
* socket_write_all - 向 socket 写入全部数据(协程感知)
|
||||||
|
*
|
||||||
|
* 循环写入直至全部数据发送完毕。若当前在协程调度器中则使用 coco_write。
|
||||||
|
*
|
||||||
|
* @param fd socket 文件描述符
|
||||||
|
* @param buf 数据缓冲区
|
||||||
|
* @param len 数据长度
|
||||||
|
* @return 实际发送字节数,失败返回 -1
|
||||||
|
*/
|
||||||
static ssize_t socket_write_all(int fd, const void *buf, size_t len) {
|
static ssize_t socket_write_all(int fd, const void *buf, size_t len) {
|
||||||
if (coco_sched_get_current() != NULL) {
|
if (coco_sched_get_current() != NULL) {
|
||||||
size_t sent = 0;
|
size_t sent = 0;
|
||||||
@ -94,7 +132,13 @@ static ssize_t socket_write_all(int fd, const void *buf, size_t len) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 内部:将 write BIO 中的加密数据刷到 socket */
|
/**
|
||||||
|
* flush_wbio - 将 write BIO 中的加密数据刷到 socket
|
||||||
|
*
|
||||||
|
* @param fd socket 文件描述符
|
||||||
|
* @param wbio write BIO
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
static int flush_wbio(int fd, BIO *wbio) {
|
static int flush_wbio(int fd, BIO *wbio) {
|
||||||
char buf[16384];
|
char buf[16384];
|
||||||
int pending = BIO_read(wbio, buf, sizeof(buf));
|
int pending = BIO_read(wbio, buf, sizeof(buf));
|
||||||
@ -105,7 +149,19 @@ static int flush_wbio(int fd, BIO *wbio) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 内部:ALPN 选择回调,优先选择 h2,否则 http/1.1 */
|
/**
|
||||||
|
* tls_alpn_select_cb - ALPN 协议选择回调
|
||||||
|
*
|
||||||
|
* 优先选择 h2(HTTP/2),次选 http/1.1。
|
||||||
|
*
|
||||||
|
* @param ssl SSL 对象(未使用)
|
||||||
|
* @param out 输出选中的协议
|
||||||
|
* @param outlen 输出协议长度
|
||||||
|
* @param in 客户端 ALPN 列表
|
||||||
|
* @param inlen 客户端 ALPN 列表长度
|
||||||
|
* @param arg 用户参数(未使用)
|
||||||
|
* @return SSL_TLSEXT_ERR_OK 成功,SSL_TLSEXT_ERR_NOACK 无匹配
|
||||||
|
*/
|
||||||
static int tls_alpn_select_cb(SSL *ssl __attribute__((unused)), const unsigned char **out,
|
static int tls_alpn_select_cb(SSL *ssl __attribute__((unused)), const unsigned char **out,
|
||||||
unsigned char *outlen, const unsigned char *in,
|
unsigned char *outlen, const unsigned char *in,
|
||||||
unsigned int inlen, void *arg __attribute__((unused))) {
|
unsigned int inlen, void *arg __attribute__((unused))) {
|
||||||
@ -146,6 +202,16 @@ static int tls_alpn_select_cb(SSL *ssl __attribute__((unused)), const unsigned c
|
|||||||
|
|
||||||
/* ===== 公共 API ===== */
|
/* ===== 公共 API ===== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tls_create_context - 创建 TLS 服务器上下文
|
||||||
|
*
|
||||||
|
* 初始化 OpenSSL,加载证书和私钥,设置 ALPN 回调。
|
||||||
|
* 最低支持 TLS 1.2。
|
||||||
|
*
|
||||||
|
* @param cert_path 证书文件路径(PEM 格式)
|
||||||
|
* @param key_path 私钥文件路径(PEM 格式)
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
int tls_create_context(const char *cert_path, const char *key_path) {
|
int tls_create_context(const char *cert_path, const char *key_path) {
|
||||||
if (!cert_path || !key_path) return -1;
|
if (!cert_path || !key_path) return -1;
|
||||||
|
|
||||||
@ -193,6 +259,11 @@ int tls_create_context(const char *cert_path, const char *key_path) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tls_destroy_context - 销毁 TLS 上下文并清理所有连接
|
||||||
|
*
|
||||||
|
* 释放 SSL_CTX、所有 TLS 连接映射表项及其关联资源。
|
||||||
|
*/
|
||||||
void tls_destroy_context(void) {
|
void tls_destroy_context(void) {
|
||||||
if (g_ctx) {
|
if (g_ctx) {
|
||||||
SSL_CTX_free(g_ctx);
|
SSL_CTX_free(g_ctx);
|
||||||
@ -213,10 +284,24 @@ void tls_destroy_context(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tls_has_context - 检查是否已创建 TLS 上下文
|
||||||
|
*
|
||||||
|
* @return true 已创建,false 未创建
|
||||||
|
*/
|
||||||
bool tls_has_context(void) {
|
bool tls_has_context(void) {
|
||||||
return g_ctx != NULL;
|
return g_ctx != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tls_accept - 接受新 TLS 连接并执行握手
|
||||||
|
*
|
||||||
|
* 为指定 fd 创建 TLS 连接对象,执行完整的握手循环。
|
||||||
|
* 使用 Memory BIO 与协程 I/O 集成。
|
||||||
|
*
|
||||||
|
* @param fd socket 文件描述符
|
||||||
|
* @return 0 成功,-1 失败
|
||||||
|
*/
|
||||||
int tls_accept(int fd) {
|
int tls_accept(int fd) {
|
||||||
if (!g_ctx) return -1;
|
if (!g_ctx) return -1;
|
||||||
|
|
||||||
@ -287,6 +372,16 @@ fail:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tls_read - 从 TLS 连接读取解密数据
|
||||||
|
*
|
||||||
|
* 若 SSL 缓冲区为空,则从 socket 读取加密数据并解密。
|
||||||
|
*
|
||||||
|
* @param fd socket 文件描述符
|
||||||
|
* @param buf 读取缓冲区
|
||||||
|
* @param len 最大读取长度
|
||||||
|
* @return 实际读取字节数,0 对端关闭,-1 错误
|
||||||
|
*/
|
||||||
ssize_t tls_read(int fd, void *buf, size_t len) {
|
ssize_t tls_read(int fd, void *buf, size_t len) {
|
||||||
tls_conn_t *t = tls_lookup(fd);
|
tls_conn_t *t = tls_lookup(fd);
|
||||||
if (!t || !t->ssl) return -1;
|
if (!t || !t->ssl) return -1;
|
||||||
@ -315,6 +410,16 @@ ssize_t tls_read(int fd, void *buf, size_t len) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tls_write - 向 TLS 连接写入数据
|
||||||
|
*
|
||||||
|
* 数据经 SSL 加密后通过 socket 发送。
|
||||||
|
*
|
||||||
|
* @param fd socket 文件描述符
|
||||||
|
* @param buf 数据缓冲区
|
||||||
|
* @param len 数据长度
|
||||||
|
* @return 实际发送字节数,-1 错误
|
||||||
|
*/
|
||||||
ssize_t tls_write(int fd, const void *buf, size_t len) {
|
ssize_t tls_write(int fd, const void *buf, size_t len) {
|
||||||
tls_conn_t *t = tls_lookup(fd);
|
tls_conn_t *t = tls_lookup(fd);
|
||||||
if (!t || !t->ssl) return -1;
|
if (!t || !t->ssl) return -1;
|
||||||
@ -346,6 +451,13 @@ ssize_t tls_write(int fd, const void *buf, size_t len) {
|
|||||||
return (ssize_t)total;
|
return (ssize_t)total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tls_close - 关闭 TLS 连接并释放资源
|
||||||
|
*
|
||||||
|
* 发送 close_notify,释放 SSL 对象和连接映射。
|
||||||
|
*
|
||||||
|
* @param fd socket 文件描述符
|
||||||
|
*/
|
||||||
void tls_close(int fd) {
|
void tls_close(int fd) {
|
||||||
tls_conn_t *t = tls_lookup(fd);
|
tls_conn_t *t = tls_lookup(fd);
|
||||||
if (!t) return;
|
if (!t) return;
|
||||||
@ -362,10 +474,22 @@ void tls_close(int fd) {
|
|||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tls_has_connection - 检查 fd 是否有关联的 TLS 连接
|
||||||
|
*
|
||||||
|
* @param fd socket 文件描述符
|
||||||
|
* @return true 有 TLS 连接,false 无
|
||||||
|
*/
|
||||||
bool tls_has_connection(int fd) {
|
bool tls_has_connection(int fd) {
|
||||||
return tls_lookup(fd) != NULL;
|
return tls_lookup(fd) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tls_negotiated_http2 - 检查 ALPN 协商结果是否为 HTTP/2
|
||||||
|
*
|
||||||
|
* @param fd socket 文件描述符
|
||||||
|
* @return true 协商为 h2,false 未协商或为 http/1.1
|
||||||
|
*/
|
||||||
bool tls_negotiated_http2(int fd) {
|
bool tls_negotiated_http2(int fd) {
|
||||||
tls_conn_t *t = tls_lookup(fd);
|
tls_conn_t *t = tls_lookup(fd);
|
||||||
if (!t || !t->ssl) return false;
|
if (!t || !t->ssl) return false;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user