Skip to content

Commit 1d4564e

Browse files
committed
```
feat(config): 新增代理路由规则配置支持端口白名单和DNS策略 - 添加 ProxyRules 结构体,支持 allowed_ports 端口白名单配置 - 添加 dns_mode 配置项,支持 direct/proxy 两种DNS处理策略 - 实现 IsPortAllowed 方法用于快速判断端口是否在白名单中 - 在JSON解析中添加 proxy_rules 字段的解析逻辑 - 添加路由规则初始化和日志输出功能 ```
1 parent c11ce6c commit 1d4564e

File tree

6 files changed

+175
-3
lines changed

6 files changed

+175
-3
lines changed

.sanshu-memory/metadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"project_path": "\\\\?\\E:\\ProjectCode\\C++Code\\antigravity-proxy",
3-
"last_organized": "2026-01-10T16:47:10.839367Z",
3+
"last_organized": "2026-01-10T16:51:05.090922300Z",
44
"total_entries": 9,
55
"version": "1.0.0"
66
}

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,11 @@ target_link_libraries(version PRIVATE ws2_32)
461461
"recv": 5000
462462
},
463463
"child_injection": true,
464-
"target_processes": []
464+
"target_processes": [],
465+
"proxy_rules": {
466+
"allowed_ports": [80, 443],
467+
"dns_mode": "direct"
468+
}
465469
}
466470
```
467471

@@ -493,6 +497,8 @@ target_link_libraries(version PRIVATE ws2_32)
493497
| `child_injection` | bool | `true` | 是否注入子进程 |
494498
| `traffic_logging` | bool | `false` | 是否记录流量日志 |
495499
| `target_processes` | array | `[]` | 目标进程列表 (空=全部) |
500+
| `proxy_rules.allowed_ports` | array | `[80, 443]` | 端口白名单 (空=全部) |
501+
| `proxy_rules.dns_mode` | string | `"direct"` | DNS策略: `direct`(直连) / `proxy`(走代理) |
496502

497503
### 验证是否生效 / Verification
498504

build.ps1

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,10 @@ $configJson = @{
271271
"language_server_windows",
272272
"Antigravity.exe"
273273
)
274+
proxy_rules = @{
275+
allowed_ports = @(80, 443)
276+
dns_mode = "direct"
277+
}
274278
} | ConvertTo-Json -Depth 4
275279

276280
$configPath = Join-Path $OutputDir "config.json"
@@ -320,7 +324,11 @@ Antigravity-Proxy 是一个基于 MinHook 的 Windows DLL 代理注入工具。
320324
"target_processes": [ // 目标进程列表 (空数组=注入所有子进程)
321325
"language_server_windows",
322326
"Antigravity.exe"
323-
]
327+
],
328+
"proxy_rules": {
329+
"allowed_ports": [80, 443], // 端口白名单 (仅这些端口走代理, 空=全部)
330+
"dns_mode": "direct" // DNS策略: direct(直连) 或 proxy(走代理)
331+
}
324332
}
325333
``````
326334
@@ -362,13 +370,18 @@ Test-NetConnection -ComputerName 127.0.0.1 -Port 7890
362370
| traffic_logging | 是否记录流量日志 | false |
363371
| child_injection | 是否注入子进程 | true |
364372
| target_processes | 目标进程列表 (空=全部) | [] |
373+
| proxy_rules.allowed_ports | 端口白名单 (空=全部) | [80, 443] |
374+
| proxy_rules.dns_mode | DNS策略 (direct/proxy) | direct |
365375
366376
## v1.1.0 更新说明
367377
368378
### 新增功能
369379
1. **目标进程过滤**: 可配置 `target_processes` 数组,仅对指定进程注入 DLL
370380
2. **回环地址 bypass**: `127.0.0.1`、`localhost` 等本地地址不再走代理
371381
3. **日志中文化**: 所有日志已统一为中文输出
382+
4. **智能路由规则**: 新增 `proxy_rules` 配置,支持端口白名单和 DNS 策略
383+
- `allowed_ports`: 仅指定端口走代理,其他直连
384+
- `dns_mode`: DNS (53端口) 可选直连或走代理
372385
373386
### 配置示例
374387
```json

docs/dns_optimization_scheme.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Antigravity-Proxy 网络拦截优化与端口路由方案
2+
3+
## 1. 背景与问题分析
4+
5+
### 1.1 现象
6+
用户反馈启用代理后,应用的网络请求(特别是 DNS)出现异常。日志显示:
7+
1. 发往 `53` 端口的连接被代理拦截。
8+
2. 代理握手(SOCKS5/HTTP)超时或失败 (`WSA error 10060`)。
9+
3. 应用随后尝试 IPv6 DoH 作为兜底,但被 `强制 IPv4` 策略拦截。
10+
11+
### 1.2 根源深度剖析
12+
经过代码审查,核心冲突在于 **DNS 的低延迟特性****同步代理握手的耗时** 之间的不匹配。
13+
14+
- **机制冲突**:当前 `Hooks.cpp` 中的 `PerformProxyConnect` 强制拦截所有 TCP 连接。对于 DNS (通常端口 53),它会立即尝试连接本地代理并执行完整的 SOCKS5 握手。
15+
- **时序灾难**
16+
1. OS/App 发起 DNS 查询(期望 ms 级响应)。
17+
2. Hook 劫持连接 -> 链接代理 (TCP RTT) -> 发送握手 (TCP RTT) -> 接收响应 (TCP RTT)。
18+
3. 此过程通常耗时 50ms - 300ms。
19+
4. DNS 客户端判定超时(通常阈值极低),关闭 Socket。
20+
5. 代理握手虽完成后,Socket 已无效,导致“握手失败”或“连接重置”日志。
21+
22+
## 2. 解决方案:智能路由表 (Smart Routing Table)
23+
24+
为了彻底解决此问题,我们引入基于端口和策略的智能路由机制,不再“粗暴”代理所有流量。
25+
26+
### 2.1 架构设计
27+
28+
`Config` 中引入 `ProxyRules` 结构,支持以下策略:
29+
30+
1. **端口白名单 (Port Whitelist)**:仅代理指定端口(如 80, 443),其他端口默认直连。
31+
2. **DNS 专用通道 (DNS Channel)**:针对 53 端口提供独立策略:
32+
- **Direct (直连)**:直接透传请求,不经过代理。
33+
- **Custom (重定向)**:将目标地址篡改为指定 DNS 服务器(如 8.8.8.8),然后直连。有效防止本地 DNS 污染同时规避代理高延迟。
34+
- **Proxy (代理)**:走标准代理流程(仅在明确需要时使用)。
35+
36+
### 2.2 详细设计
37+
38+
#### A. 配置结构 (Config.hpp)
39+
40+
```cpp
41+
struct ProxyRules {
42+
// 允许代理的端口白名单。为空则代理所有。
43+
std::vector<uint16_t> allow_ports = {80, 443};
44+
45+
// DNS (Port 53) 处理策略
46+
// "direct": 直连 (默认,最稳健)
47+
// "proxy": 走代理
48+
// "custom": 重定向到 custom_dns
49+
std::string dns_mode = "direct";
50+
51+
// 自定义 DNS 目标 (仅 mode="custom" 有效)
52+
std::string custom_dns = "8.8.8.8";
53+
};
54+
```
55+
56+
#### B. 核心逻辑 (Hooks.cpp -> PerformProxyConnect)
57+
58+
逻辑流程图:
59+
60+
```mermaid
61+
graph TD
62+
A[Hook Connect] --> B{目标端口 == 53?}
63+
B -- Yes --> C{DNS Mode?}
64+
C -- "direct" --> F[直连 (Passthrough)]
65+
C -- "custom" --> D[修改目标为 Custom DNS]
66+
D --> F
67+
C -- "proxy" --> E[执行代理握手]
68+
69+
B -- No --> G{端口在 Allow List?}
70+
G -- Yes --> E
71+
G -- No --> F
72+
```
73+
74+
## 3. 预期效果
75+
76+
### 3.1 性能提升
77+
- **DNS 秒开**:53 端口流量不再经过 SOCKS5 握手,延迟降低 90% 以上。
78+
- **无阻塞**:非 Web 流量(如 P2P、游戏、后台服务)默认直连,不再占用代理带宽,且无兼容性问题。
79+
80+
### 3.2 稳定性
81+
- **兜底恢复**:即使 TCP DNS 失败,应用的 IPv6 DoH 尝试(如果是 HTTPS 443)将根据路由表决定是否代理。若 DoH 目标为 443 且在白名单,则正常代理;否则直连。避免了之前的暴力拦截。
82+
83+
## 4. 实施步骤
84+
85+
1. **修改 `src/core/Config.hpp`**
86+
- 添加 `ProxyRules` 结构体。
87+
- 更新 JSON 解析逻辑,支持 `proxy_rules` 字段。
88+
89+
2. **修改 `src/hooks/Hooks.cpp`**
90+
- 重构 `PerformProxyConnect`
91+
- 实现上述路由逻辑。
92+
93+
3. **验证**
94+
- 启动后查看日志,确认 "Target Port 53 -> Strategy: Direct" 等日志输出。

src/core/Config.hpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,26 @@ namespace Core {
2626
int recv_ms = 5000;
2727
};
2828

29+
// ============= 代理路由规则 =============
30+
// 用于控制哪些端口走代理、DNS 53 端口的特殊处理策略
31+
struct ProxyRules {
32+
// 允许代理的目标端口白名单(为空则代理所有端口)
33+
// 默认: 仅代理 HTTP(80) 和 HTTPS(443)
34+
std::vector<uint16_t> allowed_ports = {80, 443};
35+
36+
// DNS (Port 53) 处理策略
37+
// "direct" - 直连, 不经代理 (默认, 解决 DNS 超时问题)
38+
// "proxy" - 走代理
39+
std::string dns_mode = "direct";
40+
41+
// 快速判断端口是否在白名单中
42+
bool IsPortAllowed(uint16_t port) const {
43+
if (allowed_ports.empty()) return true; // 空白名单 = 允许所有
44+
return std::find(allowed_ports.begin(), allowed_ports.end(), port)
45+
!= allowed_ports.end();
46+
}
47+
};
48+
2949
class Config {
3050
private:
3151
// 判断路径是否为绝对路径(Windows 盘符或 UNC 路径)
@@ -68,6 +88,7 @@ namespace Core {
6888
ProxyConfig proxy;
6989
FakeIPConfig fakeIp;
7090
TimeoutConfig timeout;
91+
ProxyRules rules; // 代理路由规则
7192
bool trafficLogging = false; // Phase 3: 是否启用流量监控日志
7293
bool childInjection = true; // Phase 2: 是否自动注入子进程
7394
std::vector<std::string> targetProcesses; // 目标进程列表 (空=全部)
@@ -160,6 +181,25 @@ namespace Core {
160181
timeout.recv_ms = t.value("recv", 5000);
161182
}
162183

184+
// ============= 代理路由规则解析 =============
185+
if (j.contains("proxy_rules")) {
186+
auto& pr = j["proxy_rules"];
187+
// 解析端口白名单
188+
if (pr.contains("allowed_ports") && pr["allowed_ports"].is_array()) {
189+
rules.allowed_ports.clear();
190+
for (const auto& p : pr["allowed_ports"]) {
191+
if (p.is_number_unsigned()) {
192+
rules.allowed_ports.push_back(static_cast<uint16_t>(p.get<unsigned int>()));
193+
}
194+
}
195+
}
196+
// 解析 DNS 策略
197+
rules.dns_mode = pr.value("dns_mode", "direct");
198+
Logger::Info("路由规则: allowed_ports=" + std::to_string(rules.allowed_ports.size()) +
199+
" 项, dns_mode=" + rules.dns_mode);
200+
}
201+
202+
163203
// Phase 2/3 配置项
164204
trafficLogging = j.value("traffic_logging", false);
165205
childInjection = j.value("child_injection", true);

src/hooks/Hooks.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,25 @@ int PerformProxyConnect(SOCKET s, const struct sockaddr* name, int namelen, bool
361361
return isWsa ? fpWSAConnect(s, name, namelen, NULL, NULL, NULL, NULL) : fpConnect(s, name, namelen);
362362
}
363363

364+
// ============= 智能路由决策 =============
365+
// ROUTE-1: DNS 端口特殊处理 (解决 DNS 超时问题)
366+
if (originalPort == 53) {
367+
if (config.rules.dns_mode == "direct" || config.rules.dns_mode.empty()) {
368+
Core::Logger::Info("DNS 请求直连 (策略: direct), 目标: " + originalHost + ":53");
369+
return isWsa ? fpWSAConnect(s, name, namelen, NULL, NULL, NULL, NULL)
370+
: fpConnect(s, name, namelen);
371+
}
372+
// dns_mode == "proxy" 则继续走后面的代理逻辑
373+
Core::Logger::Info("DNS 请求走代理 (策略: proxy), 目标: " + originalHost + ":53");
374+
}
375+
376+
// ROUTE-2: 端口白名单过滤
377+
if (!config.rules.IsPortAllowed(originalPort)) {
378+
Core::Logger::Info("端口 " + std::to_string(originalPort) + " 不在白名单, 直连: " + originalHost);
379+
return isWsa ? fpWSAConnect(s, name, namelen, NULL, NULL, NULL, NULL)
380+
: fpConnect(s, name, namelen);
381+
}
382+
364383
// 如果配置了代理
365384
if (config.proxy.port != 0) {
366385
Core::Logger::Info("正重定向 " + originalHost + ":" + std::to_string(originalPort) + " 到代理");

0 commit comments

Comments
 (0)