From e4b163747e3f3a740741103bc3227ac56a824aba Mon Sep 17 00:00:00 2001 From: pm5lov8b3 <1584615561@qq.com> Date: Sat, 30 Nov 2024 08:11:29 +0800 Subject: [PATCH 1/8] ADD file via upload --- WFConsulClient.cc | 1477 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1477 insertions(+) create mode 100644 WFConsulClient.cc diff --git a/WFConsulClient.cc b/WFConsulClient.cc new file mode 100644 index 0000000..8e1bef2 --- /dev/null +++ b/WFConsulClient.cc @@ -0,0 +1,1477 @@ +/* + Copyright (c) 2022 Sogou, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Authors: Wang Zhenpeng (wangzhenpeng@sogou-inc.com) +*/ + +#include +#include +#include +#include +#include +#include "json_parser.h" // JSON解析工具 +#include "StringUtil.h" // 字符串工具 +#include "URIParser.h" // URI解析工具 +#include "HttpUtil.h" // HTTP相关工具 +#include "WFConsulClient.h" // Consul客户端相关定义 + +using namespace protocol; // 使用协议相关命名空间 + +// WFConsulTask 构造函数 +WFConsulTask::WFConsulTask(const std::string& proxy_url, + const std::string& service_namespace, + const std::string& service_name, + const std::string& service_id, + int retry_max, + consul_callback_t&& cb) : + proxy_url(proxy_url), // 初始化代理地址 + callback(std::move(cb)) // 设置回调函数 +{ + this->service.service_name = service_name; // 初始化服务名称 + this->service.service_namespace = service_namespace; // 初始化服务命名空间 + this->service.service_id = service_id; // 初始化服务 ID + this->api_type = CONSUL_API_TYPE_UNKNOWN; // 设置 API 类型为未知 + this->retry_max = retry_max; // 设置最大重试次数 + this->finish = false; // 标记任务未完成 + this->consul_index = 0; // 初始化 Consul 索引为 0 +} + +// 设置服务相关信息 +void WFConsulTask::set_service(const struct protocol::ConsulService *service) +{ + this->service.tags = service->tags; // 设置服务标签 + this->service.meta = service->meta; // 设置服务元信息 + this->service.tag_override = service->tag_override; // 设置标签覆盖标志 + this->service.service_address = service->service_address; // 设置服务地址 + this->service.lan = service->lan; // 设置本地局域网地址 + this->service.lan_ipv4 = service->lan_ipv4; // 设置 IPv4 地址 + this->service.lan_ipv6 = service->lan_ipv6; // 设置 IPv6 地址 + this->service.virtual_address = service->virtual_address; // 设置虚拟地址 + this->service.wan = service->wan; // 设置广域网地址 + this->service.wan_ipv4 = service->wan_ipv4; // 设置 IPv4 地址 + this->service.wan_ipv6 = service->wan_ipv6; // 设置 IPv6 地址 +} + + +// 解析服务发现结果的静态函数 +static bool parse_discover_result(const json_value_t *root, + std::vector& result); + +// 解析服务列表结果的静态函数 +static bool parse_list_service_result(const json_value_t *root, + std::vector& result); + + +// 获取服务发现结果 +bool WFConsulTask::get_discover_result( + std::vector& result) +{ + json_value_t *root; // JSON 根节点 + int errno_bak; // 备份当前 errno 值 + bool ret; // 返回结果标志 + + // 检查当前 API 类型是否为服务发现 + if (this->api_type != CONSUL_API_TYPE_DISCOVER) + { + errno = EPERM; // 设置权限错误 + return false; // 返回失败 + } + + errno_bak = errno; // 备份 errno + errno = EBADMSG; // 设置消息错误 + std::string body = HttpUtil::decode_chunked_body(&this->http_resp); // 解码 HTTP 响应的分块数据 + root = json_value_parse(body.c_str()); // 解析 JSON 数据 + if (!root) // 如果解析失败 + return false; // 返回失败 + + ret = parse_discover_result(root, result); // 解析服务发现结果 + json_value_destroy(root); // 销毁 JSON 对象 + if (ret) // 如果解析成功 + errno = errno_bak; // 恢复原始 errno + + return ret; // 返回解析结果 +} + + +// 获取服务列表结果 +bool WFConsulTask::get_list_service_result( + std::vector& result) +{ + json_value_t *root; // JSON 根节点 + int errno_bak; // 备份当前 errno 值 + bool ret; // 返回结果标志 + + // 检查当前 API 类型是否为服务列表 + if (this->api_type != CONSUL_API_TYPE_LIST_SERVICE) + { + errno = EPERM; // 设置权限错误 + return false; // 返回失败 + } + + errno_bak = errno; // 备份 errno + errno = EBADMSG; // 设置消息错误 + std::string body = HttpUtil::decode_chunked_body(&this->http_resp); // 解码 HTTP 响应的分块数据 + root = json_value_parse(body.c_str()); // 解析 JSON 数据 + if (!root) // 如果解析失败 + return false; // 返回失败 + + ret = parse_list_service_result(root, result); // 解析服务列表结果 + json_value_destroy(root); // 销毁 JSON 对象 + if (ret) // 如果解析成功 + errno = errno_bak; // 恢复原始 errno + + return ret; // 返回解析结果 +} + + +// 分发任务,根据 API 类型选择相应的任务处理逻辑 +void WFConsulTask::dispatch() +{ + WFHttpTask *task; // 定义 HTTP 任务指针 + + if (this->finish) // 如果任务已完成 + { + this->subtask_done(); // 标记子任务完成 + return; // 退出 + } + + // 根据 API 类型选择处理任务 + switch(this->api_type) + { + case CONSUL_API_TYPE_DISCOVER: // 如果是服务发现任务 + task = create_discover_task(); // 创建服务发现任务 + break; + + case CONSUL_API_TYPE_LIST_SERVICE: // 如果是服务列表任务 + task = create_list_service_task(); // 创建服务列表任务 + break; + + case CONSUL_API_TYPE_DEREGISTER: // 如果是注销服务任务 + task = create_deregister_task(); // 创建注销服务任务 + break; + + case CONSUL_API_TYPE_REGISTER: // 如果是注册服务任务 + task = create_register_task(); // 创建注册服务任务 + if (task) + break; + + // 如果任务创建失败,设置错误状态 + if (1) + { + this->state = WFT_STATE_SYS_ERROR; // 设置系统错误状态 + this->error = errno; // 设置错误码 + } + else + { + default: + this->state = WFT_STATE_TASK_ERROR; // 设置任务错误状态 + this->error = WFT_ERR_CONSUL_API_UNKNOWN; // 设置未知 API 错误 + } + + this->finish = true; // 标记任务完成 + this->subtask_done(); // 标记子任务完成 + return; + } + + // 将任务插入到工作队列 + series_of(this)->push_front(this); // 将当前任务加入队列 + series_of(this)->push_front(task); // 将新任务加入队列 + this->subtask_done(); // 标记子任务完成 +} + + +// 标记任务完成,并执行回调或清理逻辑 +SubTask *WFConsulTask::done() +{ + SeriesWork *series = series_of(this); // 获取当前任务的工作队列 + + if (finish) // 如果任务已完成 + { + if (this->callback) // 如果有回调函数 + this->callback(this); // 执行回调函数 + + delete this; // 删除任务对象 + } + + return series->pop(); // 从队列中弹出任务 +} + + +// 将毫秒时间转换为字符串形式(如 "5s" 或 "3m") +static std::string convert_time_to_str(int milliseconds) +{ + std::string str_time; // 保存时间字符串 + int seconds = milliseconds / 1000; // 将毫秒转换为秒 + + if (seconds >= 180) // 如果时间超过 3 分钟 + str_time = std::to_string(seconds / 60) + "m"; // 转换为分钟形式 + else + str_time = std::to_string(seconds) + "s"; // 转换为秒形式 + + return str_time; // 返回时间字符串 +} + + +// 生成服务发现请求的 URL +std::string WFConsulTask::generate_discover_request() +{ + std::string url = this->proxy_url; // 初始化 URL 为代理地址 + + // 添加服务健康检查路径 + url += "/v1/health/service/" + this->service.service_name; + + // 添加数据中心参数 + url += "?dc=" + this->config.get_datacenter(); + + // 添加服务命名空间参数 + url += "&ns=" + this->service.service_namespace; + + // 获取 passing 参数值,表示是否仅返回通过健康检查的服务实例 + std::string passing = this->config.get_passing() ? "true" : "false"; + url += "&passing=" + passing; // 添加 passing 参数 + + // 添加 token 参数用于鉴权 + url += "&token=" + this->config.get_token(); + + // 添加过滤表达式参数 + url += "&filter=" + this->config.get_filter_expr(); + + // 检查是否启用 Consul 阻塞查询 + if (this->config.blocking_query()) + { + // 添加索引参数,用于阻塞查询的初始状态 + url += "&index=" + std::to_string(this->get_consul_index()); + + // 添加等待时间参数,表示阻塞查询的超时时间 + url += "&wait=" + convert_time_to_str(this->config.get_wait_ttl()); + } + + return url; // 返回生成的 URL +} + + +// 创建服务发现任务 +WFHttpTask *WFConsulTask::create_discover_task() +{ + std::string url = generate_discover_request(); // 调用生成服务发现 URL 的函数 + WFHttpTask *task = WFTaskFactory::create_http_task( // 创建 HTTP 任务 + url, 0, this->retry_max, discover_callback); + + HttpRequest *req = task->get_req(); // 获取 HTTP 请求对象 + + // 添加 HTTP 请求头,指定内容类型为 JSON + req->add_header_pair("Content-Type", "application/json"); + + task->user_data = this; // 设置用户数据为当前任务对象 + return task; // 返回创建的任务 +} + + +// 创建服务列表任务 +WFHttpTask *WFConsulTask::create_list_service_task() +{ + std::string url = this->proxy_url; // 初始化 URL 为代理地址 + + // 添加服务目录路径和鉴权 token + url += "/v1/catalog/services?token=" + this->config.get_token(); + + // 添加数据中心参数 + url += "&dc=" + this->config.get_datacenter(); + + // 添加服务命名空间参数 + url += "&ns=" + this->service.service_namespace; + + WFHttpTask *task = WFTaskFactory::create_http_task( // 创建 HTTP 任务 + url, 0, this->retry_max, list_service_callback); + + HttpRequest *req = task->get_req(); // 获取 HTTP 请求对象 + + // 添加 HTTP 请求头,指定内容类型为 JSON + req->add_header_pair("Content-Type", "application/json"); + + task->user_data = this; // 设置用户数据为当前任务对象 + return task; // 返回创建的任务 +} + + +static void print_json_value(const json_value_t *val, int depth, + std::string& json_str); + +static bool create_register_request(const json_value_t *root, + const struct ConsulService *service, + const ConsulConfig& config); + +// 创建服务注册任务 +WFHttpTask *WFConsulTask::create_register_task() +{ + std::string payload; // 定义用于存储请求体的字符串 + + std::string url = this->proxy_url; // 初始化 URL 为代理地址 + // 添加服务注册路径和替换检查选项 + url += "/v1/agent/service/register?replace-existing-checks="; + url += this->config.get_replace_checks() ? "true" : "false"; + + WFHttpTask *task = WFTaskFactory::create_http_task( // 创建 HTTP 任务 + url, 0, this->retry_max, register_callback); + + HttpRequest *req = task->get_req(); // 获取 HTTP 请求对象 + + req->set_method(HttpMethodPut); // 设置 HTTP 方法为 PUT + req->add_header_pair("Content-Type", "application/json"); // 添加内容类型头 + + // 如果存在鉴权 token,则添加到请求头 + if (!this->config.get_token().empty()) + req->add_header_pair("X-Consul-Token", this->config.get_token()); + + json_value_t *root = json_value_create(JSON_VALUE_OBJECT); // 创建 JSON 对象根节点 + if (root) // 如果创建成功 + { + // 构建服务注册请求 JSON 数据 + if (create_register_request(root, &this->service, this->config)) + print_json_value(root, 0, payload); // 将 JSON 数据转为字符串 + + json_value_destroy(root); // 销毁 JSON 对象 + // 如果请求体不为空且追加到请求成功 + if (!payload.empty() && req->append_output_body(payload)) + { + task->user_data = this; // 设置用户数据为当前任务对象 + return task; // 返回创建的任务 + } + } + + task->dismiss(); // 如果失败,销毁任务 + return NULL; // 返回空指针 +} + + +// 创建服务注销任务 +WFHttpTask *WFConsulTask::create_deregister_task() +{ + std::string url = this->proxy_url; // 初始化 URL 为代理地址 + + // 添加服务注销路径,包含服务 ID 和命名空间参数 + url += "/v1/agent/service/deregister/" + this->service.service_id; + url += "?ns=" + this->service.service_namespace; + + WFHttpTask *task = WFTaskFactory::create_http_task( // 创建 HTTP 任务 + url, 0, this->retry_max, register_callback); + + HttpRequest *req = task->get_req(); // 获取 HTTP 请求对象 + + req->set_method(HttpMethodPut); // 设置 HTTP 方法为 PUT + req->add_header_pair("Content-Type", "application/json"); // 添加内容类型头 + + // 如果存在鉴权 token,则添加到请求头 + std::string token = this->config.get_token(); + if (!token.empty()) + req->add_header_pair("X-Consul-Token", token); + + task->user_data = this; // 设置用户数据为当前任务对象 + return task; // 返回创建的任务 +} + + +// 检查任务执行结果 +bool WFConsulTask::check_task_result(WFHttpTask *task, WFConsulTask *consul_task) +{ + // 如果任务状态不是成功状态 + if (task->get_state() != WFT_STATE_SUCCESS) + { + consul_task->state = task->get_state(); // 设置任务状态 + consul_task->error = task->get_error(); // 设置错误信息 + return false; // 返回失败 + } + + // 获取任务的 HTTP 响应 + protocol::HttpResponse *resp = task->get_resp(); + + // 检查 HTTP 响应状态码是否为 "200" + if (strcmp(resp->get_status_code(), "200") != 0) + { + consul_task->state = WFT_STATE_TASK_ERROR; // 设置任务错误状态 + consul_task->error = WFT_ERR_CONSUL_CHECK_RESPONSE_FAILED; // 设置响应失败错误 + return false; // 返回失败 + } + + return true; // 返回成功 +} + + +// 从 HTTP 响应头中获取 Consul 索引 +long long WFConsulTask::get_consul_index(HttpResponse *resp) +{ + long long consul_index = 0; // 初始化 Consul 索引为 0 + + // 创建 HTTP 头游标以遍历响应头 + protocol::HttpHeaderCursor cursor(resp); + std::string consul_index_str; // 用于存储 Consul 索引字符串 + + // 查找 "X-Consul-Index" 响应头 + if (cursor.find("X-Consul-Index", consul_index_str)) + { + // 将字符串转换为长整型 + consul_index = strtoll(consul_index_str.c_str(), NULL, 10); + if (consul_index < 0) // 如果索引小于 0,则重置为 0 + consul_index = 0; + } + + return consul_index; // 返回 Consul 索引 +} + + +// 服务发现任务的回调函数 +void WFConsulTask::discover_callback(WFHttpTask *task) +{ + WFConsulTask *t = (WFConsulTask*)task->user_data; // 获取任务的用户数据 + + // 检查任务执行结果 + if (WFConsulTask::check_task_result(task, t)) + { + protocol::HttpResponse *resp = task->get_resp(); // 获取 HTTP 响应 + long long consul_index = t->get_consul_index(resp); // 获取当前 Consul 索引 + long long last_consul_index = t->get_consul_index(); // 获取上一次的 Consul 索引 + + // 更新 Consul 索引,如果当前索引小于上次索引,则重置为 0 + t->set_consul_index(consul_index < last_consul_index ? 0 : consul_index); + t->state = task->get_state(); // 设置任务状态 + } + + // 将 HTTP 响应转移到任务对象 + t->http_resp = std::move(*task->get_resp()); + t->finish = true; // 标记任务完成 +} + + +// 服务列表任务的回调函数 +void WFConsulTask::list_service_callback(WFHttpTask *task) +{ + WFConsulTask *t = (WFConsulTask*)task->user_data; // 获取任务的用户数据 + + // 检查任务执行结果 + if (WFConsulTask::check_task_result(task, t)) + t->state = task->get_state(); // 设置任务状态 + + // 将 HTTP 响应转移到任务对象 + t->http_resp = std::move(*task->get_resp()); + t->finish = true; // 标记任务完成 +} + + +// 服务注册任务的回调函数 +void WFConsulTask::register_callback(WFHttpTask *task) +{ + WFConsulTask *t = (WFConsulTask *)task->user_data; // 获取任务的用户数据 + + // 检查任务执行结果 + if (WFConsulTask::check_task_result(task, t)) + t->state = task->get_state(); // 设置任务状态 + + // 将 HTTP 响应转移到任务对象 + t->http_resp = std::move(*task->get_resp()); + t->finish = true; // 标记任务完成 +} + + +// 初始化 Consul 客户端 +int WFConsulClient::init(const std::string& proxy_url, ConsulConfig config) +{ + ParsedURI uri; // 定义用于存储解析后的 URI 的对象 + + // 解析代理 URL + if (URIParser::parse(proxy_url, uri) >= 0) + { + // 构建完整的代理 URL + this->proxy_url = uri.scheme; + this->proxy_url += "://"; + this->proxy_url += uri.host; + if (uri.port) // 如果指定了端口,则追加端口信息 + { + this->proxy_url += ":"; + this->proxy_url += uri.port; + } + + this->config = std::move(config); // 将配置赋值给客户端 + return 0; // 返回成功 + } + else if (uri.state == URI_STATE_INVALID) // 如果 URI 无效 + errno = EINVAL; // 设置错误码为无效参数 + + return -1; // 返回失败 +} + + +// 初始化 Consul 客户端(使用默认配置) +int WFConsulClient::init(const std::string& proxy_url) +{ + return this->init(proxy_url, ConsulConfig()); // 调用带配置参数的 init 函数 +} + + +// 创建服务发现任务 +WFConsulTask *WFConsulClient::create_discover_task( + const std::string& service_namespace, + const std::string& service_name, + int retry_max, + consul_callback_t cb) +{ + // 创建一个新的 Consul 任务 + WFConsulTask *task = new WFConsulTask(this->proxy_url, service_namespace, + service_name, "", retry_max, + std::move(cb)); + + task->set_api_type(CONSUL_API_TYPE_DISCOVER); // 设置任务类型为服务发现 + task->set_config(this->config); // 设置任务的配置信息 + return task; // 返回创建的任务 +} + + +// 创建服务列表任务 +WFConsulTask *WFConsulClient::create_list_service_task( + const std::string& service_namespace, + int retry_max, + consul_callback_t cb) +{ + // 创建一个新的 Consul 任务 + WFConsulTask *task = new WFConsulTask(this->proxy_url, service_namespace, + "", "", retry_max, + std::move(cb)); + + task->set_api_type(CONSUL_API_TYPE_LIST_SERVICE); // 设置任务类型为服务列表 + task->set_config(this->config); // 设置任务的配置信息 + return task; // 返回创建的任务 +} + + +// 创建服务注册任务 +WFConsulTask *WFConsulClient::create_register_task( + const std::string& service_namespace, + const std::string& service_name, + const std::string& service_id, + int retry_max, + consul_callback_t cb) +{ + // 创建一个新的 Consul 任务 + WFConsulTask *task = new WFConsulTask(this->proxy_url, service_namespace, + service_name, service_id, retry_max, + std::move(cb)); + + task->set_api_type(CONSUL_API_TYPE_REGISTER); // 设置任务类型为服务注册 + task->set_config(this->config); // 设置任务的配置信息 + return task; // 返回创建的任务 +} + + +// 创建服务注销任务 +WFConsulTask *WFConsulClient::create_deregister_task( + const std::string& service_namespace, + const std::string& service_id, + int retry_max, + consul_callback_t cb) +{ + // 创建一个新的 Consul 任务 + WFConsulTask *task = new WFConsulTask(this->proxy_url, service_namespace, + "", service_id, retry_max, + std::move(cb)); + + task->set_api_type(CONSUL_API_TYPE_DEREGISTER); // 设置任务类型为服务注销 + task->set_config(this->config); // 设置任务的配置信息 + return task; // 返回创建的任务 +} + + +// 创建带标签的地址对象 +static bool create_tagged_address(const ConsulAddress& consul_address, + const std::string& name, + json_object_t *tagged_obj) +{ + // 如果地址为空,直接返回成功 + if (consul_address.first.empty()) + return true; + + // 向 JSON 对象中添加名为 name 的嵌套对象 + const json_value_t *val = json_object_append(tagged_obj, name.c_str(), + JSON_VALUE_OBJECT); + if (!val) // 如果添加失败,返回 false + return false; + + // 获取新创建的嵌套对象 + json_object_t *obj = json_value_object(val); + if (!obj) // 如果对象获取失败,返回 false + return false; + + // 向嵌套对象中添加 "Address" 字段 + if (!json_object_append(obj, "Address", JSON_VALUE_STRING, + consul_address.first.c_str())) + return false; + + // 向嵌套对象中添加 "Port" 字段 + if (!json_object_append(obj, "Port", JSON_VALUE_NUMBER, + (double)consul_address.second)) + return false; + + return true; // 地址对象创建成功 +} + + +// 创建健康检查配置 +static bool create_health_check(const ConsulConfig& config, json_object_t *obj) +{ + const json_value_t *val; // 存储添加字段的返回值 + std::string str; // 临时字符串存储变量 + + // 如果未启用健康检查,直接返回成功 + if (!config.get_health_check()) + return true; + + // 在 JSON 对象中添加 "Check" 字段 + val = json_object_append(obj, "Check", JSON_VALUE_OBJECT); + if (!val) // 如果添加失败,返回 false + return false; + + obj = json_value_object(val); // 获取 "Check" 对象 + if (!obj) // 如果对象获取失败,返回 false + return false; + + // 添加健康检查的名称 + str = config.get_check_name(); + if (!json_object_append(obj, "Name", JSON_VALUE_STRING, str.c_str())) + return false; + + // 添加健康检查的备注 + str = config.get_check_notes(); + if (!json_object_append(obj, "Notes", JSON_VALUE_STRING, str.c_str())) + return false; + + // 添加健康检查的 HTTP URL + str = config.get_check_http_url(); + if (!str.empty()) // 如果 URL 不为空 + { + if (!json_object_append(obj, "HTTP", JSON_VALUE_STRING, str.c_str())) + return false; + + // 添加 HTTP 方法 + str = config.get_check_http_method(); + if (!json_object_append(obj, "Method", JSON_VALUE_STRING, str.c_str())) + return false; + + // 添加 HTTP 请求体 + str = config.get_http_body(); + if (!json_object_append(obj, "Body", JSON_VALUE_STRING, str.c_str())) + return false; + + // 添加 HTTP 头部信息 + val = json_object_append(obj, "Header", JSON_VALUE_OBJECT); + if (!val) + return false; + + json_object_t *header_obj = json_value_object(val); + if (!header_obj) + return false; + + // 遍历并添加所有 HTTP 头部字段 + for (const auto& header : *config.get_http_headers()) + { + val = json_object_append(header_obj, header.first.c_str(), + JSON_VALUE_ARRAY); + if (!val) + return false; + + json_array_t *arr = json_value_array(val); + if (!arr) + return false; + + // 添加头部字段对应的多个值 + for (const auto& value : header.second) + { + if (!json_array_append(arr, JSON_VALUE_STRING, value.c_str())) + return false; + } + } + } + + // 添加 TCP 检查地址 + str = config.get_check_tcp(); + if (!str.empty()) + { + if (!json_object_append(obj, "TCP", JSON_VALUE_STRING, str.c_str())) + return false; + } + + // 添加初始状态 + str = config.get_initial_status(); + if (!json_object_append(obj, "Status", JSON_VALUE_STRING, str.c_str())) + return false; + + // 添加自动注销时间 + str = convert_time_to_str(config.get_auto_deregister_time()); + if (!json_object_append(obj, "DeregisterCriticalServiceAfter", + JSON_VALUE_STRING, str.c_str())) + return false; + + // 添加检查间隔时间 + str = convert_time_to_str(config.get_check_interval()); + if (!json_object_append(obj, "Interval", JSON_VALUE_STRING, str.c_str())) + return false; + + // 添加检查超时时间 + str = convert_time_to_str(config.get_check_timeout()); + if (!json_object_append(obj, "Timeout", JSON_VALUE_STRING, str.c_str())) + return false; + + // 添加连续成功次数限制 + if (!json_object_append(obj, "SuccessBeforePassing", JSON_VALUE_NUMBER, + (double)config.get_success_times())) + return false; + + // 添加连续失败次数限制 + if (!json_object_append(obj, "FailuresBeforeCritical", JSON_VALUE_NUMBER, + (double)config.get_failure_times())) + return false; + + return true; // 健康检查配置创建成功 +} + + +// 创建服务注册请求 +static bool create_register_request(const json_value_t *root, + const struct ConsulService *service, + const ConsulConfig& config) +{ + const json_value_t *val; // 临时存储 JSON 值 + json_object_t *obj; // 临时存储 JSON 对象 + + obj = json_value_object(root); // 获取根对象 + if (!obj) + return false; + + // 添加服务 ID + if (!json_object_append(obj, "ID", JSON_VALUE_STRING, + service->service_id.c_str())) + return false; + + // 添加服务名称 + if (!json_object_append(obj, "Name", JSON_VALUE_STRING, + service->service_name.c_str())) + return false; + + // 如果命名空间非空,则添加命名空间 + if (!service->service_namespace.empty()) + { + if (!json_object_append(obj, "ns", JSON_VALUE_STRING, + service->service_namespace.c_str())) + return false; + } + + // 添加服务标签数组 + val = json_object_append(obj, "Tags", JSON_VALUE_ARRAY); + if (!val) + return false; + + json_array_t *arr = json_value_array(val); + if (!arr) + return false; + + // 遍历并添加所有标签 + for (const auto& tag : service->tags) + { + if (!json_array_append(arr, JSON_VALUE_STRING, tag.c_str())) + return false; + } + + // 添加服务地址 + if (!json_object_append(obj, "Address", JSON_VALUE_STRING, + service->service_address.first.c_str())) + return false; + + // 添加服务端口 + if (!json_object_append(obj, "Port", JSON_VALUE_NUMBER, + (double)service->service_address.second)) + return false; + + // 添加元数据对象 + val = json_object_append(obj, "Meta", JSON_VALUE_OBJECT); + if (!val) + return false; + + json_object_t *meta_obj = json_value_object(val); + if (!meta_obj) + return false; + + // 遍历并添加所有元数据 + for (const auto& meta_kv : service->meta) + { + if (!json_object_append(meta_obj, meta_kv.first.c_str(), + JSON_VALUE_STRING, meta_kv.second.c_str())) + return false; + } + + // 添加标签覆盖选项 + int type = service->tag_override ? JSON_VALUE_TRUE : JSON_VALUE_FALSE; + if (!json_object_append(obj, "EnableTagOverride", type)) + return false; + + // 添加带标签的地址 + val = json_object_append(obj, "TaggedAddresses", JSON_VALUE_OBJECT); + if (!val) + return false; + + json_object_t *tagged_obj = json_value_object(val); + if (!tagged_obj) + return false; + + // 创建所有类型的带标签地址 + if (!create_tagged_address(service->lan, "lan", tagged_obj)) + return false; + + if (!create_tagged_address(service->lan_ipv4, "lan_ipv4", tagged_obj)) + return false; + + if (!create_tagged_address(service->lan_ipv6, "lan_ipv6", tagged_obj)) + return false; + + if (!create_tagged_address(service->virtual_address, "virtual", tagged_obj)) + return false; + + if (!create_tagged_address(service->wan, "wan", tagged_obj)) + return false; + + if (!create_tagged_address(service->wan_ipv4, "wan_ipv4", tagged_obj)) + return false; + + if (!create_tagged_address(service->wan_ipv6, "wan_ipv6", tagged_obj)) + return false; + + // 创建健康检查配置 + if (!create_health_check(config, obj)) + return false; + + return true; // 服务注册请求创建成功 +} + + +// 解析服务列表结果 +static bool parse_list_service_result(const json_value_t *root, + std::vector& result) +{ + const json_object_t *obj; // 存储 JSON 对象 + const json_value_t *val; // 存储 JSON 值 + const json_array_t *arr; // 存储 JSON 数组 + const char *key; // 存储键 + const char *str; // 存储字符串值 + + // 将根值转换为 JSON 对象 + obj = json_value_object(root); + if (!obj) // 如果转换失败,返回 false + return false; + + // 遍历 JSON 对象中的每个键值对 + json_object_for_each(key, val, obj) + { + struct ConsulServiceTags instance; // 定义一个服务标签实例 + + instance.service_name = key; // 将键作为服务名称 + arr = json_value_array(val); // 获取值作为数组 + if (!arr) // 如果值不是数组,返回 false + return false; + + const json_value_t *tag_val; // 遍历数组的每个值 + json_array_for_each(tag_val, arr) + { + str = json_value_string(tag_val); // 获取值的字符串形式 + if (!str) // 如果值不是字符串,返回 false + return false; + + instance.tags.emplace_back(str); // 将标签添加到实例 + } + + result.emplace_back(std::move(instance)); // 将实例添加到结果列表 + } + + return true; // 返回成功 +} + + +// 解析发现节点信息 +static bool parse_discover_node(const json_object_t *obj, + struct ConsulServiceInstance *instance) +{ + const json_value_t *val; // 存储 JSON 值 + const char *str; // 存储字符串值 + + // 查找并解析 "Node" 信息 + val = json_object_find("Node", obj); + if (!val) + return false; + + obj = json_value_object(val); // 获取 "Node" 对象 + if (!obj) + return false; + + // 获取 "ID" 字段 + val = json_object_find("ID", obj); + if (!val) + return false; + + str = json_value_string(val); // 转换为字符串 + if (!str) + return false; + + instance->node_id = str; // 设置节点 ID + + // 获取 "Node" 字段 + val = json_object_find("Node", obj); + if (!val) + return false; + + str = json_value_string(val); + if (!str) + return false; + + instance->node_name = str; // 设置节点名称 + + // 获取 "Address" 字段 + val = json_object_find("Address", obj); + if (!val) + return false; + + str = json_value_string(val); + if (!str) + return false; + + instance->node_address = str; // 设置节点地址 + + // 获取 "Datacenter" 字段 + val = json_object_find("Datacenter", obj); + if (!val) + return false; + + str = json_value_string(val); + if (!str) + return false; + + instance->dc = str; // 设置数据中心 + + // 解析 "Meta" 信息 + val = json_object_find("Meta", obj); + if (!val) + return false; + + const json_object_t *meta_obj = json_value_object(val); // 获取 "Meta" 对象 + if (!meta_obj) + return false; + + const char *meta_k; // 存储元数据键 + const json_value_t *meta_v; // 存储元数据值 + + // 遍历 "Meta" 对象 + json_object_for_each(meta_k, meta_v, meta_obj) + { + str = json_value_string(meta_v); // 获取元数据值 + if (!str) + return false; + + instance->node_meta[meta_k] = str; // 添加元数据键值对 + } + + // 获取 "CreateIndex" 字段 + val = json_object_find("CreateIndex", obj); + if (val) + instance->create_index = json_value_number(val); // 设置创建索引 + + // 获取 "ModifyIndex" 字段 + val = json_object_find("ModifyIndex", obj); + if (val) + instance->modify_index = json_value_number(val); // 设置修改索引 + + return true; // 返回成功 +} + + +// 解析服务发现结果 +static bool parse_discover_result(const json_value_t *root, + std::vector& result) +{ + const json_array_t *arr = json_value_array(root); // 获取 JSON 数组 + const json_value_t *val; // 存储数组值 + const json_object_t *obj; // 存储 JSON 对象 + + if (!arr) // 如果不是数组,返回 false + return false; + + // 遍历数组 + json_array_for_each(val, arr) + { + struct ConsulServiceInstance instance; // 创建服务实例 + + obj = json_value_object(val); // 获取数组中的对象 + if (!obj) + return false; + + // 解析节点信息 + if (!parse_discover_node(obj, &instance)) + return false; + + // 解析服务信息 + if (!parse_service(obj, &instance.service)) + return false; + + // 解析健康检查 + parse_health_check(obj, &instance); + + result.emplace_back(std::move(instance)); // 添加实例到结果列表 + } + + return true; // 返回成功 +} + + +// 解析服务信息 +static bool parse_service(const json_object_t *obj, + struct ConsulService *service) +{ + const json_value_t *val; // 用于存储 JSON 值 + const char *str; // 用于存储字符串值 + + // 获取 "Service" 对象 + val = json_object_find("Service", obj); + if (!val) + return false; + + obj = json_value_object(val); // 将值转换为对象 + if (!obj) + return false; + + // 解析服务 ID + val = json_object_find("ID", obj); + if (!val) + return false; + + str = json_value_string(val); // 将值转换为字符串 + if (!str) + return false; + + service->service_id = str; // 设置服务 ID + + // 解析服务名称 + val = json_object_find("Service", obj); + if (!val) + return false; + + str = json_value_string(val); + if (!str) + return false; + + service->service_name = str; // 设置服务名称 + + // 解析命名空间 + val = json_object_find("Namespace", obj); + if (val) + { + str = json_value_string(val); + if (!str) + return false; + + service->service_namespace = str; // 设置命名空间 + } + + // 解析服务地址 + val = json_object_find("Address", obj); + if (!val) + return false; + + str = json_value_string(val); + if (!str) + return false; + + service->service_address.first = str; // 设置服务地址 + + // 解析服务端口 + val = json_object_find("Port", obj); + if (!val) + return false; + + service->service_address.second = json_value_number(val); // 设置服务端口 + + // 解析带标签地址 + val = json_object_find("TaggedAddresses", obj); + if (!val) + return false; + + parse_tagged_address("lan", val, service->lan); + parse_tagged_address("lan_ipv4", val, service->lan_ipv4); + parse_tagged_address("lan_ipv6", val, service->lan_ipv6); + parse_tagged_address("virtual", val, service->virtual_address); + parse_tagged_address("wan", val, service->wan); + parse_tagged_address("wan_ipv4", val, service->wan_ipv4); + parse_tagged_address("wan_ipv6", val, service->wan_ipv6); + + // 解析标签列表 + val = json_object_find("Tags", obj); + if (!val) + return false; + + const json_array_t *tags_arr = json_value_array(val); // 获取数组 + if (tags_arr) + { + const json_value_t *tags_value; + json_array_for_each(tags_value, tags_arr) // 遍历数组 + { + str = json_value_string(tags_value); // 获取标签字符串 + if (!str) + return false; + + service->tags.emplace_back(str); // 添加标签到服务 + } + } + + // 解析元数据 + val = json_object_find("Meta", obj); + if (!val) + return false; + + const json_object_t *meta_obj = json_value_object(val); // 获取元数据对象 + if (!meta_obj) + return false; + + const char *meta_k; + const json_value_t *meta_v; + json_object_for_each(meta_k, meta_v, meta_obj) // 遍历元数据 + { + str = json_value_string(meta_v); + if (!str) + return false; + + service->meta[meta_k] = str; // 添加元数据键值对 + } + + // 检查标签覆盖选项 + val = json_object_find("EnableTagOverride", obj); + if (val) + service->tag_override = (json_value_type(val) == JSON_VALUE_TRUE); + + return true; // 返回成功 +} + + +// 解析健康检查信息 +static bool parse_health_check(const json_object_t *obj, + struct ConsulServiceInstance *instance) +{ + const json_value_t *val; // 存储 JSON 值 + const char *str; // 存储字符串值 + + // 获取 "Checks" 数组 + val = json_object_find("Checks", obj); + if (!val) + return false; + + const json_array_t *check_arr = json_value_array(val); // 转换为数组 + if (!check_arr) + return false; + + const json_value_t *arr_val; + json_array_for_each(arr_val, check_arr) // 遍历数组 + { + obj = json_value_object(arr_val); // 获取数组中的对象 + if (!obj) + return false; + + // 解析服务名称 + val = json_object_find("ServiceName", obj); + if (!val) + return false; + + str = json_value_string(val); + if (!str) + return false; + + std::string check_service_name = str; + + // 解析服务 ID + val = json_object_find("ServiceID", obj); + if (!val) + return false; + + str = json_value_string(val); + if (!str) + return false; + + std::string check_service_id = str; + if (check_service_id.empty() || check_service_name.empty()) + continue; + + // 解析检查 ID + val = json_object_find("CheckID", obj); + if (!val) + return false; + + str = json_value_string(val); + if (!str) + return false; + + instance->check_id = str; + + // 解析检查名称 + val = json_object_find("Name", obj); + if (!val) + return false; + + str = json_value_string(val); + if (!str) + return false; + + instance->check_name = str; + + // 解析检查状态 + val = json_object_find("Status", obj); + if (!val) + return false; + + str = json_value_string(val); + if (!str) + return false; + + instance->check_status = str; + + // 解析备注 + val = json_object_find("Notes", obj); + if (val) + { + str = json_value_string(val); + if (!str) + return false; + + instance->check_notes = str; + } + + // 解析输出 + val = json_object_find("Output", obj); + if (val) + { + str = json_value_string(val); + if (!str) + return false; + + instance->check_output = str; + } + + // 解析检查类型 + val = json_object_find("Type", obj); + if (val) + { + str = json_value_string(val); + if (!str) + return false; + + instance->check_type = str; + } + + break; // 只解析一个有效的健康检查 + } + + return true; // 返回成功 +} + +// 解析服务发现结果 +static bool parse_discover_result(const json_value_t *root, + std::vector& result) +{ + const json_array_t *arr = json_value_array(root); // 转换为数组 + const json_value_t *val; // 存储数组中的值 + const json_object_t *obj; // 存储 JSON 对象 + + if (!arr) + return false; + + // 遍历数组 + json_array_for_each(val, arr) + { + struct ConsulServiceInstance instance; // 定义服务实例 + + obj = json_value_object(val); // 获取数组中的对象 + if (!obj) + return false; + + // 解析节点信息 + if (!parse_discover_node(obj, &instance)) + return false; + + // 解析服务信息 + if (!parse_service(obj, &instance.service)) + return false; + + // 解析健康检查 + parse_health_check(obj, &instance); + + result.emplace_back(std::move(instance)); // 添加实例到结果 + } + + return true; // 返回成功 +} + + +// 打印 JSON 对象,递归地将其转换为字符串格式 +static void print_json_object(const json_object_t *obj, int depth, + std::string& json_str) +{ + const char *name; // JSON 对象的键 + const json_value_t *val; // JSON 对象的值 + int n = 0; // 键值对的计数器 + int i; + + json_str += "{\n"; // 开始对象 + + // 遍历 JSON 对象中的每个键值对 + json_object_for_each(name, val, obj) + { + if (n != 0) // 如果不是第一个键值对,添加逗号换行 + json_str += ",\n"; + + n++; // 键值对计数加 1 + for (i = 0; i < depth + 1; i++) // 根据深度添加缩进 + json_str += " "; + + // 添加键 + json_str += "\""; + json_str += name; + json_str += "\": "; + + // 递归打印值 + print_json_value(val, depth + 1, json_str); + } + + json_str += "\n"; // 对象内容结束 + for (i = 0; i < depth; i++) // 根据深度添加缩进 + json_str += " "; + + json_str += "}"; // 结束对象 +} + + +// 打印 JSON 数组,递归地将其转换为字符串格式 +static void print_json_array(const json_array_t *arr, int depth, + std::string& json_str) +{ + const json_value_t *val; // JSON 数组的值 + int n = 0; // 数组值的计数器 + int i; + + json_str += "[\n"; // 开始数组 + + // 遍历 JSON 数组中的每个值 + json_array_for_each(val, arr) + { + if (n != 0) // 如果不是第一个值,添加逗号换行 + json_str += ",\n"; + + n++; // 值计数加 1 + for (i = 0; i < depth + 1; i++) // 根据深度添加缩进 + json_str += " "; + + // 递归打印值 + print_json_value(val, depth + 1, json_str); + } + + json_str += "\n"; // 数组内容结束 + for (i = 0; i < depth; i++) // 根据深度添加缩进 + json_str += " "; + + json_str += "]"; // 结束数组 +} + + +// 打印 JSON 字符串,处理特殊字符转义 +static void print_json_string(const char *str, std::string& json_str) +{ + json_str += "\""; // 开始字符串 + + // 遍历字符串中的每个字符 + while (*str) + { + switch (*str) + { + case '\r': // 回车符转义 + json_str += "\\r"; + break; + case '\n': // 换行符转义 + json_str += "\\n"; + break; + case '\f': // 换页符转义 + json_str += "\\f"; + break; + case '\b': // 退格符转义 + json_str += "\\b"; + break; + case '\"': // 双引号转义 + json_str += "\\\""; + break; + case '\t': // 制表符转义 + json_str += "\\t"; + break; + case '\\': // 反斜杠转义 + json_str += "\\\\"; + break; + default: // 其他字符直接添加 + json_str += *str; + break; + } + str++; // 指向下一个字符 + } + json_str += "\""; // 结束字符串 +} + + +// 打印 JSON 数字 +static void print_json_number(double number, std::string& json_str) +{ + long long integer = number; // 检查数字是否是整数 + + if (integer == number) // 如果是整数 + json_str += std::to_string(integer); // 转换为整数字符串 + else // 如果是浮点数 + json_str += std::to_string(number); // 转换为浮点数字符串 +} + + +// 根据值的类型打印 JSON 值 +static void print_json_value(const json_value_t *val, int depth, + std::string& json_str) +{ + switch (json_value_type(val)) // 获取值的类型 + { + case JSON_VALUE_STRING: // 如果是字符串 + print_json_string(json_value_string(val), json_str); + break; + case JSON_VALUE_NUMBER: // 如果是数字 + print_json_number(json_value_number(val), json_str); + break; + case JSON_VALUE_OBJECT: // 如果是对象 + print_json_object(json_value_object(val), depth, json_str); + break; + case JSON_VALUE_ARRAY: // 如果是数组 + print_json_array(json_value_array(val), depth, json_str); + break; + case JSON_VALUE_TRUE: // 如果是布尔值 true + json_str += "true"; + break; + case JSON_VALUE_FALSE: // 如果是布尔值 false + json_str += "false"; + break; + case JSON_VALUE_NULL: // 如果是 null + json_str += "null"; + break; + } +} + From 5b5972a1724e96bc8f07a843aefcffb3d09f53ed Mon Sep 17 00:00:00 2001 From: pm5lov8b3 <1584615561@qq.com> Date: Sat, 30 Nov 2024 08:21:52 +0800 Subject: [PATCH 2/8] ADD file via upload --- WFDnsClient.cc | 308 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100644 WFDnsClient.cc diff --git a/WFDnsClient.cc b/WFDnsClient.cc new file mode 100644 index 0000000..b74afca --- /dev/null +++ b/WFDnsClient.cc @@ -0,0 +1,308 @@ +/* + Copyright (c) 2021 Sogou, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Author: Liu Kai (liukaidx@sogou-inc.com) +*/ + +#include +#include +#include +#include "URIParser.h" +#include "StringUtil.h" +#include "WFDnsClient.h" + +using namespace protocol; + +using DnsCtx = std::function; +using ComplexTask = WFComplexClientTask; + +// 定义一个DnsParams类,用于存储DNS查询参数 +class DnsParams +{ +public: + // 定义一个内部结构体dns_params,用于存储具体的DNS参数 + struct dns_params + { + std::vector uris; // 存储解析后的URI + std::vector search_list; // 搜索列表 + int ndots; // 域名中允许的最小点数 + int attempts; // 最大尝试次数 + bool rotate; // 是否轮询 + }; + +public: + // DnsParams类的构造函数 + DnsParams() + { + this->ref = new std::atomic(1); // 初始化引用计数为1 + this->params = new dns_params(); // 初始化参数结构体 + } + + // DnsParams类的拷贝构造函数 + DnsParams(const DnsParams& p) + { + this->ref = p.ref; // 拷贝引用计数指针 + this->params = p.params; // 拷贝参数结构体指针 + this->incref(); // 增加引用计数 + } + + // DnsParams类的赋值运算符 + DnsParams& operator=(const DnsParams& p) + { + if (this != &p) // 如果不是自赋值 + { + this->decref(); // 减少当前对象的引用计数 + this->ref = p.ref; // 拷贝引用计数指针 + this->params = p.params; // 拷贝参数结构体指针 + this->incref(); // 增加引用计数 + } + return *this; // 返回当前对象的引用 + } + + // DnsParams类的析构函数 + ~DnsParams() { this->decref(); } // 减少引用计数 + + // 获取const类型的参数指针 + const dns_params *get_params() const { return this->params; } + // 获取非const类型的参数指针 + dns_params *get_params() { return this->params; } + +private: + // 增加引用计数 + void incref() { (*this->ref)++; } + // 减少引用计数,并在计数为0时释放资源 + void decref() + { + if (--*this->ref == 0) + { + delete this->params; // 删除参数结构体 + delete this->ref; // 删除引用计数 + } + } + +private: + dns_params *params; // 指向参数结构体的指针 + std::atomic *ref; // 指向引用计数的指针 +}; + +// 定义DNS状态枚举 +enum +{ + DNS_STATUS_TRY_ORIGIN_DONE = 0, + DNS_STATUS_TRY_ORIGIN_FIRST = 1, + DNS_STATUS_TRY_ORIGIN_LAST = 2 +}; + +// 定义DnsStatus结构体,用于存储DNS查询状态 +struct DnsStatus +{ + std::string origin_name; // 原始域名 + std::string current_name; // 当前域名 + size_t next_server; // 下一个要尝试的服务器 + size_t last_server; // 上一个尝试的服务器 + size_t next_domain; // 下一个要尝试的搜索域 + int attempts_left; // 剩余尝试次数 + int try_origin_state; // 尝试原始域名的状态 +}; + +// 计算字符串中点的数量 +static int __get_ndots(const std::string& s) +{ + int ndots = 0; + for (size_t i = 0; i < s.size(); i++) + ndots += s[i] == '.'; // 统计点的数量 + return ndots; +} + +// 检查是否有下一个域名要尝试 +static bool __has_next_name(const DnsParams::dns_params *p, + struct DnsStatus *s) +{ + if (s->try_origin_state == DNS_STATUS_TRY_ORIGIN_FIRST) + { + s->current_name = s->origin_name; // 设置当前域名为原始域名 + s->try_origin_state = DNS_STATUS_TRY_ORIGIN_DONE; // 更新状态 + return true; + } + + if (s->next_domain < p->search_list.size()) // 如果还有搜索域要尝试 + { + s->current_name = s->origin_name; // 设置当前域名为原始域名 + s->current_name.push_back('.'); // 添加点 + s->current_name.append(p->search_list[s->next_domain]); // 添加搜索域 + + s->next_domain++; // 移动到下一个搜索域 + return true; + } + + if (s->try_origin_state == DNS_STATUS_TRY_ORIGIN_LAST) + { + s->current_name = s->origin_name; // 设置当前域名为原始域名 + s->try_origin_state = DNS_STATUS_TRY_ORIGIN_DONE; // 更新状态 + return true; + } + + return false; // 没有下一个域名要尝试 +} + +// DNS查询回调内部函数 +static void __callback_internal(WFDnsTask *task, const DnsParams& params, + struct DnsStatus& s) +{ + ComplexTask *ctask = static_cast(task); // 转换任务类型 + int state = task->get_state(); // 获取任务状态 + DnsRequest *req = task->get_req(); // 获取DNS请求 + DnsResponse *resp = task->get_resp(); // 获取DNS响应 + const auto *p = params.get_params(); // 获取DNS参数 + int rcode = resp->get_rcode(); // 获取响应码 + + bool try_next_server = state != WFT_STATE_SUCCESS || // 如果状态不是成功 + rcode == DNS_RCODE_SERVER_FAILURE || // 或者响应码是服务器失败 + rcode == DNS_RCODE_NOT_IMPLEMENTED || // 或者响应码是未实现 + rcode == DNS_RCODE_REFUSED; // 或者响应码是拒绝 + bool try_next_name = rcode == DNS_RCODE_FORMAT_ERROR || // 如果响应码是格式错误 + rcode == DNS_RCODE_NAME_ERROR || // 或者响应码是名字错误 + resp->get_ancount() == 0; // 或者响应中没有答案 + + if (try_next_server) + { + if (s.last_server == s.next_server) // 如果已经是最后一个服务器 + s.attempts_left--; // 减少尝试次数 + if (s.attempts_left <= 0) // 如果尝试次数用完 + return; // 返回 + + s.next_server = (s.next_server + 1) % p->uris.size(); // 计算下一个服务器 + ctask->set_redirect(p->uris[s.next_server]); // 设置重定向 + return; // 返回 + } + + if (try_next_name && __has_next_name(p, &s)) // 如果需要尝试下一个名字 + { + req->set_question_name(s.current_name.c_str()); // 设置查询名字 + ctask->set_redirect(p->uris[s.next_server]); // 设置重定向 + return; // 返回 + } +} + +// WFDnsClient类的初始化函数,带一个URL参数 +int WFDnsClient::init(const std::string& url) +{ + return this->init(url, "", 1, 2, false); // 调用另一个初始化函数 +} + +// WFDnsClient类的初始化函数,用于配置DNS客户端 +int WFDnsClient::init(const std::string& url, const std::string& search_list, + int ndots, int attempts, bool rotate) +{ + std::vector hosts; // 用于存储分割后的主机名 + std::vector uris; // 用于存储解析后的URI + std::string host; // 单个主机名字符串 + ParsedURI uri; // 用于存储解析后的单个URI + + this->id = 0; // 初始化客户端ID为0 + hosts = StringUtil::split_filter_empty(url, ','); // 根据逗号分割URL字符串,获取主机名列表 + + // 遍历主机名列表,对每个主机名进行处理 + for (size_t i = 0; i < hosts.size(); i++) + { + host = hosts[i]; // 获取当前主机名 + // 检查主机名是否以"dns://"或"dnss://"开头,如果不是,则添加"dns://"前缀 + if (strncasecmp(host.c_str(), "dns://", 6) != 0 && + strncasecmp(host.c_str(), "dnss://", 7) != 0) + { + host = "dns://" + host; + } + + // 使用URIParser解析当前主机名,如果解析失败则返回错误码-1 + if (URIParser::parse(host, uri) != 0) + return -1; + + // 将解析后的URI添加到uris列表中 + uris.emplace_back(std::move(uri)); + } + + // 如果uris列表为空,或者ndots小于0,或者attempts小于1,则设置errno为EINVAL并返回错误码-1 + if (uris.empty() || ndots < 0 || attempts < 1) + { + errno = EINVAL; + return -1; + } + + // 创建一个新的DnsParams对象来存储DNS参数 + this->params = new DnsParams; + DnsParams::dns_params *q = ((DnsParams *)this->params)->get_params(); // 获取DNS参数的指针 + q->uris = std::move(uris); // 将解析后的URI列表移动到DNS参数中 + q->search_list = StringUtil::split_filter_empty(search_list, ','); // 根据逗号分割search_list字符串,获取搜索域列表 + // 设置ndots的值,如果大于15则设置为15 + q->ndots = ndots > 15 ? 15 : ndots; + // 设置attempts的值,如果大于5则设置为5 + q->attempts = attempts > 5 ? 5 : attempts; + q->rotate = rotate; // 设置是否轮询 + + return 0; // 初始化成功,返回0 +} + +// WFDnsClient类的析构函数,用于释放资源 +void WFDnsClient::deinit() +{ + delete (DnsParams *)this->params; // 删除分配的DnsParams对象 + this->params = NULL; // 将params指针设置为NULL +} + +// WFDnsClient类的方法,用于创建一个新的DNS任务 +WFDnsTask *WFDnsClient::create_dns_task(const std::string& name, + dns_callback_t callback) +{ + DnsParams::dns_params *p = ((DnsParams *)this->params)->get_params(); // 获取DNS参数 + struct DnsStatus status; // 创建DNS状态结构体 + size_t next_server; // 下一个要尝试的服务器索引 + WFDnsTask *task; // 指向新创建的DNS任务的指针 + DnsRequest *req; // 指向DNS请求的指针 + + // 如果启用轮询,则计算下一个服务器索引,否则使用第一个服务器 + next_server = p->rotate ? this->id++ % p->uris.size() : 0; + + status.origin_name = name; // 设置原始域名 + status.next_domain = 0; // 设置下一个要尝试的搜索域索引 + status.attempts_left = p->attempts; // 设置剩余尝试次数 + status.try_origin_state = DNS_STATUS_TRY_ORIGIN_FIRST; // 设置尝试原始域名的状态 + + // 如果域名以点结尾,则跳过搜索域 + if (!name.empty() && name.back() == '.') + status.next_domain = p->search_list.size(); + // 如果域名中的点数少于ndots,则设置尝试原始域名的状态为最后尝试 + else if (__get_ndots(name) < p->ndots) + status.try_origin_state = DNS_STATUS_TRY_ORIGIN_LAST; + + // 检查是否有下一个域名要尝试,并更新状态 + __has_next_name(p, &status); + + // 创建一个新的DNS任务,使用下一个服务器的URI和提供的回调函数 + task = WFTaskFactory::create_dns_task(p->uris[next_server], 0, std::move(callback)); + status.next_server = next_server; // 设置当前服务器索引 + status.last_server = (next_server + p->uris.size() - 1) % p->uris.size(); // 设置最后一个服务器索引 + + req = task->get_req(); // 获取DNS请求对象 + req->set_question(status.current_name.c_str(), DNS_TYPE_A, DNS_CLASS_IN); // 设置DNS请求的问题部分 + req->set_rd(1); // 设置DNS请求的递归标志 + + ComplexTask *ctask = static_cast(task); // 将任务转换为ComplexTask类型 + // 设置任务的上下文回调,当DNS任务完成时,将调用__callback_internal函数 + *ctask->get_mutable_ctx() = std::bind(__callback_internal, + std::placeholders::_1, + *(DnsParams *)params, status); + + return task; // 返回新创建的DNS任务 +} From f28954beaeba2a5b696dc388625eac2c9288fd9e Mon Sep 17 00:00:00 2001 From: p8keuqptb <2096779240@qq.com> Date: Tue, 17 Dec 2024 00:16:02 +0800 Subject: [PATCH 3/8] ADD file via upload --- dns_parser.c | 1206 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1206 insertions(+) create mode 100644 dns_parser.c diff --git a/dns_parser.c b/dns_parser.c new file mode 100644 index 0000000..78022ed --- /dev/null +++ b/dns_parser.c @@ -0,0 +1,1206 @@ +/* + Copyright (c) 2021 Sogou, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Author: Liu Kai (liukaidx@sogou-inc.com) +*/ + +#include +#include +#include +#include "dns_parser.h" + +#define DNS_LABELS_MAX 63 +#define DNS_NAMES_MAX 256 +#define DNS_MSGBASE_INIT_SIZE 514 // 512 + 2(leading length) +#define MAX(x, y) ((x) <= (y) ? (y) : (x)) + +struct __dns_record_entry +{ + struct list_head entry_list; + struct dns_record record; +}; + + +static inline uint8_t __dns_parser_uint8(const char *ptr) +{ + return (unsigned char)ptr[0]; +} + +static inline uint16_t __dns_parser_uint16(const char *ptr) +{ + const unsigned char *p = (const unsigned char *)ptr; + return ((uint16_t)p[0] << 8) + + ((uint16_t)p[1]); +} + +static inline uint32_t __dns_parser_uint32(const char *ptr) +{ + const unsigned char *p = (const unsigned char *)ptr; + return ((uint32_t)p[0] << 24) + + ((uint32_t)p[1] << 16) + + ((uint32_t)p[2] << 8) + + ((uint32_t)p[3]); +} + +/* + * Parse a single . + * is a domain name represented as a series of labels, and + * terminated by a label with zero length. + * + * phost must point to an char array with at least DNS_NAMES_MAX+1 size + */ +static int __dns_parser_parse_host(char *phost, dns_parser_t *parser) +{ + uint8_t len; + uint16_t pointer; + size_t hcur; + const char *msgend; + const char **cur; + const char *curbackup; // backup cur when host label is pointer + + msgend = (const char *)parser->msgbuf + parser->msgsize; + cur = &(parser->cur); + curbackup = NULL; + hcur = 0; + + if (*cur >= msgend) + return -2; + + while (*cur < msgend) + { + len = __dns_parser_uint8(*cur); + + if ((len & 0xC0) == 0) + { + (*cur)++; + if (len == 0) + break; + if (len > DNS_LABELS_MAX || *cur + len > msgend || + hcur + len + 1 > DNS_NAMES_MAX) + return -2; + + memcpy(phost + hcur, *cur, len); + *cur += len; + hcur += len; + phost[hcur++] = '.'; + } + // RFC 1035, 4.1.4 Message compression + else if ((len & 0xC0) == 0xC0) + { + pointer = __dns_parser_uint16(*cur) & 0x3FFF; + + if (pointer >= parser->msgsize) + return -2; + + // pointer must point to a prior position + if ((const char *)parser->msgbase + pointer >= *cur) + return -2; + + *cur += 2; + + // backup cur only when the first pointer occurs + if (curbackup == NULL) + curbackup = *cur; + *cur = (const char *)parser->msgbase + pointer; + } + else + return -2; + } + if (curbackup != NULL) + *cur = curbackup; + + if (hcur > 1 && phost[hcur - 1] == '.') + hcur--; + + if (hcur == 0) + phost[hcur++] = '.'; + phost[hcur++] = '\0'; + + return 0; +} + +static void __dns_parser_free_record(struct __dns_record_entry *r) +{ + switch (r->record.type) + { + case DNS_TYPE_SOA: + { + struct dns_record_soa *soa; + soa = (struct dns_record_soa *)(r->record.rdata); + free(soa->mname); + free(soa->rname); + break; + } + case DNS_TYPE_SRV: + { + struct dns_record_srv *srv; + srv = (struct dns_record_srv *)(r->record.rdata); + free(srv->target); + break; + } + case DNS_TYPE_MX: + { + struct dns_record_mx *mx; + mx = (struct dns_record_mx *)(r->record.rdata); + free(mx->exchange); + break; + } + } + free(r->record.name); + free(r); +} + +static void __dns_parser_free_record_list(struct list_head *head) +{ + struct list_head *pos, *tmp; + struct __dns_record_entry *entry; + + list_for_each_safe(pos, tmp, head) + { + entry = list_entry(pos, struct __dns_record_entry, entry_list); + list_del(pos); + __dns_parser_free_record(entry); + } +} + +/* + * A RDATA format, from RFC 1035: + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | ADDRESS | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * + * ADDRESS: A 32 bit Internet address. + * Hosts that have multiple Internet addresses will have multiple A records. + */ +static int __dns_parser_parse_a(struct __dns_record_entry **r, + uint16_t rdlength, + dns_parser_t *parser) +{ + const char **cur; + struct __dns_record_entry *entry; + size_t entry_size; + + if (sizeof (struct in_addr) != rdlength) + return -2; + + cur = &(parser->cur); + entry_size = sizeof (struct __dns_record_entry) + sizeof (struct in_addr); + entry = (struct __dns_record_entry *)malloc(entry_size); + if (!entry) + return -1; + + entry->record.rdata = (void *)(entry + 1); + memcpy(entry->record.rdata, *cur, rdlength); + *cur += rdlength; + *r = entry; + + return 0; +} + +/* + * AAAA RDATA format, from RFC 3596: + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | ADDRESS | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * + * ADDRESS: A 128 bit Internet address. + * Hosts that have multiple addresses will have multiple AAAA records. + */ +static int __dns_parser_parse_aaaa(struct __dns_record_entry **r, + uint16_t rdlength, + dns_parser_t *parser) +{ + const char **cur; + struct __dns_record_entry *entry; + size_t entry_size; + + if (sizeof (struct in6_addr) != rdlength) + return -2; + + cur = &(parser->cur); + entry_size = sizeof (struct __dns_record_entry) + sizeof (struct in6_addr); + entry = (struct __dns_record_entry *)malloc(entry_size); + if (!entry) + return -1; + + entry->record.rdata = (void *)(entry + 1); + memcpy(entry->record.rdata, *cur, rdlength); + *cur += rdlength; + *r = entry; + + return 0; +} + +/* + * Parse any record. + */ +static int __dns_parser_parse_names(struct __dns_record_entry **r, + uint16_t rdlength, + dns_parser_t *parser) +{ + const char *rcdend; + const char **cur; + struct __dns_record_entry *entry; + size_t entry_size; + size_t name_len; + char name[DNS_NAMES_MAX + 2]; + int ret; + + cur = &(parser->cur); + rcdend = *cur + rdlength; + ret = __dns_parser_parse_host(name, parser); + if (ret < 0) + return ret; + + if (*cur != rcdend) + return -2; + + name_len = strlen(name); + entry_size = sizeof (struct __dns_record_entry) + name_len + 1; + entry = (struct __dns_record_entry *)malloc(entry_size); + if (!entry) + return -1; + + entry->record.rdata = (void *)(entry + 1); + memcpy(entry->record.rdata, name, name_len + 1); + *r = entry; + + return 0; +} + +/* + * SOA RDATA format, from RFC 1035: + * 1 1 1 1 1 1 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * / MNAME / + * / / + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * / RNAME / + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | SERIAL | + * | | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | REFRESH | + * | | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | RETRY | + * | | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | EXPIRE | + * | | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | MINIMUM | + * | | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * + * MNAME: + * RNAME: + * SERIAL: The unsigned 32 bit version number. + * REFRESH: A 32 bit time interval. + * RETRY: A 32 bit time interval. + * EXPIRE: A 32 bit time value. + * MINIMUM: The unsigned 32 bit integer. + */ +static int __dns_parser_parse_soa(struct __dns_record_entry **r, + uint16_t rdlength, + dns_parser_t *parser) +{ + const char *rcdend; + const char **cur; + struct __dns_record_entry *entry; + struct dns_record_soa *soa; + size_t entry_size; + char mname[DNS_NAMES_MAX + 2]; + char rname[DNS_NAMES_MAX + 2]; + int ret; + + cur = &(parser->cur); + rcdend = *cur + rdlength; + ret = __dns_parser_parse_host(mname, parser); + if (ret < 0) + return ret; + ret = __dns_parser_parse_host(rname, parser); + if (ret < 0) + return ret; + + if (*cur + 20 != rcdend) + return -2; + + entry_size = sizeof (struct __dns_record_entry) + + sizeof (struct dns_record_soa); + entry = (struct __dns_record_entry *)malloc(entry_size); + if (!entry) + return -1; + + entry->record.rdata = (void *)(entry + 1); + soa = (struct dns_record_soa *)(entry->record.rdata); + + soa->mname = strdup(mname); + soa->rname = strdup(rname); + soa->serial = __dns_parser_uint32(*cur); + soa->refresh = __dns_parser_uint32(*cur + 4); + soa->retry = __dns_parser_uint32(*cur + 8); + soa->expire = __dns_parser_uint32(*cur + 12); + soa->minimum = __dns_parser_uint32(*cur + 16); + + if (!soa->mname || !soa->rname) + { + free(soa->mname); + free(soa->rname); + free(entry); + return -1; + } + + *cur += 20; + *r = entry; + + return 0; +} + +/* + * SRV RDATA format, from RFC 2782: + * 1 1 1 1 1 1 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | PRIORITY | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | WEIGHT | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | PORT | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * / TARGET / + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * + * PRIORITY: A 16 bit unsigned integer in network byte order. + * WEIGHT: A 16 bit unsigned integer in network byte order. + * PORT: A 16 bit unsigned integer in network byte order. + * TARGET: + */ +static int __dns_parser_parse_srv(struct __dns_record_entry **r, + uint16_t rdlength, + dns_parser_t *parser) +{ + const char *rcdend; + const char **cur; + struct __dns_record_entry *entry; + struct dns_record_srv *srv; + size_t entry_size; + char target[DNS_NAMES_MAX + 2]; + uint16_t priority; + uint16_t weight; + uint16_t port; + int ret; + + cur = &(parser->cur); + rcdend = *cur + rdlength; + + if (*cur + 6 > rcdend) + return -2; + + priority = __dns_parser_uint16(*cur); + weight = __dns_parser_uint16(*cur + 2); + port = __dns_parser_uint16(*cur + 4); + *cur += 6; + + ret = __dns_parser_parse_host(target, parser); + if (ret < 0) + return ret; + if (*cur != rcdend) + return -2; + + entry_size = sizeof (struct __dns_record_entry) + + sizeof (struct dns_record_srv); + entry = (struct __dns_record_entry *)malloc(entry_size); + if (!entry) + return -1; + + entry->record.rdata = (void *)(entry + 1); + srv = (struct dns_record_srv *)(entry->record.rdata); + + srv->priority = priority; + srv->weight = weight; + srv->port = port; + srv->target = strdup(target); + + if (!srv->target) + { + free(entry); + return -1; + } + + *r = entry; + + return 0; +} + +static int __dns_parser_parse_mx(struct __dns_record_entry **r, + uint16_t rdlength, + dns_parser_t *parser) +{ + const char *rcdend; + const char **cur; + struct __dns_record_entry *entry; + struct dns_record_mx *mx; + size_t entry_size; + char exchange[DNS_NAMES_MAX + 2]; + int16_t preference; + int ret; + + cur = &(parser->cur); + rcdend = *cur + rdlength; + + if (*cur + 2 > rcdend) + return -2; + preference = __dns_parser_uint16(*cur); + *cur += 2; + + ret = __dns_parser_parse_host(exchange, parser); + if (ret < 0) + return ret; + if (*cur != rcdend) + return -2; + + entry_size = sizeof (struct __dns_record_entry) + + sizeof (struct dns_record_mx); + entry = (struct __dns_record_entry *)malloc(entry_size); + if (!entry) + return -1; + + entry->record.rdata = (void *)(entry + 1); + mx = (struct dns_record_mx *)(entry->record.rdata); + mx->exchange = strdup(exchange); + mx->preference = preference; + + if (!mx->exchange) + { + free(entry); + return -1; + } + + *r = entry; + + return 0; +} + +static int __dns_parser_parse_others(struct __dns_record_entry **r, + uint16_t rdlength, + dns_parser_t *parser) +{ + const char **cur; + struct __dns_record_entry *entry; + size_t entry_size; + + cur = &(parser->cur); + entry_size = sizeof (struct __dns_record_entry) + rdlength; + entry = (struct __dns_record_entry *)malloc(entry_size); + if (!entry) + return -1; + + entry->record.rdata = (void *)(entry + 1); + memcpy(entry->record.rdata, *cur, rdlength); + *cur += rdlength; + *r = entry; + + return 0; +} + +/* + * RR format, from RFC 1035: + * 1 1 1 1 1 1 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | | + * / NAME / + * / / + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | TYPE | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | CLASS | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | TTL | + * | | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | RDLENGTH | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * / RDATA / + * / / + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * + */ +static int __dns_parser_parse_record(int idx, dns_parser_t *parser) +{ + uint16_t i; + uint16_t type; + uint16_t rclass; + uint32_t ttl; + uint16_t rdlength; + uint16_t count; + const char *msgend; + const char **cur; + int ret; + struct __dns_record_entry *entry; + char host[DNS_NAMES_MAX + 2]; + struct list_head *list; + + switch (idx) + { + case 0: + count = parser->header.ancount; + list = &parser->answer_list; + break; + case 1: + count = parser->header.nscount; + list = &parser->authority_list; + break; + case 2: + count = parser->header.arcount; + list = &parser->additional_list; + break; + default: + return -2; + } + + msgend = (const char *)parser->msgbuf + parser->msgsize; + cur = &(parser->cur); + + for (i = 0; i < count; i++) + { + ret = __dns_parser_parse_host(host, parser); + if (ret < 0) + return ret; + + // TYPE(2) + CLASS(2) + TTL(4) + RDLENGTH(2) = 10 + if (*cur + 10 > msgend) + return -2; + type = __dns_parser_uint16(*cur); + rclass = __dns_parser_uint16(*cur + 2); + ttl = __dns_parser_uint32(*cur + 4); + rdlength = __dns_parser_uint16(*cur + 8); + *cur += 10; + if (*cur + rdlength > msgend) + return -2; + + entry = NULL; + switch (type) + { + case DNS_TYPE_A: + ret = __dns_parser_parse_a(&entry, rdlength, parser); + break; + case DNS_TYPE_AAAA: + ret = __dns_parser_parse_aaaa(&entry, rdlength, parser); + break; + case DNS_TYPE_NS: + case DNS_TYPE_CNAME: + case DNS_TYPE_PTR: + ret = __dns_parser_parse_names(&entry, rdlength, parser); + break; + case DNS_TYPE_SOA: + ret = __dns_parser_parse_soa(&entry, rdlength, parser); + break; + case DNS_TYPE_SRV: + ret = __dns_parser_parse_srv(&entry, rdlength, parser); + break; + case DNS_TYPE_MX: + ret = __dns_parser_parse_mx(&entry, rdlength, parser); + break; + default: + ret = __dns_parser_parse_others(&entry, rdlength, parser); + } + + if (ret < 0) + return ret; + + entry->record.name = strdup(host); + if (!entry->record.name) + { + __dns_parser_free_record(entry); + return -1; + } + + entry->record.type = type; + entry->record.rclass = rclass; + entry->record.ttl = ttl; + entry->record.rdlength = rdlength; + list_add_tail(&entry->entry_list, list); + } + + return 0; +} + +/* + * Question format, from RFC 1035: + * 1 1 1 1 1 1 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | | + * / QNAME / + * / / + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | QTYPE | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * | QCLASS | + * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + * + * The query name is encoded as a series of labels, each represented + * as a one-byte length (maximum 63) followed by the text of the + * label. The list is terminated by a label of length zero (which can + * be thought of as the root domain). + */ +static int __dns_parser_parse_question(dns_parser_t *parser) +{ + uint16_t qtype; + uint16_t qclass; + const char *msgend; + const char **cur; + int ret; + char host[DNS_NAMES_MAX + 2]; + + msgend = (const char *)parser->msgbuf + parser->msgsize; + cur = &(parser->cur); + + // question count != 1 is an error + if (parser->header.qdcount != 1) + return -2; + + // parse qname + ret = __dns_parser_parse_host(host, parser); + if (ret < 0) + return ret; + + // parse qtype and qclass + if (*cur + 4 > msgend) + return -2; + + qtype = __dns_parser_uint16(*cur); + qclass = __dns_parser_uint16(*cur + 2); + *cur += 4; + + if (parser->question.qname) + free(parser->question.qname); + + parser->question.qname = strdup(host); + if (parser->question.qname == NULL) + return -1; + + parser->question.qtype = qtype; + parser->question.qclass = qclass; + + return 0; +} + +void dns_parser_init(dns_parser_t *parser) +{ + // 鍒濆鍖栬В鏋愬櫒缁撴瀯浣擄紝鍖呮嫭鍒嗛厤鍐呭瓨銆佽缃寚閽堛佸垵濮嬪寲璁℃暟鍣ㄥ拰鍒楄〃澶 + parser->msgbuf = NULL; + parser->msgbase = NULL; + parser->cur = NULL; + parser->msgsize = 0; + parser->bufsize = 0; + parser->complete = 0; + parser->single_packet = 0; + memset(&parser->header, 0, sizeof (struct dns_header)); + memset(&parser->question, 0, sizeof (struct dns_question)); + INIT_LIST_HEAD(&parser->answer_list); + INIT_LIST_HEAD(&parser->authority_list); + INIT_LIST_HEAD(&parser->additional_list); +} + +int dns_parser_set_question(const char *name, + uint16_t qtype, + uint16_t qclass, + dns_parser_t *parser) +{ + int ret; + + // 璁剧疆DNS鏌ヨ鐨勯棶棰橀儴鍒嗭紝鍖呮嫭鍩熷悕銆佹煡璇㈢被鍨嬪拰鏌ヨ绫 + ret = dns_parser_set_question_name(name, parser); + if (ret < 0) + return ret; + + parser->question.qtype = qtype; + parser->question.qclass = qclass; + parser->header.qdcount = 1; + + return 0; +} + +int dns_parser_set_question_name(const char *name, dns_parser_t *parser) +{ + char *newname; + size_t len; + + len = strlen(name); + newname = (char *)malloc(len + 1); + + if (!newname) + return -1; + + memcpy(newname, name, len + 1); + // Remove trailing dot, except name is "." + if (len > 1 && newname[len - 1] == '.') + newname[len - 1] = '\0'; + + if (parser->question.qname) + free(parser->question.qname); + parser->question.qname = newname; + + return 0; +} + +void dns_parser_set_id(uint16_t id, dns_parser_t *parser) +{ + parser->header.id = id; +} + +int dns_parser_parse_all(dns_parser_t *parser) +{ + struct dns_header *h; + int ret; + int i; + + parser->complete = 1; + parser->cur = (const char *)parser->msgbase; + h = &parser->header; + + if (parser->msgsize < sizeof (struct dns_header)) + return -2; + + memcpy(h, parser->msgbase, sizeof (struct dns_header)); + h->id = ntohs(h->id); + h->qdcount = ntohs(h->qdcount); + h->ancount = ntohs(h->ancount); + h->nscount = ntohs(h->nscount); + h->arcount = ntohs(h->arcount); + parser->cur += sizeof (struct dns_header); + + ret = __dns_parser_parse_question(parser); + if (ret < 0) + return ret; + + for (i = 0; i < 3; i++) + { + ret = __dns_parser_parse_record(i, parser); + if (ret < 0) + return ret; + } + + return 0; +} + +int dns_parser_append_message(const void *buf, + size_t *n, + dns_parser_t *parser) +{ + int ret; + size_t total; + size_t new_size; + size_t msgsize_bak; + void *new_buf; + + if (parser->complete) + { + *n = 0; + return 1; + } + + if (!parser->single_packet) + { + msgsize_bak = parser->msgsize; + if (parser->msgsize + *n > parser->bufsize) + { + new_size = MAX(DNS_MSGBASE_INIT_SIZE, 2 * parser->bufsize); + + while (new_size < parser->msgsize + *n) + new_size *= 2; + + new_buf = realloc(parser->msgbuf, new_size); + if (!new_buf) + return -1; + + parser->msgbuf = new_buf; + parser->bufsize = new_size; + } + + memcpy((char*)parser->msgbuf + parser->msgsize, buf, *n); + parser->msgsize += *n; + + if (parser->msgsize < 2) + return 0; + + total = __dns_parser_uint16((char*)parser->msgbuf); + if (parser->msgsize < total + 2) + return 0; + + *n = total + 2 - msgsize_bak; + parser->msgsize = total + 2; + parser->msgbase = (char*)parser->msgbuf + 2; + } + else + { + parser->msgbuf = malloc(*n); + memcpy(parser->msgbuf, buf, *n); + parser->msgbase = parser->msgbuf; + parser->msgsize = *n; + parser->bufsize = *n; + } + + ret = dns_parser_parse_all(parser); + if (ret < 0) + return ret; + + return 1; +} + +void dns_parser_deinit(dns_parser_t *parser) +{ + free(parser->msgbuf); + free(parser->question.qname); + + __dns_parser_free_record_list(&parser->answer_list); + __dns_parser_free_record_list(&parser->authority_list); + __dns_parser_free_record_list(&parser->additional_list); +} + +int dns_record_cursor_next(struct dns_record **record, + dns_record_cursor_t *cursor) +{ + struct __dns_record_entry *e; + + if (cursor->next->next != cursor->head) + { + cursor->next = cursor->next->next; + e = list_entry(cursor->next, struct __dns_record_entry, entry_list); + *record = &e->record; + return 0; + } + + return 1; +} + +int dns_record_cursor_find_cname(const char *name, + const char **cname, + dns_record_cursor_t *cursor) +{ + struct __dns_record_entry *e; + + if (!name || !cname) + return 1; + + cursor->next = cursor->head; + while (cursor->next->next != cursor->head) + { + cursor->next = cursor->next->next; + e = list_entry(cursor->next, struct __dns_record_entry, entry_list); + + if (e->record.type == DNS_TYPE_CNAME && + strcasecmp(name, e->record.name) == 0) + { + *cname = (const char *)e->record.rdata; + return 0; + } + } + + return 1; +} + +int dns_add_raw_record(const char *name, uint16_t type, uint16_t rclass, + uint32_t ttl, uint16_t rlen, const void *rdata, + struct list_head *list) +{ + struct __dns_record_entry *entry; + size_t entry_size = sizeof (struct __dns_record_entry) + rlen; + + entry = (struct __dns_record_entry *)malloc(entry_size); + if (!entry) + return -1; + + entry->record.name = strdup(name); + if (!entry->record.name) + { + free(entry); + return -1; + } + + entry->record.type = type; + entry->record.rclass = rclass; + entry->record.ttl = ttl; + entry->record.rdlength = rlen; + entry->record.rdata = (void *)(entry + 1); + memcpy(entry->record.rdata, rdata, rlen); + list_add_tail(&entry->entry_list, list); + + return 0; +} + +int dns_add_str_record(const char *name, uint16_t type, uint16_t rclass, + uint32_t ttl, const char *rdata, + struct list_head *list) +{ + size_t rlen = strlen(rdata); + // record.rdlength has no meaning for parsed record types, ignore its + // correctness, same for soa/srv/mx record + return dns_add_raw_record(name, type, rclass, ttl, rlen+1, rdata, list); +} + +int dns_add_soa_record(const char *name, uint16_t rclass, uint32_t ttl, + const char *mname, const char *rname, + uint32_t serial, int32_t refresh, + int32_t retry, int32_t expire, uint32_t minimum, + struct list_head *list) +{ + struct __dns_record_entry *entry; + struct dns_record_soa *soa; + size_t entry_size; + char *pname, *pmname, *prname; + + entry_size = sizeof (struct __dns_record_entry) + + sizeof (struct dns_record_soa); + + entry = (struct __dns_record_entry *)malloc(entry_size); + if (!entry) + return -1; + + entry->record.rdata = (void *)(entry + 1); + entry->record.rdlength = 0; + soa = (struct dns_record_soa *)(entry->record.rdata); + + pname = strdup(name); + pmname = strdup(mname); + prname = strdup(rname); + + if (!pname || !pmname || !prname) + { + free(pname); + free(pmname); + free(prname); + free(entry); + return -1; + } + + soa->mname = pmname; + soa->rname = prname; + soa->serial = serial; + soa->refresh = refresh; + soa->retry = retry; + soa->expire = expire; + soa->minimum = minimum; + + entry->record.name = pname; + entry->record.type = DNS_TYPE_SOA; + entry->record.rclass = rclass; + entry->record.ttl = ttl; + list_add_tail(&entry->entry_list, list); + + return 0; +} + +int dns_add_srv_record(const char *name, uint16_t rclass, uint32_t ttl, + uint16_t priority, uint16_t weight, + uint16_t port, const char *target, + struct list_head *list) +{ + struct __dns_record_entry *entry; + struct dns_record_srv *srv; + size_t entry_size; + char *pname, *ptarget; + + entry_size = sizeof (struct __dns_record_entry) + + sizeof (struct dns_record_srv); + + entry = (struct __dns_record_entry *)malloc(entry_size); + if (!entry) + return -1; + + entry->record.rdata = (void *)(entry + 1); + entry->record.rdlength = 0; + srv = (struct dns_record_srv *)(entry->record.rdata); + + pname = strdup(name); + ptarget = strdup(target); + + if (!pname || !ptarget) + { + free(pname); + free(ptarget); + free(entry); + return -1; + } + + srv->priority = priority; + srv->weight = weight; + srv->port = port; + srv->target = ptarget; + + entry->record.name = pname; + entry->record.type = DNS_TYPE_SRV; + entry->record.rclass = rclass; + entry->record.ttl = ttl; + list_add_tail(&entry->entry_list, list); + + return 0; +} + +int dns_add_mx_record(const char *name, uint16_t rclass, uint32_t ttl, + int16_t preference, const char *exchange, + struct list_head *list) +{ + struct __dns_record_entry *entry; + struct dns_record_mx *mx; + size_t entry_size; + char *pname, *pexchange; + + entry_size = sizeof (struct __dns_record_entry) + + sizeof (struct dns_record_mx); + + entry = (struct __dns_record_entry *)malloc(entry_size); + if (!entry) + return -1; + + entry->record.rdata = (void *)(entry + 1); + entry->record.rdlength = 0; + mx = (struct dns_record_mx *)(entry->record.rdata); + + pname = strdup(name); + pexchange = strdup(exchange); + + if (!pname || !pexchange) + { + free(pname); + free(pexchange); + free(entry); + return -1; + } + + mx->preference = preference; + mx->exchange = pexchange; + + entry->record.name = pname; + entry->record.type = DNS_TYPE_MX; + entry->record.rclass = rclass; + entry->record.ttl = ttl; + list_add_tail(&entry->entry_list, list); + + return 0; +} + +const char *dns_type2str(int type) +{ + switch (type) + { + case DNS_TYPE_A: + return "A"; + case DNS_TYPE_NS: + return "NS"; + case DNS_TYPE_MD: + return "MD"; + case DNS_TYPE_MF: + return "MF"; + case DNS_TYPE_CNAME: + return "CNAME"; + case DNS_TYPE_SOA: + return "SOA"; + case DNS_TYPE_MB: + return "MB"; + case DNS_TYPE_MG: + return "MG"; + case DNS_TYPE_MR: + return "MR"; + case DNS_TYPE_NULL: + return "NULL"; + case DNS_TYPE_WKS: + return "WKS"; + case DNS_TYPE_PTR: + return "PTR"; + case DNS_TYPE_HINFO: + return "HINFO"; + case DNS_TYPE_MINFO: + return "MINFO"; + case DNS_TYPE_MX: + return "MX"; + case DNS_TYPE_AAAA: + return "AAAA"; + case DNS_TYPE_SRV: + return "SRV"; + case DNS_TYPE_TXT: + return "TXT"; + case DNS_TYPE_AXFR: + return "AXFR"; + case DNS_TYPE_MAILB: + return "MAILB"; + case DNS_TYPE_MAILA: + return "MAILA"; + case DNS_TYPE_ALL: + return "ALL"; + default: + return "Unknown"; + } +} + +const char *dns_class2str(int dnsclass) +{ + switch (dnsclass) + { + case DNS_CLASS_IN: + return "IN"; + case DNS_CLASS_CS: + return "CS"; + case DNS_CLASS_CH: + return "CH"; + case DNS_CLASS_HS: + return "HS"; + case DNS_CLASS_ALL: + return "ALL"; + default: + return "Unknown"; + } +} + +const char *dns_opcode2str(int opcode) +{ + switch (opcode) + { + case DNS_OPCODE_QUERY: + return "QUERY"; + case DNS_OPCODE_IQUERY: + return "IQUERY"; + case DNS_OPCODE_STATUS: + return "STATUS"; + default: + return "Unknown"; + } +} + +const char *dns_rcode2str(int rcode) +{ + switch (rcode) + { + case DNS_RCODE_NO_ERROR: + return "NO_ERROR"; + case DNS_RCODE_FORMAT_ERROR: + return "FORMAT_ERROR"; + case DNS_RCODE_SERVER_FAILURE: + return "SERVER_FAILURE"; + case DNS_RCODE_NAME_ERROR: + return "NAME_ERROR"; + case DNS_RCODE_NOT_IMPLEMENTED: + return "NOT_IMPLEMENTED"; + case DNS_RCODE_REFUSED: + return "REFUSED"; + default: + return "Unknown"; + } +} + From dc043d541daf73c79da512ba5a955b35a2fd4052 Mon Sep 17 00:00:00 2001 From: p8keuqptb <2096779240@qq.com> Date: Mon, 30 Dec 2024 19:55:21 +0800 Subject: [PATCH 4/8] ADD file via upload --- src%2Fserver/CMakeLists.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src%2Fserver/CMakeLists.txt diff --git a/src%2Fserver/CMakeLists.txt b/src%2Fserver/CMakeLists.txt new file mode 100644 index 0000000..ed11ded --- /dev/null +++ b/src%2Fserver/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.6) # 璁剧疆 CMake 鐨勬渶浣庣増鏈姹備负 3.6 +project(server) # 瀹氫箟椤圭洰鍚嶇О涓 "server" + +# 璁剧疆婧愭枃浠跺垪琛 +set(SRC + WFServer.cc # 娣诲姞 WFServer.cc 鏂囦欢鍒版簮鏂囦欢鍒楄〃 +) + +# 濡傛灉 MySQL 閰嶇疆鏈璁剧疆涓 "n" +if (NOT MYSQL STREQUAL "n") + set(SRC + ${SRC} # 淇濈暀鍘熸湁鐨勬簮鏂囦欢 + WFMySQLServer.cc # 娣诲姞 WFMySQLServer.cc 鏂囦欢鍒版簮鏂囦欢鍒楄〃 + ) +endif () + +# 灏嗘簮鏂囦欢鍒楄〃鏋勫缓涓轰竴涓璞″簱 +add_library(${PROJECT_NAME} OBJECT ${SRC}) # 鐢熸垚鍚嶄负 "server" 鐨勫璞″簱 From ff54d8f02022d05783629f325766596cd055374a Mon Sep 17 00:00:00 2001 From: p8keuqptb <2096779240@qq.com> Date: Mon, 30 Dec 2024 19:55:54 +0800 Subject: [PATCH 5/8] ADD file via upload --- src%2Fserver/WFDnsServer.h | 70 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src%2Fserver/WFDnsServer.h diff --git a/src%2Fserver/WFDnsServer.h b/src%2Fserver/WFDnsServer.h new file mode 100644 index 0000000..25c2ae8 --- /dev/null +++ b/src%2Fserver/WFDnsServer.h @@ -0,0 +1,70 @@ +/* + Copyright (c) 2021 Sogou, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Authors: Liu Kai (liukaidx@sogou-inc.com) +*/ + +#ifndef _WFDNSSERVER_H_ +#define _WFDNSSERVER_H_ + +#include "DnsMessage.h" // 寮曞叆 DNS 娑堟伅鐩稿叧鐨勫ご鏂囦欢 +#include "WFServer.h" // 寮曞叆鏈嶅姟鍣ㄥ姛鑳界殑澶存枃浠 +#include "WFTaskFactory.h" // 寮曞叆浠诲姟宸ュ巶浠ュ垱寤 DNS 浠诲姟 + +// 瀹氫箟涓涓 dns_process_t 绫诲瀷锛屽畠鏄竴涓帴鍙 WFDnsTask 鎸囬拡骞惰繑鍥 void 鐨勫嚱鏁板璞 +using dns_process_t = std::function; + +// 瀹氫箟 WFDnsServer 绫诲瀷锛屽熀浜 WFServer 妯℃澘绫伙紝浣跨敤 DnsRequest 鍜 DnsResponse 浣滀负鍗忚 +using WFDnsServer = WFServer; + +// 璁剧疆 DNS 鏈嶅姟鍣ㄧ殑榛樿鍙傛暟 +static constexpr struct WFServerParams DNS_SERVER_PARAMS_DEFAULT = +{ + .transport_type = TT_UDP, // 浼犺緭绫诲瀷涓 UDP + .max_connections = 2000, // 鏈澶ц繛鎺ユ暟 + .peer_response_timeout = 10 * 1000, // 瀵圭鍝嶅簲瓒呮椂鏃堕棿 + .receive_timeout = -1, // 鎺ユ敹瓒呮椂鏃堕棿锛-1 琛ㄧず涓嶈秴鏃 + .keep_alive_timeout = 300 * 1000, // 淇濇寔杩炴帴鐨勮秴鏃舵椂闂 + .request_size_limit = (size_t)-1, // 璇锋眰澶у皬闄愬埗锛-1 琛ㄧず鏃犻檺鍒 + .ssl_accept_timeout = 5000, // SSL 鎺ュ彈瓒呮椂鏃堕棿 +}; + +// WFDnsServer 鏋勯犲嚱鏁扮殑鐗瑰寲妯℃澘 +template<> inline +WFDnsServer::WFServer(dns_process_t proc) : + WFServerBase(&DNS_SERVER_PARAMS_DEFAULT), // 璋冪敤鍩虹被鏋勯犲嚱鏁帮紝浼犲叆榛樿鍙傛暟 + process(std::move(proc)) // 绉诲姩鏋勯犲嚱鏁颁互鎻愰珮鎬ц兘 +{ +} + +// 鍒涘缓鏂扮殑浼氳瘽锛岄噸鍐欏熀绫绘柟娉 +template<> inline +CommSession *WFDnsServer::new_session(long long seq, CommConnection *conn) +{ + WFDnsTask *task; + + // 浣跨敤浠诲姟宸ュ巶鍒涘缓涓涓柊鐨 DNS 浠诲姟 + task = WFServerTaskFactory::create_dns_task(this, this->process); + // 璁剧疆淇濇寔杩炴帴鐨勮秴鏃舵椂闂 + task->set_keep_alive(this->params.keep_alive_timeout); + // 璁剧疆鎺ユ敹瓒呮椂鏃堕棿 + task->set_receive_timeout(this->params.receive_timeout); + // 璁剧疆璇锋眰澶у皬闄愬埗 + task->get_req()->set_size_limit(this->params.request_size_limit); + + return task; // 杩斿洖鍒涘缓鐨勪换鍔 +} + +#endif // _WFDNSSERVER_H_ From 027a83d95ef06500441f32014c42af0d0d0d9da2 Mon Sep 17 00:00:00 2001 From: p8keuqptb <2096779240@qq.com> Date: Mon, 30 Dec 2024 19:56:12 +0800 Subject: [PATCH 6/8] ADD file via upload --- src_252Fserver/WFHttpServer.h | 71 +++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src_252Fserver/WFHttpServer.h diff --git a/src_252Fserver/WFHttpServer.h b/src_252Fserver/WFHttpServer.h new file mode 100644 index 0000000..940a708 --- /dev/null +++ b/src_252Fserver/WFHttpServer.h @@ -0,0 +1,71 @@ +/* + Copyright (c) 2019 Sogou, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Authors: Xie Han (xiehan@sogou-inc.com) +*/ + +#ifndef _WFHTTPSERVER_H_ +#define _WFHTTPSERVER_H_ + +#include // 寮曞叆鏍囧噯搴撲腑鐨勫伐鍏峰嚱鏁 +#include "HttpMessage.h" // 寮曞叆 HTTP 娑堟伅鐩稿叧鐨勫ご鏂囦欢 +#include "WFServer.h" // 寮曞叆鏈嶅姟鍣ㄥ姛鑳界殑澶存枃浠 +#include "WFTaskFactory.h" // 寮曞叆浠诲姟宸ュ巶浠ュ垱寤 HTTP 浠诲姟 + +// 瀹氫箟涓涓 http_process_t 绫诲瀷锛屽畠鏄竴涓帴鍙 WFHttpTask 鎸囬拡骞惰繑鍥 void 鐨勫嚱鏁板璞 +using http_process_t = std::function; + +// 瀹氫箟 WFHttpServer 绫诲瀷锛屽熀浜 WFServer 妯℃澘绫伙紝浣跨敤 HttpRequest 鍜 HttpResponse 浣滀负鍗忚 +using WFHttpServer = WFServer; + +// 璁剧疆 HTTP 鏈嶅姟鍣ㄧ殑榛樿鍙傛暟 +static constexpr struct WFServerParams HTTP_SERVER_PARAMS_DEFAULT = +{ + .transport_type = TT_TCP, // 浼犺緭绫诲瀷涓 TCP + .max_connections = 2000, // 鏈澶ц繛鎺ユ暟 + .peer_response_timeout = 10 * 1000, // 瀵圭鍝嶅簲瓒呮椂鏃堕棿 + .receive_timeout = -1, // 鎺ユ敹瓒呮椂鏃堕棿锛-1 琛ㄧず涓嶈秴鏃 + .keep_alive_timeout = 60 * 1000, // 淇濇寔杩炴帴鐨勮秴鏃舵椂闂 + .request_size_limit = (size_t)-1, // 璇锋眰澶у皬闄愬埗锛-1 琛ㄧず鏃犻檺鍒 + .ssl_accept_timeout = 10 * 1000, // SSL 鎺ュ彈瓒呮椂鏃堕棿 +}; + +// WFHttpServer 鏋勯犲嚱鏁扮殑鐗瑰寲妯℃澘 +template<> inline +WFHttpServer::WFServer(http_process_t proc) : + WFServerBase(&HTTP_SERVER_PARAMS_DEFAULT), // 璋冪敤鍩虹被鏋勯犲嚱鏁帮紝浼犲叆榛樿鍙傛暟 + process(std::move(proc)) // 绉诲姩鏋勯犲嚱鏁颁互鎻愰珮鎬ц兘 +{ +} + +// 鍒涘缓鏂扮殑浼氳瘽锛岄噸鍐欏熀绫荤殑鏂规硶 +template<> inline +CommSession *WFHttpServer::new_session(long long seq, CommConnection *conn) +{ + WFHttpTask *task; // 澹版槑涓涓 HTTP 浠诲姟鎸囬拡 + + // 浣跨敤浠诲姟宸ュ巶鍒涘缓涓涓柊鐨 HTTP 浠诲姟 + task = WFServerTaskFactory::create_http_task(this, this->process); + // 璁剧疆淇濇寔杩炴帴鐨勮秴鏃舵椂闂 + task->set_keep_alive(this->params.keep_alive_timeout); + // 璁剧疆鎺ユ敹瓒呮椂鏃堕棿 + task->set_receive_timeout(this->params.receive_timeout); + // 璁剧疆璇锋眰澶у皬闄愬埗 + task->get_req()->set_size_limit(this->params.request_size_limit); + + return task; // 杩斿洖鍒涘缓鐨勪换鍔 +} + +#endif // _WFHTTPSERVER_H_ From 1c5d07c884c96c446f80f16d1f658cc30305d4c0 Mon Sep 17 00:00:00 2001 From: p8keuqptb <2096779240@qq.com> Date: Mon, 30 Dec 2024 20:01:04 +0800 Subject: [PATCH 7/8] ADD file via upload --- src%2Fserver/xmake.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src%2Fserver/xmake.lua diff --git a/src%2Fserver/xmake.lua b/src%2Fserver/xmake.lua new file mode 100644 index 0000000..b76ff63 --- /dev/null +++ b/src%2Fserver/xmake.lua @@ -0,0 +1,10 @@ +-- 瀹氫箟涓涓 xmake 鐩爣锛屽悕涓 server +target("server") + set_kind("object") -- 璁剧疆鐩爣绫诲瀷涓哄璞℃枃浠 + + add_files("*.cc") -- 娣诲姞褰撳墠鐩綍涓嬫墍鏈夌殑 .cc 鏂囦欢鍒扮洰鏍囦腑 + + -- 妫鏌ユ槸鍚︽湭瀹氫箟 MySQL 閰嶇疆 + if not has_config("mysql") then + remove_files("WFMySQLServer.cc") -- 濡傛灉鏈畾涔 MySQL 閰嶇疆锛屽垯绉婚櫎 MySQL 鏈嶅姟鍣ㄧ浉鍏崇殑婧愭枃浠 + end From a7cb38990c13587afaf08d4b4098ccf0d37ee833 Mon Sep 17 00:00:00 2001 From: p8keuqptb <2096779240@qq.com> Date: Mon, 30 Dec 2024 20:04:29 +0800 Subject: [PATCH 8/8] ADD file via upload --- src/doc | Bin 0 -> 197569 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/doc diff --git a/src/doc b/src/doc new file mode 100644 index 0000000000000000000000000000000000000000..0d06029833da55a009c95c7fe20bacafcee468b2 GIT binary patch literal 197569 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 %^eQ}OJ_!8_RcFj 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 literal 0 HcmV?d00001