架构总览

三层结构 ​

text
┌──────────────────────────── nginx worker ────────────────────────────┐
│                                                                      │
│  模块本体  ngx_http_cfd_tunnel_module.c                              │
│    ├─ 指令与配置(42 条,main conf = 一条隧道实例)                  │
│    ├─ 进程生命周期(init_process / exit_process)                    │
│    ├─ 1 s 内务定时器(背压采样、超时、停滞判定)                     │
│    └─ 启动期校验与告警                                              │
│                                                                      │
│  传输层  cfd_ngx_transport.c  ── nginx 自己的 OpenSSL(ALPN=h2)     │
│    ├─ h2 会话:nghttp2 服务端 API(本端主动连边缘,但收流用 server)  │
│    ├─ 写路径与背压(SSL_write 重试约束)                             │
│    └─ 控制流:Cap'n Proto RPC(register / heartbeat / update-config)│
│                                                                      │
│  注入层  cfd_ngx_inject.c                                            │
│    ├─ 造虚拟 ngx_connection_t → ngx_http_init_connection()           │
│    ├─ 请求头序列化  cfd_hdr_ser.c(含 Upgrade / trailer)            │
│    ├─ 远程规则匹配  cfd_rcfg.c(0.12.0)                             │
│    └─ MIME 嗅探  cfd_mimesniff.c(对齐 Go 的默认行为)               │
│                                                                      │
│  协议层  src/(26 个文件,与阶段 1 独立客户端共用同一份)             │
│    cfd_h2 / capnp_* / cfd_rpc / cfd_creds / cfd_transport.h /        │
│    cfd_client / cfd_tls / cfd_quick / cfd_tls_client / cfd_proxy /   │
│    cfd_json / capnp_templates.h(生成物)                            │
└──────────────────────────────────────────────────────────────────────┘

没有第四层:不需要额外的 cloudflared 进程、不需要共享内存、不需要一个要自己管理的 UDS 路径 (虚拟连接用的是 socketpair(AF_UNIX) 的 fd 作连接身份载体,数据一个字节都不经过它,而是由 模块通过 c->recv / c->send 直接喂给 nginx 的 HTTP 解析器 —— 详见 注入层)。

一条请求的完整路径 ​

text
1. 边缘在隧道连接上新开一条 h2 流,带请求头(`:path`、`host`、`Cf-Connecting-IP` …)
2. 传输层把这条流交给注入层(裸 TCP 流的判据在这里:Cf-Cloudflared-Proxy-Src)
3. 注入层:远程规则匹配(可选)→ 定注入端口与 Host → 选监听器
4. 注入层:构造虚拟连接,把请求头序列化成 HTTP/1.1 字节喂进 nginx 的 HTTP 解析器
5. nginx:server_name / location / rewrite / proxy_pass / 变量 / access_log(全原生)
6. 注入层:把 nginx 的响应(含 chunked 解块、trailer)写回那条 h2 流
7. 记账释放(连接级配额一并归还),流关闭

运行期模型 ​

  • 每 worker 一份:配置是 COW 拷贝;运行期状态(连接、流表、背压记账、定时器)每 worker 独立。
  • 每条在途注入连接 = 一个连接槽 + 一条 socketpair:连接槽与 fd 都是真的(ngx_get_connection() / socketpair(AF_UNIX)),数据不经过 fd,只经 c->recv / c->send 三个函数指针。
  • 每隧道一条连接:多 worker 时每条隧道在每个 worker 各建一条(connIndex = worker 槽位, 可用 conn_index 指定);快速隧道例外,只由 0 号 worker 建。
  • 单条 h2 连接上多流并发:控制流(Cap’n Proto RPC)与数据流并存,靠 nghttp2 统一调度。
  • 1 s 内务定时器:背压采样、停滞判定、预算淘汰、拒绝线检查都在这里做(CFD_HOUSEKEEPING_TICK)。

代码地图 ​

文件职责
ngx_http_cfd_tunnel_module.c指令、配置、生命周期、注入入口、定时器、背压五层、启动校验、快速隧道编排
cfd_ngx_transport.c/.hTLS + h2 会话、写路径与背压、nghttp2 回调
cfd_ngx_inject.c/.h注入器:h2 流 → nginx 虚拟连接 + 原生请求
cfd_hdr_ser.c/.hh1 请求头序列化与合成(WebSocket、请求 trailer)
cfd_mimesniff.c/.h上游缺 Content-Type 时的 MIME 嗅探(对齐 cloudflared/Go)
cfd_rcfg.c/.h远程配置规则表的解析、校验、匹配与惰性注入目标缓存
src/(26 个文件)协议层:h2、capnp、RPC、凭据、传输抽象、隧道编排、TLS、快速隧道、代理、JSON
config动态模块构建描述(ngx_addon_name / ngx_module_srcs / -lnghttp2 -lz)
tools/gen-template.py 生成 src/capnp_templates.h;regen-templates.sh --check 对账

模块文档 · 对齐依据是 cloudflared 的源码与实测行为