1- # cfnat C 版 v0.0.9
1+ # cfnat C 版 v0.0.10
22
33面向低内存环境的 ** Cloudflare IP 扫描 + 单端口 TCP 转发** 工具。
44
@@ -65,17 +65,18 @@ Cloudflare 优选 IP:443 或 :80
6565- 支持 IPv4 / IPv6 扫描入口。
6666- 支持 IPv4 / IPv6 监听地址。
6767- 支持按 Cloudflare 数据中心过滤,例如 ` HKG ` 、` SJC ` 、` LAX ` 。
68- - 候选 IP 按延迟和丢包率综合评分 ,始终使用当前 score 最低的最优 IP。
68+ - 候选 IP 按 EWMA 平滑延迟(α=0.125)、丢包率、抖动和连续失败次数综合评分 ,始终使用当前 score 最低的最优 IP。
6969- 默认启用候选缓存,二次启动时先快速健康检查缓存 IP,命中后立即监听,再后台刷新。
7070- 单端口同时承接 TLS 与非 TLS / HTTP 流量。
71- - 支持定时健康检查与失败自动切换 。
71+ - 渐进式三级健康检查(LIGHT → MEDIUM → FULL),失败自动升级,连续成功降级 。
7272- 支持百度前置代理。
7373- 支持直连优选监听和百度前置优选监听,可单独启用,也可同进程同时启用。
7474- 单一 ` cfnat.c ` 源码通过条件编译同时支持 Linux / macOS / Windows。
7575- 统一日志级别:` silent ` 、` error ` 、` warn ` 、` info ` 、` debug ` 。
76- - 事件驱动 I/O 多路复用:Linux epoll / macOS kqueue / Windows IOCP,降低 select 轮询开销。
77- - 候选 IP 懒加载(BatchIterator):流式扫描,批大小 1024,避免一次性展开全部 CIDR 占用大量内存。
78- - 连接级 IP 选择缓存:健康检查线程维护 cache_valid 标记,连接建立时 O(1) 获取当前 IP,跳过重复健康检查。
76+ - 事件驱动 I/O 多路复用:Linux epoll / macOS kqueue / select 回退,降低 select 轮询开销。
77+ - CIDR 惰性展开(前缀和 + 二分查找):只存 CIDR 范围,按需生成 IP,KB 级内存即可处理百万级 IP 段。
78+ - HTTP Keep-Alive 连接复用:同一 IP 多次探测复用 TCP 连接,断连后自动重连,减少握手开销。
79+ - 连接级 IP 选择缓存 + 代理节点选择缓存(5 秒),连接建立和节点切换时 O(1) 获取,降低 CPU 开销。
7980
8081---
8182
@@ -170,7 +171,7 @@ TLS 流量 → Cloudflare IP:443
170171| ` -port ` | TLS 流量转发目标端口 | ` 443 ` |
171172| ` -http-port ` | 非 TLS / HTTP 流量转发目标端口 | ` 80 ` |
172173| ` -random ` | 是否从 CIDR 随机抽样 IP;` true ` 启动快,` false ` 会完整展开 CIDR,扫描量很大 | ` true ` |
173- | ` -task ` | 扫描线程数,上限为 ` 512 ` | ` 100 ` |
174+ | ` -task ` | 扫描线程数 | ` 100 ` |
174175| ` -V ` / ` -version ` | 显示版本号并退出 | — |
175176| ` -code ` | HTTP / HTTPS 探测期望状态码 | ` 200 ` |
176177| ` -domain ` | 健康检查目标域名与路径 | ` cloudflaremirrors.com/debian ` |
@@ -341,15 +342,24 @@ xxxx-LAX
341342
342343### 6. 综合评分
343344
344- 候选 IP 会根据延迟和丢包率计算综合分 ,分数越低越优。
345+ 候选 IP 会根据 EWMA 平滑延迟、丢包率、抖动和连续失败次数计算综合分 ,分数越低越优。
345346
346- 可以近似理解为 :
347+ 评分公式 :
347348
348349``` text
349- score = latency * 10 + loss_rate * 25
350+ base_latency = ewma_latency > 0 ? ewma_latency : latency_ms
351+ score = base_latency * 10 + loss_rate * 25 + jitter_ms * 5
352+ if consecutive_fail > 0:
353+ penalty = 50
354+ for i in 0..min(consecutive_fail, 10): penalty *= 2
355+ score += penalty
350356```
351357
352- 所以程序不是单纯选择最低延迟,而是同时考虑速度和稳定性。
358+ - ** EWMA 平滑延迟** :` ewma = ewma × 7/8 + best_latency × 1/8 ` (α=0.125),消除单次延迟毛刺。
359+ - ** 抖动(jitter)** :` jitter = (jitter × 7 + |best_latency - ewma|) / 8 ` ,同样用 EWMA 平滑,衡量延迟波动幅度,抖动大的 IP 即使平均延迟低也会被扣分。
360+ - ** 连续失败指数惩罚** :连续失败 1 次 +50,2 次 +100,3 次 +200……指数级增长,快速淘汰不稳定节点。
361+
362+ 所以程序不是单纯选择最低延迟,而是综合评估平滑延迟、稳定性、丢包率和历史可靠性。
353363
354364### 优选原则
355365
@@ -368,16 +378,27 @@ score = latency * 10 + loss_rate * 25
368378
369379### 7. 健康检查
370380
371- 程序会对候选 IP 做目标端口健康检查。
381+ 程序会对候选 IP 做目标端口健康检查。采用三级渐进策略,根据节点历史表现动态调整检查强度:
372382
373- 只有健康检查通过的 IP 才会成为当前转发 IP。
383+ ``` text
384+ LIGHT(轻量级) → TCP 端口连通性探测,仅检查端口是否可达
385+ MEDIUM(中等) → TCP 连通 + HTTP 请求,验证 HTTP 状态码
386+ FULL(全量) → TCP 连通 + HTTP 请求 + 完整响应体读取,验证内容完整性
387+ ```
388+
389+ - 新节点首次检查从 ` MEDIUM ` 开始。
390+ - 连续成功 3 次后降级为 ` LIGHT ` ,降低检查开销。
391+ - 任意一次失败立即升级为 ` FULL ` ,确认节点是否彻底不可用。
392+ - 只有健康检查通过的 IP 才会成为当前转发 IP。
374393
375394### 8. 自动切换
376395
377396运行期间会定时检查当前 IP。
378397
379398当当前 IP 连续失败两次后,程序会切换到下一个可用候选;如果候选池耗尽,会重新扫描。
380399
400+ 切换时优先使用代理节点选择缓存(5 秒有效期),避免高频重复选择。
401+
381402### 9. 单端口自动分流
382403
383404客户端只需要连接同一个本地端口。程序接收连接后读取客户端首字节:
@@ -713,9 +734,12 @@ C 版的核心价值是降低常驻资源占用。
713734- 候选结果只保留必要字段。
714735- 使用原生 ` pthread ` / Winsock / BSD socket。
715736- 健康检查逻辑固定频率执行,不引入复杂后台状态机。
716- - 候选 IP 懒加载(BatchIterator)避免一次性展开全部 CIDR,大幅降低扫描阶段内存峰值 。
737+ - CIDR 惰性展开(前缀和 + 二分查找):只存 CIDR 范围,按需生成 IP,KB 级内存即可处理百万级 IP 段 。
717738- 连接级 IP 选择缓存(cache_valid)减少连接建立时的重复健康检查,降低瞬时 CPU 开销。
718- - EventLoop 抽象层使用原生 epoll/kqueue/IOCP,替代 select 轮询,提升高并发下的 I/O 效率。
739+ - EventLoop 抽象层使用原生 epoll/kqueue,select 回退,提升高并发下的 I/O 效率。
740+ - EWMA 评分算法:平滑延迟波动,避免单次毛刺导致链路切换,提升稳定性。
741+ - 代理节点选择缓存(5 秒):高频选择场景下 O(1) 命中,降低 CPU 开销。
742+ - 渐进式三级健康检查:LIGHT 级别仅做 TCP 探测,减少健康检查对转发性能的影响。
719743
720744更适合:
721745
0 commit comments