{"id":49416290,"url":"https://github.com/fscarmen/cfnat","last_synced_at":"2026-06-08T03:02:58.057Z","repository":{"id":354661700,"uuid":"1224583849","full_name":"fscarmen/cfnat","owner":"fscarmen","description":"一个轻量级 Cloudflare IP 优选转发器，支持按 Cloudflare 数据中心过滤，并根据延迟和丢包率计算综合 score，始终使用当前最优 IP。单端口可同时承接 TLS 与非 TLS / HTTP 流量，支持百度前置代理，以及移动、电信、联通运营商分池监听入口。","archived":false,"fork":false,"pushed_at":"2026-06-07T07:47:09.000Z","size":203,"stargazers_count":6,"open_issues_count":0,"forks_count":5,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-07T09:20:48.319Z","etag":null,"topics":["cdn","cloudflare","cloudflare-cdn","cloudflare-ip","cloudflare-ip-scanner","edge-network","ip-optimization","ip-scanner","latency","linux","macos","nats","network-tools","port-forwarding","proxy","reverse-proxy","tcp-proxy","windows"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fscarmen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-29T12:29:16.000Z","updated_at":"2026-06-07T07:42:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/fscarmen/cfnat","commit_stats":null,"previous_names":["fscarmen/cfnat"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/fscarmen/cfnat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fscarmen%2Fcfnat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fscarmen%2Fcfnat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fscarmen%2Fcfnat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fscarmen%2Fcfnat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fscarmen","download_url":"https://codeload.github.com/fscarmen/cfnat/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fscarmen%2Fcfnat/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34046003,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cdn","cloudflare","cloudflare-cdn","cloudflare-ip","cloudflare-ip-scanner","edge-network","ip-optimization","ip-scanner","latency","linux","macos","nats","network-tools","port-forwarding","proxy","reverse-proxy","tcp-proxy","windows"],"created_at":"2026-04-29T03:08:08.938Z","updated_at":"2026-06-08T03:02:58.050Z","avatar_url":"https://github.com/fscarmen.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cfnat C 版\n\n面向低内存环境的 **Cloudflare IP 扫描 + 单端口 TCP 转发** 工具。\n\nC 版基于 [`cfnat.go`](cfnat.go) 移植，目标不是把功能做得更复杂，而是在保留扫描、优选、转发、健康检查、百度前置代理和双方案监听等核心能力的同时，尽量降低常驻内存占用，适合 OpenWrt、路由器、小内存 VPS、ARM 小板机等资源受限环境。\n\n---\n\n## 目录\n\n- [项目定位](#项目定位)\n- [核心特性](#核心特性)\n- [快速开始](#快速开始)\n- [运行参数](#运行参数)\n- [常用示例](#常用示例)\n- [工作原理](#工作原理)\n- [快速启动缓存](#快速启动缓存)\n- [百度前置代理与双方案监听](#百度前置代理与双方案监听)\n- [构建与发布](#构建与发布)\n- [仓库文件说明](#仓库文件说明)\n- [数据文件说明](#数据文件说明)\n- [日志与排错](#日志与排错)\n- [资源占用说明](#资源占用说明)\n- [常见问题](#常见问题)\n- [免责声明](#免责声明)\n\n---\n\n## 项目定位\n\ncfnat C 版做三件事：\n\n1. 扫描 Cloudflare IP，按数据中心、延迟、丢包率筛出候选节点。\n2. 在本机监听一个 TCP 端口，自动识别 TLS / 非 TLS 流量。\n3. 把客户端连接转发到当前可用的 Cloudflare 优选 IP，并在失败时自动切换。\n\n它不是 HTTP 反向代理，也不会解密或篡改业务数据。它只做 TCP 字节转发。\n\n典型链路：\n\n```text\n客户端\n  ↓\ncfnat 本地监听端口\n  ↓\nCloudflare 优选 IP:443 或 :80\n```\n\n启用百度前置代理时：\n\n```text\n客户端\n  ↓\ncfnat 本地监听端口\n  ↓\n百度前置节点（HTTP CONNECT）\n  ↓\nCloudflare 优选 IP:443 或 :80\n```\n\n---\n\n## 核心特性\n\n- 支持 IPv4 / IPv6 扫描入口。\n- 支持 IPv4 / IPv6 监听地址。\n- 支持按 Cloudflare 数据中心过滤，例如 `HKG`、`SJC`、`LAX`。\n- 候选 IP 按延迟和丢包率综合评分，始终使用当前 score 最低的最优 IP。\n- 默认启用候选缓存，二次启动时先快速健康检查缓存 IP，命中后立即监听，再后台刷新。\n- 单端口同时承接 TLS 与非 TLS / HTTP 流量。\n- 支持定时健康检查与失败自动切换。\n- 支持百度前置代理。\n- 支持直连优选监听和百度前置优选监听，可单独启用，也可同进程同时启用。\n- 单一 `cfnat.c` 源码通过条件编译同时支持 Linux / macOS / Windows。\n- 统一日志级别：`silent`、`error`、`warn`、`info`、`debug`。\n\n---\n\n## 快速开始\n\n### 1. 本地编译\n\nLinux（glibc 动态版，推荐给常规发行版）：\n\n```bash\ngcc -O2 -pipe -std=c11 -Wall -Wextra -Wno-unused-parameter \\\n  ./cfnat.c -o ./cfnat-linux \\\n  -pthread\n```\n\nLinux（musl 静态版，推荐给 OpenWrt / Alpine / 小系统）：\n\n```bash\nzig cc -target x86_64-linux-musl -O2 -pipe -std=c11 \\\n  -Wall -Wextra -Wno-unused-parameter \\\n  ./cfnat.c -o ./cfnat-linux-amd64-musl \\\n  -pthread -static -s\n```\n\nmacOS：\n\n```bash\nclang -O2 -pipe -std=c11 -Wall -Wextra -Wno-unused-parameter \\\n  ./cfnat.c -o ./cfnat-macos \\\n  -pthread\n```\n\nWindows（MinGW-w64）：\n\n```bash\nx86_64-w64-mingw32-gcc \\\n  -O2 -pipe -std=c11 -D_WIN32_WINNT=0x0601 \\\n  -finput-charset=UTF-8 -fexec-charset=UTF-8 \\\n  -Wall -Wextra -Wno-unused-parameter \\\n  ./cfnat.c -o ./cfnat.exe \\\n  -lws2_32 -lwininet -lwinpthread -static -s\n```\n\n### 2. 启动\n\nLinux 示例：\n\n```bash\n./cfnat-linux -direct-listen=0.0.0.0:40000 -colo=HKG -delay=120 -random=true\n```\n\nmacOS 示例：\n\n```bash\n./cfnat-macos -direct-listen=0.0.0.0:40000 -colo=HKG -delay=120 -random=true\n```\n\nWindows 示例：\n\n```bash\ncfnat.exe -direct-listen=0.0.0.0:40000 -colo=HKG -delay=120 -random=true\n```\n\n### 3. 客户端访问\n\n客户端统一连接同一个端口：\n\n```text\n服务器IP:40000\n```\n\n程序会自动识别连接类型：\n\n```text\nTLS 流量           → Cloudflare IP:443\n非 TLS / HTTP 流量 → Cloudflare IP:80\n```\n\n---\n\n## 运行参数\n\n| 参数             | 说明                                                                        | 默认值                         |\n| ---------------- | --------------------------------------------------------------------------- | ------------------------------ |\n| `-direct-listen` | 直连优选监听地址；只填它时，只跑直连 Cloudflare 优选                        | 空                             |\n| `-baidu-listen`  | 百度前置优选监听地址；只填它时，只跑百度前置方案                            | 空                             |\n| `-colo`          | Cloudflare 数据中心过滤，多个用逗号分隔，例如 `HKG,SJC,LAX`                 | 空                             |\n| `-delay`         | 有效延迟阈值，单位毫秒                                                      | `300`                          |\n| `-ipnum`         | 保留的候选 IP 数量                                                          | `20`                           |\n| `-ips`           | 扫描 IPv4 或 IPv6，取值 `4` 或 `6`                                          | `4`                            |\n| `-num`           | 每个客户端连接的目标连接尝试次数                                            | `5`                            |\n| `-port`          | TLS 流量转发目标端口                                                        | `443`                          |\n| `-http-port`     | 非 TLS / HTTP 流量转发目标端口                                              | `80`                           |\n| `-random`        | 是否从 CIDR 随机抽样 IP；`true` 启动快，`false` 会完整展开 CIDR，扫描量很大 | `true`                         |\n| `-task`          | 扫描线程数，上限为 `512`                                                    | `100`                          |\n| `-code`          | HTTP / HTTPS 探测期望状态码                                                 | `200`                          |\n| `-domain`        | 健康检查目标域名与路径                                                      | `cloudflaremirrors.com/debian` |\n| `-health-log`    | 健康检查成功日志输出间隔，单位秒；设为 `0` 可关闭成功日志                   | `60`                           |\n| `-log`           | 日志级别：`silent`、`error`、`warn`、`info`、`debug`                        | `info`                         |\n\n---\n\n## 常用示例\n\n### 只扫描不监听（查看候选 IP）\n\n```bash\n./cfnat-linux -colo=HKG -delay=120 -random=true\n```\n\n### 只监听直连优选\n\n```bash\n./cfnat-linux -direct-listen=0.0.0.0:1234 -colo=HKG\n```\n\n### 只监听百度前置优选\n\n```bash\n./cfnat-linux -baidu-listen=0.0.0.0:1235 -colo=HKG\n```\n\n### 同时监听直连优选和百度前置优选\n\n```bash\n./cfnat-linux \\\n  -direct-listen=0.0.0.0:1234 \\\n  -baidu-listen=0.0.0.0:1235 \\\n  -colo=HKG\n```\n\n双方案模式下：\n\n```text\n服务器IP:1234 → 直连 Cloudflare 优选\n服务器IP:1235 → 百度前置优选\n```\n\n### 同时接受多个数据中心\n\n```bash\n./cfnat-linux -direct-listen=0.0.0.0:40000 -colo=HKG,SJC,LAX -delay=120\n```\n\n### 使用 IPv6 扫描源\n\n```bash\n./cfnat-linux -direct-listen=[::]:40000 -ips=6 -colo=HKG -delay=120\n```\n\n### 打开调试日志\n\n```bash\n./cfnat-linux -log=debug\n```\n\n### 提高候选池规模和扫描并发\n\n```bash\n./cfnat-linux -ipnum=50 -task=200\n```\n\n---\n\n## 工作原理\n\n### 1. 加载 IP 段\n\n程序启动后根据 `-ips` 选择 IPv4 或 IPv6 扫描源：\n\n```text\n-ips=4 → IPv4\n-ips=6 → IPv6\n```\n\n本地数据文件不存在时，会尝试自动下载。\n\n### 2. 生成待测 IP\n\n根据 `-random` 决定扫描方式：\n\n```text\n-random=true   从每个 CIDR 随机抽取 IP，启动快，适合日常使用\n-random=false  完整展开 CIDR 后按顺序测试，扫描更全面，但 IP 数量可能超过百万，耗时明显更长\n```\n\n程序会输出 IP 列表加载进度和扫描进度。Windows 下如果看到“默认百度代理池已建立”后短时间没有发现有效 IP，通常是在完整展开或扫描大量候选，并不是卡死。需要快速启动时优先使用默认的 `-random=true`。\n\n---\n\n## 快速启动缓存\n\n程序默认启用候选缓存，用来解决\"每次启动都要重新扫描一遍\"的问题。\n\n首次运行时仍会正常扫描 IP。扫描成功后，程序会把当前候选池写入缓存文件。后续启动时会先读取缓存，对前几个候选 IP 做快速健康检查：\n\n```text\n启动\n→ 读取候选缓存\n→ 快速检查缓存里的前几个 IP\n→ 命中可用 IP 后立即开始监听\n→ 后台继续扫描刷新候选池\n→ 刷新完成后写回缓存\n```\n\n这样第二次及之后启动通常不需要等待完整扫描完成，命中缓存后可以先进入监听状态，再慢慢刷新更优结果。\n\n缓存文件按 IP 类型和运行模式区分：\n\n```text\ndirect-cache-v4.txt      IPv4 直连模式缓存\ndirect-cache-v6.txt      IPv6 直连模式缓存\nbaidu-cache-v4.txt       IPv4 百度前置代理缓存\nbaidu-cache-v6.txt       IPv6 百度前置代理缓存\nmixed-cache-v4.txt       IPv4 混合模式缓存\nmixed-cache-v6.txt       IPv6 混合模式缓存\n```\n\n缓存不按时间失效。程序启动时只看健康检查结果：缓存 IP 可用就立即使用，不可用才等待完整扫描。\n\n后台刷新不会阻塞监听服务。刷新成功后会重新按 score 排序，并把扫描结果写回缓存。\n\n需要完全重新扫描时，删除对应的 `*-cache-*.txt` 文件即可。\n\n### 3. TCP 连通性测试\n\n对待测 IP 发起 TCP 连接测试，并记录建连耗时。\n\n这个耗时会作为基础延迟，后续用于候选评分。\n\n### 4. 识别 Cloudflare 数据中心\n\n程序向目标 IP 发起 HTTP 探测，并优先从响应头中读取 `CF-RAY`。\n\n探测时会先使用目标 IP 作为 `Host` 发起请求，行为更接近原 Go 版；随后再尝试默认域名。这样可以避免部分 Windows / 网络环境下请求有响应但没有命中预期 Host，导致一直扫不到 IP。\n\n示例：\n\n```text\nxxxx-HKG\nxxxx-SJC\nxxxx-LAX\n```\n\n后缀就是 Cloudflare 数据中心代码。程序会结合 `locations.json` 映射地区与城市信息。\n\n如果 HTTP 响应能正常返回但没有 `CF-RAY`，并且没有指定 `-colo`，程序会把这个 IP 作为 `UNK` 候选保留下来，再由后续健康检查确认是否可用。\n\n仅 TCP 连接成功但没有读到 HTTP 响应时，不再直接加入候选池，避免 Windows 多线程扫描或百度前置代理场景下把大量不可确认节点误判为有效 IP。\n\n### 5. 按 `-colo` 过滤\n\n如果指定：\n\n```bash\n-colo=HKG,SJC,LAX\n```\n\n程序只保留匹配这些数据中心的结果。\n\n不指定 `-colo` 时，不按数据中心过滤。\n\n### 6. 综合评分\n\n候选 IP 会根据延迟和丢包率计算综合分，分数越低越优。\n\n可以近似理解为：\n\n```text\nscore = latency * 10 + loss_rate * 25\n```\n\n所以程序不是单纯选择最低延迟，而是同时考虑速度和稳定性。\n\n### 优选原则\n\n程序没有多套选择逻辑，只有一套固定的自动优选逻辑：\n\n```text\n扫描候选\n→ 按 score 排序\n→ 永远取 score 最低的 IP\n→ 健康检查失败\n→ 切换到下一个最优候选\n→ 候选池耗尽后重新扫描并重新排序\n```\n\n这个模型可以避免轮询或随机选择带来的链路漂移，让行为更稳定、代码更简单。\n\n### 7. 健康检查\n\n程序会对候选 IP 做目标端口健康检查。\n\n只有健康检查通过的 IP 才会成为当前转发 IP。\n\n### 8. 自动切换\n\n运行期间会定时检查当前 IP。\n\n当当前 IP 连续失败两次后，程序会切换到下一个可用候选；如果候选池耗尽，会重新扫描。\n\n### 9. 单端口自动分流\n\n客户端只需要连接同一个本地端口。程序接收连接后读取客户端首字节：\n\n```text\n首字节是 0x16 → 认为是 TLS 流量\n其他情况      → 认为是非 TLS / HTTP 流量\n```\n\n然后转发到不同目标端口：\n\n```text\nTLS 流量           → Cloudflare IP:-port\n非 TLS / HTTP 流量 → Cloudflare IP:-http-port\n```\n\n默认等价于：\n\n```text\nTLS 流量           → Cloudflare IP:443\n非 TLS / HTTP 流量 → Cloudflare IP:80\n```\n\n---\n\n## 百度前置代理与双方案监听\n\n### 百度前置代理\n\n启用 `-baidu-listen`（配合百度域名和端口）后，程序会通过百度前置节点建立 HTTP CONNECT 链路来扫描和转发。\n\n简化链路：\n\n```text\n客户端\n  ↓\ncfnat\n  ↓\n百度前置节点\n  ↓\nCloudflare IP\n```\n\n这个模式适合本机直连 Cloudflare 不稳定、但经前置节点链路更稳定的网络环境。\n\n注意：百度前置代理不是万能加速器。它的价值在于让扫描路径和实际转发路径尽量一致，减少\"扫得通但转发不稳\"的偏差。\n\n### 双方案监听\n\n你现在可以把直连优选和百度前置优选明确拆开，而不是再靠一个参数配单入口硬切模式。\n\n示例：\n\n```bash\n-direct-listen=0.0.0.0:1234\n-baidu-listen=0.0.0.0:1235\n```\n\n行为说明：\n\n- 只填 `-direct-listen`：只启动直连 Cloudflare 优选。\n- 只填 `-baidu-listen`：只启动百度前置优选。\n- 两个都填：同一个进程里同时维护两套候选池、两套监听入口。\n\n百度前置模式不再对解析出的百度 IP 做 ASN 归类筛选，而是直接对解析得到的全部百度 IP 做可用性验证，扫描通过的都可加入优选池。\n\n---\n\n## 构建与发布\n\n本仓库当前只维护一个 C 入口文件：\n\n| 平台                    | 源文件               | 主要依赖                                                                                            |\n| ----------------------- | -------------------- | --------------------------------------------------------------------------------------------------- |\n| Linux / macOS / Windows | [`cfnat.c`](cfnat.c) | Linux/macOS: `pthread`、POSIX/BSD socket、`getaddrinfo`\u003cbr\u003eWindows: Winsock2、WinINet、`winpthread` |\n\n平台差异通过 `_WIN32` / `__APPLE__` 等条件编译处理，避免三份源码重复维护。\n\n### Linux 发布版本选择\n\nRelease 同时提供两类 Linux 文件：\n\n| 类型         | 适合用户                                           | 说明                                                                |\n| ------------ | -------------------------------------------------- | ------------------------------------------------------------------- |\n| glibc 动态版 | Debian、Ubuntu、Arch、CentOS、Fedora 等常规发行版  | 默认推荐，运行时使用系统自己的 glibc，避免静态 glibc 与系统环境错位 |\n| musl 静态版  | Alpine、OpenWrt、ImmortalWrt、极简容器、小内存系统 | 完全静态，更适合轻量系统和无 glibc 环境                             |\n\nglibc fully-static 在部分发行版和新内核环境下可能出现 resolver、pthread、NSS、IPv6 或 DNS 初始化兼容问题，因此不再作为默认发布产物。需要完全静态时，请优先使用 musl 静态版。\n\n### Linux 构建\n\nglibc 动态版：\n\n```bash\ngcc -O2 -pipe -std=c11 -Wall -Wextra -Wno-unused-parameter \\\n  ./cfnat.c -o ./cfnat-linux \\\n  -pthread\n```\n\nmusl 静态版示例：\n\n```bash\nzig cc -target x86_64-linux-musl -O2 -pipe -std=c11 \\\n  -Wall -Wextra -Wno-unused-parameter \\\n  ./cfnat.c -o ./cfnat-linux-amd64-musl \\\n  -pthread -static -s\n```\n\n说明：\n\n- 默认推荐 glibc 动态版，适合常规 Linux 发行版。\n- 如需完全静态二进制，推荐 musl 静态版。\n- 当前源码只依赖标准 socket / 域名解析接口，不需要额外的 resolver 库。\n\n### macOS 构建\n\n```bash\nclang -O2 -pipe -std=c11 -Wall -Wextra -Wno-unused-parameter \\\n  ./cfnat.c -o ./cfnat-macos \\\n  -pthread\n```\n\n交叉指定架构示例：\n\n```bash\nclang -O2 -pipe -std=c11 \\\n  -arch x86_64 -mmacosx-version-min=10.13 \\\n  ./cfnat.c -o ./cfnat-darwin-amd64 \\\n  -pthread\n```\n\n```bash\nclang -O2 -pipe -std=c11 \\\n  -arch arm64 -mmacosx-version-min=11.0 \\\n  ./cfnat.c -o ./cfnat-darwin-arm64 \\\n  -pthread\n```\n\n说明：\n\n- macOS amd64 最低目标可设为 `10.13`。\n- macOS arm64 最低目标通常设为 `11.0`，因为 Apple Silicon 从 macOS 11 开始支持。\n- macOS 不支持像 Linux musl 那样生成完全静态的系统 libc 二进制。\n- macOS 版同样不需要额外链接 `-lresolv`。\n\n### Windows 中文显示\n\nWindows 7 的传统 CMD 对 UTF-8 控制台支持不稳定，单纯调用 `SetConsoleOutputCP(CP_UTF8)` 或执行 `chcp 65001` 仍可能乱码。\n\nWindows 版现在不再依赖控制台代码页显示中文。程序会把内部 UTF-8 日志转换为 Unicode，并通过 `WriteConsoleW` 直接写入控制台。\n\n这样在 Windows 7 / Windows 10 / Windows 11 下都更稳定：\n\n- 直接在 CMD 运行时，中文走 Unicode 控制台输出。\n- 输出重定向到文件时，仍保留 UTF-8 文本。\n- 不需要用户手动执行 `chcp 65001`。\n\n如果 Windows 7 下仍显示方块，通常是控制台字体缺少中文字形，建议把 CMD 字体改成支持中文的字体，或使用 PowerShell。\n\n### Windows 构建\n\n64 位：\n\n```bash\nx86_64-w64-mingw32-gcc \\\n  -O2 -pipe -std=c11 -D_WIN32_WINNT=0x0601 \\\n  -finput-charset=UTF-8 -fexec-charset=UTF-8 \\\n  -Wall -Wextra -Wno-unused-parameter \\\n  ./cfnat.c -o ./cfnat-windows-amd64.exe \\\n  -lws2_32 -lwininet -lwinpthread -static -s\n```\n\n32 位：\n\n```bash\ni686-w64-mingw32-gcc \\\n  -O2 -pipe -std=c11 -D_WIN32_WINNT=0x0601 \\\n  -finput-charset=UTF-8 -fexec-charset=UTF-8 \\\n  -Wall -Wextra -Wno-unused-parameter \\\n  ./cfnat.c -o ./cfnat-windows-386.exe \\\n  -lws2_32 -lwininet -lwinpthread -static -s\n```\n\n说明：\n\n- `_WIN32_WINNT=0x0601` 表示目标为 Windows 7 或更高版本。\n- `-finput-charset=UTF-8 -fexec-charset=UTF-8` 确保源码中的中文字符串按 UTF-8 编译，配合 `WriteConsoleW` 避免 Windows 7 控制台乱码。\n- Windows 网络层使用 Winsock2，因此需要 `-lws2_32`。\n- Windows 自动下载数据文件使用 WinINet，不再依赖 curl/wget，因此需要 `-lwininet`。\n- Windows 线程兼容层使用 MinGW-w64 `winpthread`，因此需要 `-lwinpthread`。\n\n### Windows 数据文件下载说明\n\nWindows 版不再调用外部 `curl` / `wget` 命令下载数据文件，而是使用系统 WinINet API 下载。\n\n启动时会优先查找：\n\n```text\nips-v4.txt\nips-v6.txt\nlocations.json\n```\n\nWin7 如果系统 TLS 组件过旧，HTTPS 下载仍可能失败。这种情况下把上述三个数据文件放到 exe 同目录即可离线运行。\n\n### GitHub Actions\n\n多平台构建工作流位于：\n\n```text\n.github/workflows/build.yml\n```\n\n当前工作流包含：\n\n- Linux glibc 动态版：amd64、386、armv5、armv6、armv7、arm64、mips、mipsel、mips64、mips64el、ppc64、ppc64le、riscv64、s390x。\n- Linux musl 静态版：amd64、386、armv6、armv7、arm64、mips、mipsel、riscv64。\n- armv5、mips64、mips64el、ppc64、ppc64le、s390x 当前使用 glibc 动态版发布；Zig 0.15.1 在 armv5 musl 下会因 32 位原子内建符号缺失导致链接失败，在 mips64 / ppc64 / s390x 等架构下也不能稳定提供 musl libc，因此不放入必跑 musl 矩阵，避免 release 出现红叉。\n- Windows：amd64、386。\n- macOS：amd64、arm64。\n- tag 触发发布：推送 `v*` 标签后打包 release 文件和校验和。\n- 手动触发：支持 `workflow_dispatch`。\n\n发布包会把二进制文件放入 `bin/`，并附带源码、README 和基础数据文件。\n\n### 常见构建失败\n\n| 现象                                                                                             | 原因                                           | 修复                                                                 |\n| ------------------------------------------------------------------------------------------------ | ---------------------------------------------- | -------------------------------------------------------------------- |\n| 旧版 macOS 源码出现 `_res_9_query`、`_res_9_ns_initparse`、`_res_9_ns_parserr` undefined symbols | 使用了系统 resolver API 但未链接 resolver 库   | 当前源码已不再依赖这套接口；如使用旧源码才需要 `-lresolv`            |\n| 旧版 Linux 源码出现 `res_query`、`ns_initparse`、`ns_parserr` undefined reference                | 使用了 glibc resolver API 但未链接 resolver 库 | 当前源码已不再依赖这套接口；如使用旧源码才需要 `-lresolv`            |\n| Windows 出现 Winsock 相关 undefined reference                                                    | 没有链接 Winsock2                              | 加 `-lws2_32`                                                        |\n| Windows 出现 `SOCKET` 相关类型 warning                                                           | Windows `SOCKET` 与 POSIX `int fd` 不同        | 当前统一源码已使用 `socket_t` 和 `INVALID_SOCKET` 封装，避免直接比较 |\n\n---\n\n## 仓库文件说明\n\n```text\ncfnat.go                         Go 版实现 / 参考实现\ncfnat-origin.go                  原始 Go 版留档\ncfnat.c                          C 版统一入口，支持 Linux / macOS / Windows\nips-v4.txt                       IPv4 数据文件\nips-v6.txt                       IPv6 数据文件\nlocations.json                   Cloudflare 数据中心位置文件\nREADME.md                        主说明文档\n.github/workflows/build.yml      C 版多平台构建工作流\n.github/workflows/build_go.yml   Go 版构建工作流\n```\n\n`README-build.md` 已合并进本文件，不再单独维护，避免构建说明和主文档互相漂移。\n\n---\n\n## 数据文件说明\n\n源码运行时会查找以下本地文件：\n\n```text\nips-v4.txt\nips-v6.txt\nlocations.json\n```\n\n如果文件不存在，程序会自动从上游地址下载并保存为上述文件名。\n\n离线运行时请直接把下面三个文件放在程序同目录：\n\n```text\nips-v4.txt\nips-v6.txt\nlocations.json\n```\n\nLinux、macOS、Windows 三个平台统一使用这三个带扩展名的数据文件，避免 Windows 用户看不到文件类型或手动复制时混淆。\n\n---\n\n## 日志与排错\n\n### 日志级别\n\n```text\n-log=silent  不输出普通日志\n-log=error   仅输出错误\n-log=warn    输出警告和错误\n-log=info    输出常规运行日志\n-log=debug   输出调试信息\n```\n\n### 正常日志示例\n\n```text\n可用 IP: 104.18.x.x (健康检查端口:443)\n正在监听 0.0.0.0:40000，TLS目标端口：443，非TLS目标端口：80\n状态检查成功: 当前 IP 104.18.x.x 可用\n```\n\n### 自动切换日志示例\n\n```text\n状态检查失败 (1/2): 当前 IP 104.18.x.x 暂不可用\n连续两次状态检查失败，切换到下一个 IP\n切换到下一个最优 IP: 104.18.x.x 候选索引: 3\n```\n\n### 没有扫到有效 IP\n\n```text\n未发现有效IP，可尝试放宽 -delay 或提高 -log=debug 查看细节，3 秒后重试\n```\n\n建议按下面顺序排查：\n\n1. 开启 `-log=debug`，查看扫描统计里的连接失败、读取响应失败、缺少 `CF-RAY`、数据中心过滤数量；如果读取响应失败很高，说明 TCP 可连但 HTTP 探测未成功，不会再被直接当作有效 IP。\n2. 暂时去掉 `-colo`，确认不是数据中心过滤过严。\n3. 放宽延迟限制，例如 `-delay=300` 或更高。\n4. 日常使用保持默认 `-random=true`；只有需要完整扫描时才使用 `-random=false`。\n5. 提高扫描并发，例如 `-task=200`。\n6. 网络直连 Cloudflare 不稳定时，改用 `-baidu-listen` 单独开一个百度前置入口。\n\n---\n\n## 资源占用说明\n\nC 版的核心价值是降低常驻资源占用。\n\n相较于 Go 版，C 版没有 Go 运行时、GC 和 goroutine 调度器的额外常驻成本，并在实现上做了更保守的资源控制：\n\n- 双向转发缓冲区固定为 `16 KB`。\n- 每个转发方向使用固定缓冲区。\n- 连接线程使用较小栈空间。\n- 候选结果只保留必要字段。\n- 使用原生 `pthread` / Winsock / BSD socket。\n- 健康检查逻辑固定频率执行，不引入复杂后台状态机。\n\n更适合：\n\n- OpenWrt / ImmortalWrt 路由器。\n- 小内存 VPS。\n- ARM 小板机。\n- 需要长期驻留的网络中转环境。\n- 连接数波动较大但希望内存可控的场景。\n\nGo 版仍然适合快速开发、维护和功能扩展；C 版更适合资源受限和长期常驻。\n\n---\n\n## 常见问题\n\n### 1. 为什么只监听一个端口，却能同时处理 TLS 和非 TLS？\n\n程序读取客户端连接的首字节：\n\n```text\n0x16 → TLS\n其他 → 非 TLS / HTTP\n```\n\n然后分别转发到 `-port` 和 `-http-port`。\n\n### 2. `-choose` 参数去哪了？\n\n当前三平台固定使用综合评分最低的候选 IP，不再暴露 `-choose` 参数。\n\n这样可以减少参数复杂度，也避免三平台行为不一致。\n\n### 3. 百度前置代理一定更快吗？\n\n不一定。\n\n它主要解决的是部分网络环境下直连 Cloudflare 不稳定的问题。是否更快取决于本机、前置节点、Cloudflare IP 三者之间的实际链路。\n\n### 4. 什么时候需要同时开启直连优选和百度前置优选？\n\n当你希望把两种链路彻底分开给用户选，或者想在同一台机器上同时保留“直连 Cloudflare 优选”和“百度前置优选”两个入口时，就有必要。\n\n如果你只需要其中一种方案，只填对应的 `-direct-listen` 或 `-baidu-listen` 即可。\n\n### 5. C 版是不是功能一定比 Go 版强？\n\n不是。\n\nC 版的优势是低内存和更可控的运行时开销。Go 版在开发效率、可维护性和扩展速度上仍然更有优势。\n\n### 6. 为什么编译能过，但运行时提示找不到 IP 文件？\n\nC 源码运行时默认查找 `ips-v4.txt`、`ips-v6.txt` 和 `locations.json`。\n\n请确认程序同目录下存在 `ips-v4.txt`、`ips-v6.txt`、`locations.json`，或允许程序联网自动下载。\n\n---\n\n## 免责声明\n\n本工具仅用于网络测试与学习用途。\n\n请在合法、合规的网络环境下使用。使用者需要自行承担因错误配置、滥用或违反当地法律法规造成的后果。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffscarmen%2Fcfnat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffscarmen%2Fcfnat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffscarmen%2Fcfnat/lists"}