ワンクリックで
integrate-protocol
添加新代理协议时必须遵循此流程。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
添加新代理协议时必须遵循此流程。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
写入新模块文档、重构模块、或用户要求分析模块时触发。
Bug 修复或对接问题排查确认有效后,将经验记录到知识库。
修改 PMR 分配器、内存池配置、热路径容器、对象生命周期管理代码后触发。
编写或修改性能基准测试、分析 benchmark 结果、优化热路径性能时触发。
新增或修改 enable_shared_from_this 类、co_spawn 调用、shared_ptr 捕获的 lambda、co_await 后的成员访问时触发。
新增或修改原子操作、异步定时器、无锁通道、跨线程状态同步、CAS 竞争相关代码时触发。
SOC 職業分類に基づく
| name | integrate-protocol |
| description | 添加新代理协议时必须遵循此流程。 |
Prism 采用编译期分发架构处理多种代理协议。每个协议实现为自由函数,由会话层的 switch 语句静态分发。添加新协议时必须遵循以下完整步骤。
会话层: 接受连接 → 读取首包 24 字节 → 协议检测
│
识别层: 外层探测(非 TLS) 或 TLS 内检测
│
会话层: switch(protocol_type) → 协议 handler 自由函数
│
协议层: 包装预读 → 创建连接对象 → 握手 → 解析目标地址
│
连接层: 拨号建立上游连接 → 双向隧道转发
每个协议 handler 是一个自由函数,不是基类继承。统一的签名约定:
namespace project::protocol::<name>
{
[[nodiscard]] auto handle(context::session &ctx,
std::span<const std::byte> preread)
-> net::awaitable<void>;
}
核心特征:没有抽象基类、没有动态注册表、没有工厂模式。分发是会话层中的编译期 switch。
在协议类型枚举中添加新值,同步更新字符串转换函数。
根据协议的首包特征,在两个检测入口之一添加逻辑:
外层检测(非 TLS 协议)— 首包 24 字节嗅探:
0x05 → SOCKS50x16 + 0x03 → TLSTLS 内检测(运行在 TLS 隧道内的协议)— TLS 载荷分析:
新增协议需要确定首包特征并在对应入口添加判断分支。外层检测只读取 24 字节。
每个协议模块的标准文件结构:
| 文件 | 职责 |
|---|---|
process.hpp / process.cpp | 声明和实现 handle() — 协议处理主流程 |
conn.hpp / conn.cpp | 连接对象类(继承传输装饰器基类) |
config.hpp | 协议专属配置结构体 |
constants.hpp | 线格式常量(命令码、版本号等) |
packet.hpp | 请求/响应数据结构 |
framing.hpp / framing.cpp | 线格式编解码 |
所有 handler 遵循统一的处理流程:
[[nodiscard]] auto handle(context::session &ctx,
std::span<const std::byte> preread)
-> net::awaitable<void>
{
// 1. 包装预读传输 — 重放检测阶段已消耗的预读数据
auto transport = transport::wrap_with_preview(ctx.inbound, preread);
// 2. 创建协议连接对象
auto agent = make_conn(std::move(transport), ctx);
// 3. 协议握手(解析请求、认证、获取目标地址)
auto result = co_await agent.handshake();
// 4. 通过连接层建立上游连接 + 双向转发
auto opts = connect::forward_options{.label = "<name>", .target = result.target};
co_await connect::forward(ctx, std::move(opts), std::move(agent));
}
连接对象设计:继承传输装饰器基类,使协议层成为可替换的传输装饰器。握手完成后,连接对象本身就是下游传输,可直接传给隧道转发。
在会话层的协议分发 switch 语句中添加新的 case 分支,并 include 对应的 process.hpp。
在配置结构体中添加协议专属字段,更新配置文件 schema。
创建新模块的 CMakeLists.txt,在上层 CMakeLists.txt 中添加 add_subdirectory,创建聚合头文件。
添加协议的单元测试,覆盖正常握手、认证失败、格式错误等场景。
如果新协议需要支持多路复用:
实现新协议时必须遵循 Prism 的协程规范:
co_await 异步完成co_spawn 的 lambda 必须捕获 self(shared_ptr)保持对象存活// ❌ 首包检测过度读取 — 消耗超出必要的数据
auto data = co_await read_exactly(1024);
// ✅ 仅读取必要的首包字节
auto data = co_await peek(24);
// ❌ handler 中使用阻塞 DNS 解析
auto endpoints = resolver::sync_resolve(host);
// ✅ 使用异步解析
auto endpoints = co_await resolver::async_resolve(host);
// ❌ 协议状态机缺少超时保护
while (!complete)
{
co_await read_frame(); // 无限等待
}
// ✅ 所有握手阶段有超时保护
net::steady_timer timer(executor());
timer.expires_after(std::chrono::seconds(30));
// ❌ 错误响应暴露协议细节
co_await send("ERROR: invalid command byte");
// ✅ 错误响应使用标准格式或安全回落
co_await fallback_to_dest(raw_request);
// ❌ 预读缓冲区未传递给后续阶段
auto preview = co_await peek(24);
// ... 解析协议类型后丢弃 preview
co_await agent.handshake(); // handshake 看不到 preview 数据
// ✅ 预读数据包装回传输层
auto transport = transport::wrap_with_preview(ctx.inbound, preview);
auto agent = make_conn(std::move(transport), ctx);
添加新协议后,必须执行以下安全审计:
replay-audit — 验证协议认证的防重放机制(时间戳、nonce、AEAD)probe-audit — 验证首包特征不会暴露代理身份(固定长度首包、响应行为)dpi-audit — 验证协议握手不会产生可识别的 TLS 指纹leak-audit — 验证协议交互中不包含软件标识字符串traffic-audit — 验证协议流量的包长分布和时序特征不异常coroutine-audit — 验证实现中无阻塞调用、无互斥锁、生命周期安全