# INP2P 任务拆分 ## 项目概述 自研 P2P 组网系统,两个二进制:`inp2ps`(信令服务器)+ `inp2pc`(客户端)。 UDP 打洞优先,分层中继,超级辅助节点。 项目位置:`/root/.openclaw/workspace/inp2p/` --- ## 一、核心层(我负责) **目标**:两个二进制能跑起来、能连上、能打洞、能建隧道、能中继。 ### M1: 信令连接(预计 400 行)✅ 完成 - [x] 协议定义 `pkg/protocol/` — 消息格式、编解码、类型枚举 - [x] 信令连接 `pkg/signal/` — WSS 封装、handler 注册、同步请求/响应 - [x] 认证 `pkg/auth/` — CRC64 token 生成、TOTP 生成/验证、一次性中继令牌 - [x] 配置 `pkg/config/` — Server/Client 配置结构体、默认值、环境变量 - [x] **inp2ps 信令主循环** `internal/server/server.go` - [x] WSS 接受连接 → Login 验证 → 注册节点 - [x] 心跳管理 → 超时离线清理 - [x] ReportBasic 处理 **(必须回响应,OpenP2P 踩过的坑)** - [x] 节点上线广播 - [x] 连接协调 `internal/server/coordinator.go`(收到 A 的 ConnectReq → 同时推送给 A 和 B punch 参数) - [x] **inp2pc 信令主循环** `internal/client/client.go` - [x] WSS 连接 → Login → ReportBasic → 心跳 - [x] 断线重连(5s 退避) - [x] 收到 PushConnectReq 后触发打洞 - [x] 收到 PushNodeOnline 后重试 apps ### M2: NAT 探测(预计 200 行)✅ 完成 - [x] UDP STUN 客户端/服务端 `pkg/nat/` - [x] TCP STUN 回退 - [x] **集成到 inp2ps main**:启动 4 个 STUN listener(UDP×2 + TCP×2) - [x] **集成到 inp2pc main**:登录前先探测,结果带入 LoginReq - [ ] 定期重新探测(每 5 分钟),NATType 变化时通知 server ### M3: 打洞(预计 300 行)✅ 完成 - [x] UDP punch 基础实现 `pkg/punch/` - [x] TCP punch 基础实现 - [x] 优先级链(direct → UDP → TCP) - [x] **双端同步打洞协调** `internal/server/coordinator.go` - [x] server 收到 A 的 ConnectReq - [x] 同时推送 PunchStart 给 A 和 B(带对方的 IP:Port + NAT 类型) - [x] 双方同时调 `punch.Connect()` - [x] 任一方成功后报告 PunchResult - [ ] Symmetric NAT 端口预测(可选优化) - [ ] 打洞结果上报 + 统计 ### M4: 隧道 + 多路复用(预计 500 行)✅ 完成 - [x] 隧道框架 `pkg/tunnel/` — 端口转发、统计、生命周期 - [x] **流多路复用协议** `pkg/mux/` - [x] 帧格式:`StreamID(4B) + Flags(1B) + Len(2B) + Data` - [x] SYN/FIN/DATA/PING/PONG/RST 控制帧 - [x] Session(多路复用会话)+ Stream(虚拟连接,实现 net.Conn) - [x] Ring buffer 接收缓冲 - [x] 7 个单元测试 + 1 个性能基准测试 全部通过 - [x] TCP 端口转发实现(listener → mux stream → peer demux → dst connect) - [x] 端到端测试通过(echo server + tunnel + 验证数据一致性) - [x] 5 并发连接测试通过 - [ ] UDP 端口转发实现 - [x] 连接池/复用(同 peer 多 app 共享一条 tunnel) ### M5: 中继(预计 400 行)✅ 完成 - [x] 中继管理器 `pkg/relay/` — 完整实现(~320 行) - [x] **中继节点选择策略**(server 端 `server.GetRelayNodes()`) - [x] 同用户 `--relay` 节点优先 - [x] 全局 `--super` 节点次优 - [x] server 自身中继兜底 - [x] **中继握手协议**(长度前缀 JSON) - [x] A → relay: TCP 连接 + RelayHandshake{sessionID, role="from", token, node} - [x] B → relay: TCP 连接 + RelayHandshake{sessionID, role="to", token, node} - [x] relay: TOTP 验证 → 配对等待(30s 超时)→ 双向桥接 - [x] 结果回传 relayResult{error, detail} - [x] **中继认证** - [x] 同用户:TOTP(token, now) - [x] 跨用户超级节点:server 签发 `RelayToken`(HMAC-SHA256 签名,含 TTL) - [x] **客户端工具函数** `ConnectToRelay()` — 封装完整握手+等待配对 - [x] **测试覆盖**(3/3 通过) - [x] TestRelayBridge — A↔B 双向数据验证 - [x] TestRelayLargeData — 1MB 精确传输 - [x] TestRelayAuthDenied — 错误 TOTP 被正确拒绝 - [ ] 中继带宽统计 + 负载均衡 ### M6: inp2ps / inp2pc main 入口(预计 200 行)✅ 完成 - [x] `cmd/inp2ps/main.go` — flag 解析、启动 STUN + WSS + API + 优雅退出 - [x] `cmd/inp2pc/main.go` — flag 解析、config.json 读写、优雅退出 - [x] 端到端验证: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 模式(`-d` fork 子进程) - 自动更新(可选) ### 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 调用) ```go 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 配置持久化调用) ```go client.Run() error // 主循环(阻塞) client.Stop() // 优雅退出 // 配置通过 config.ClientConfig 传入 ```