## 开发相关 ### 目录结构 server/fwd: 服务端核心代码 - core: 核心代码,目前主要是连接管理 - dispatcher: 请求处理器,负责解析传入协议,并将请求分发到对应的处理器 - http: http 处理器,负责处理 http 请求 - socks: socks5 处理器,负责处理 socks5 请求 - repo: 状态仓库,所有有状态数据都通过 repo 中的接口与外部服务交互 ### 更新测试环境 1. 构建项目 2. 使用测试配置 `.env.test` 远程启动 docker ### 转发服务结束时资源清理 1. 关闭接听端口,防止新连接接入(user, data, ctrl) 2. 通知并等待所有正在运行的 conn 处理协程全部关闭(user, data, ctrl) 3. 结束所有保存且未使用的 conn 连接(user, ctrl) ### 代码清理 检查 slog 级别: ERR: 除非有必要,否则全部 error 都使用 `errors.Wrap()` 包裹(如果下游有返回 err),并附带本层业务信息,return 到上层统一打印 其他级别日志就地打印,Info 只用来跟踪关键流程 ### proxy.lock 文件格式 | mag_num(1) | name(16) | |-------------|-----------| | 魔法数,固定 0x72 | 服务名称,uuid | ## 协议 ### 步骤说明 1. 启动转发服务,尝试注册自身到后端服务,随后持续报告心跳 2. 启动边缘节点后,尝试注册自身到后端服务,随后持续报告心跳 3. 后端服务根据在线转发服务的状态,返回分配给边缘节点的转发服务地址 4. 边缘节点根据配置尝试连接到转发服务(建立控制通道) 5. 连接成功后,控制通道将长期保留,边缘节点定时发送保活心跳,代理服务丢弃所有心跳包 6. 当用户请求代理时,转发服务通过控制通道向边缘节点提供代理目标信息 7. 边缘节点尝试连接到目标地址,同时尝试建立数据通道 8. 当成功建立数据通道后,边缘节点将数据通道标识以及对目标地址的连接结果提供给转发服务 9. 如果连接成功建立,则开始代理流量,如果连接失败,则关闭数据通道 ### 协议报文详情 协议中所有数值都以大端形式传输 #### 建立控制通道 客户端: | id(4) | |--------| | 客户端 ID | 服务端: | status(1) | |-----------| | 状态,固定为 1 | #### 建立数据通道 服务端: | tag(16) | dst_len(2) | dst_buf(n) | |---------|------------|------------| | 通道标识 | 目标地址长度 | 目标地址 | 客户端: | tag(16) | status(1) | |---------|-----------------------| | 通道标识 | 目标地址连接结果,成功为 1,不成功为 0 |