9.3 KiB
9.3 KiB
INP2P 任务拆分
项目概述
自研 P2P 组网系统,两个二进制:inp2ps(信令服务器)+ inp2pc(客户端)。
UDP 打洞优先,分层中继,超级辅助节点。
项目位置:/root/.openclaw/workspace/inp2p/
一、核心层(我负责)
目标:两个二进制能跑起来、能连上、能打洞、能建隧道、能中继。
M1: 信令连接(预计 400 行)✅ 完成
- 协议定义
pkg/protocol/— 消息格式、编解码、类型枚举 - 信令连接
pkg/signal/— WSS 封装、handler 注册、同步请求/响应 - 认证
pkg/auth/— CRC64 token 生成、TOTP 生成/验证、一次性中继令牌 - 配置
pkg/config/— Server/Client 配置结构体、默认值、环境变量 - inp2ps 信令主循环
internal/server/server.go- WSS 接受连接 → Login 验证 → 注册节点
- 心跳管理 → 超时离线清理
- ReportBasic 处理 (必须回响应,OpenP2P 踩过的坑)
- 节点上线广播
- 连接协调
internal/server/coordinator.go(收到 A 的 ConnectReq → 同时推送给 A 和 B punch 参数)
- inp2pc 信令主循环
internal/client/client.go- WSS 连接 → Login → ReportBasic → 心跳
- 断线重连(5s 退避)
- 收到 PushConnectReq 后触发打洞
- 收到 PushNodeOnline 后重试 apps
M2: NAT 探测(预计 200 行)✅ 完成
- UDP STUN 客户端/服务端
pkg/nat/ - TCP STUN 回退
- 集成到 inp2ps main:启动 4 个 STUN listener(UDP×2 + TCP×2)
- 集成到 inp2pc main:登录前先探测,结果带入 LoginReq
- 定期重新探测(每 5 分钟),NATType 变化时通知 server
M3: 打洞(预计 300 行)✅ 完成
- UDP punch 基础实现
pkg/punch/ - TCP punch 基础实现
- 优先级链(direct → UDP → TCP)
- 双端同步打洞协调
internal/server/coordinator.go- server 收到 A 的 ConnectReq
- 同时推送 PunchStart 给 A 和 B(带对方的 IP:Port + NAT 类型)
- 双方同时调
punch.Connect() - 任一方成功后报告 PunchResult
- Symmetric NAT 端口预测(可选优化)
- 打洞结果上报 + 统计
M4: 隧道 + 多路复用(预计 500 行)✅ 完成
- 隧道框架
pkg/tunnel/— 端口转发、统计、生命周期 - 流多路复用协议
pkg/mux/- 帧格式:
StreamID(4B) + Flags(1B) + Len(2B) + Data - SYN/FIN/DATA/PING/PONG/RST 控制帧
- Session(多路复用会话)+ Stream(虚拟连接,实现 net.Conn)
- Ring buffer 接收缓冲
- 7 个单元测试 + 1 个性能基准测试 全部通过
- 帧格式:
- TCP 端口转发实现(listener → mux stream → peer demux → dst connect)
- 端到端测试通过(echo server + tunnel + 验证数据一致性)
- 5 并发连接测试通过
- UDP 端口转发实现
- 连接池/复用(同 peer 多 app 共享一条 tunnel)
M5: 中继(预计 400 行)✅ 完成
- 中继管理器
pkg/relay/— 完整实现(~320 行) - 中继节点选择策略(server 端
server.GetRelayNodes())- 同用户
--relay节点优先 - 全局
--super节点次优 - server 自身中继兜底
- 同用户
- 中继握手协议(长度前缀 JSON)
- A → relay: TCP 连接 + RelayHandshake{sessionID, role="from", token, node}
- B → relay: TCP 连接 + RelayHandshake{sessionID, role="to", token, node}
- relay: TOTP 验证 → 配对等待(30s 超时)→ 双向桥接
- 结果回传 relayResult{error, detail}
- 中继认证
- 同用户:TOTP(token, now)
- 跨用户超级节点:server 签发
RelayToken(HMAC-SHA256 签名,含 TTL)
- 客户端工具函数
ConnectToRelay()— 封装完整握手+等待配对 - 测试覆盖(3/3 通过)
- TestRelayBridge — A↔B 双向数据验证
- TestRelayLargeData — 1MB 精确传输
- TestRelayAuthDenied — 错误 TOTP 被正确拒绝
- 中继带宽统计 + 负载均衡
M6: inp2ps / inp2pc main 入口(预计 200 行)✅ 完成
cmd/inp2ps/main.go— flag 解析、启动 STUN + WSS + API + 优雅退出cmd/inp2pc/main.go— flag 解析、config.json 读写、优雅退出- 端到端验证:server + 2 client 同时运行,health API 显示 nodes=2
二、次要层(可由他人完成)
S1: 配置持久化
inp2pc的config.json读写(登录后 server 回的 token/node 写回文件)- 支持
-newconfig覆盖文件配置 - 热重载(收到 PushEditApp 后更新本地 config)
S2: SDWAN 虚拟组网
- TUN 虚拟网卡创建
- 虚拟 IP 分配(server 侧管理子网)
- 组网路由表管理
- 中心模式 vs 全互联模式
S3: 日志系统
- 分级日志(DEBUG/INFO/WARN/ERROR)
- 日志轮转(按大小)
- 日志目录
log/
S4: 系统集成
- Systemd service 文件生成
- 开机自启
- Daemon 模式(
-dfork 子进程) - 自动更新(可选)
S5: 安全加固
- TLS 证书自动生成(自签名)
- 连接限速
- 单 IP 最大连接数限制
- Brute-force 保护
三、前端 + Web API(可由他人完成)
F1: REST API(inp2ps 内嵌 Gin)
POST /api/v1/login— JWT 签发GET /api/v1/devices— 设备列表(名称、IP、NAT 类型、在线状态、版本)GET /api/v1/devices/:node— 设备详情POST /api/v1/devices/:node/app— 创建隧道DELETE /api/v1/devices/:node/app/:name— 删除隧道PUT /api/v1/devices/:node/app/:name— 编辑隧道(启停)GET /api/v1/dashboard— 概览统计GET /api/v1/connections— 活跃连接列表(打洞/中继/RTT)GET /api/v1/relays— 中继节点状态POST /api/v1/sdwan/edit— SDWAN 配置GET /api/v1/sdwans— SDWAN 列表GET /api/v1/health— 健康检查
F2: Web 控制台 UI
- 设备列表页(在线/离线、NAT 类型标签、版本)
- 隧道管理(创建/编辑/删除/启停)
- 连接状态页(实时连接方式、RTT、流量)
- 中继节点页(负载、带宽、会话数)
- SDWAN 组网页
- Dashboard 概览
- 用户管理(admin/operator RBAC)
F3: 客户端安装脚本
GET /api/v1/client/bootstrap— 返回安装参数- 一键安装脚本(curl | bash)
- 多架构支持(amd64/arm64)
依赖关系
M1 (信令) ← 无依赖,最先完成
M2 (NAT) ← 依赖 M1
M3 (打洞) ← 依赖 M1 + M2
M4 (隧道) ← 依赖 M3
M5 (中继) ← 依赖 M1 + M4
M6 (main) ← 依赖 M1~M5
S1~S5 ← 依赖 M6 完成后可并行
F1 ← 依赖 M1(设备数据来自 server 内存)
F2 ← 依赖 F1
F3 ← 依赖 M6
当前状态
pkg/
├── protocol/ ✅ 完成(消息格式、NAT 枚举、所有结构体)
├── config/ ✅ 完成(Server/Client 配置、环境变量、校验、STUN 端口)
├── auth/ ✅ 完成(CRC64 token、TOTP、一次性中继令牌)
├── nat/ ✅ 完成(UDP/TCP STUN 客户端 + 服务端,集成验证通过)
├── signal/ ✅ 完成(WSS 封装、handler、同步请求/响应)
├── punch/ ✅ 完成(UDP/TCP punch + direct + 优先级链)
├── mux/ ✅ 完成(流多路复用,7 测试 + 1 benchmark 全部通过)
├── tunnel/ ✅ 完成(基于 mux 的端口转发,端到端测试通过)
└── relay/ ✅ 完成(中继握手、TOTP 认证、双向桥接、3 测试通过)
internal/
├── server/ ✅ 完成(登录、心跳、report、relay 选择、节点管理、打洞协调)
│ ├── server.go — WSS 主循环、handler 注册
│ └── coordinator.go — 打洞协调、EditApp/DeleteApp 推送
└── client/ ✅ 完成(连接、登录、打洞、中继回退、app 管理、断线重连)
cmd/
├── inp2ps/ ✅ 完成(flag、STUN、WSS、API、graceful shutdown)
└── inp2pc/ ✅ 完成(flag、config.json、relay、graceful shutdown)
编译状态: ✅ go build ./... 通过
测试状态: ✅ go test ./... 全部通过
- internal/client: 1 test (8.3s) — 完整 NAT+WSS+Login+Report 链路
- internal/server: 2 tests (0.8s) — Login + 双客户端 + Relay 发现
- pkg/mux: 7 tests + 1 bench (0.2s) — 并发/大载荷/FIN/session
- pkg/tunnel: 3 tests (0.16s) — 端到端转发/5 并发/统计
- pkg/relay: 3 tests (0.3s) — 双向桥接/1MB 中继/认证拒绝
二进制: bin/inp2ps (6.0MB) + bin/inp2pc (5.6MB) (静态编译, strip)
接口约定(核心层 ↔ 前端/次要层)
server.Server 暴露的方法(供 F1 REST API 调用)
srv.GetNode(name string) *NodeInfo // 查单个设备
srv.GetOnlineNodes() []*NodeInfo // 在线设备列表
srv.GetRelayNodes(user string) []*NodeInfo // 中继节点列表
srv.PushConnect(from, to, app) // 触发打洞
// NodeInfo 字段: Name, PublicIP, NATType, Version, OS, LanIP,
// RelayEnabled, SuperRelay, ShareBandwidth, LoginTime, LastHeartbeat, Apps
client.Client 暴露的方法(供 S1 配置持久化调用)
client.Run() error // 主循环(阻塞)
client.Stop() // 优雅退出
// 配置通过 config.ClientConfig 传入