From 288f469c3664473fdd80666cf4b9bc2ed83266ec Mon Sep 17 00:00:00 2001 From: V2Ray Date: Sun, 18 Oct 2015 16:06:55 +0200 Subject: [PATCH] Update design --- spec/design.md | 47 +----------------------------------------- spec/v2ray_design.png | Bin 0 -> 20352 bytes 2 files changed, 1 insertion(+), 46 deletions(-) create mode 100644 spec/v2ray_design.png diff --git a/spec/design.md b/spec/design.md index 3e541c63..fcd3978b 100644 --- a/spec/design.md +++ b/spec/design.md @@ -7,49 +7,4 @@ ## 架构 -### 术语 -* Point:一个 V2Ray 服务器称为 Point Server -* Set:一组 Point Server,包含多个 Point 进程,由一个 Master 进程统一管理。 -* SuperSet:多机环境中的多个 Set - -### 工作流程 -Point 可接收来自用户或其它 Point 的请求,并将请求转发至配置中的下一个 Point(或 Set 或 SuperSet) 或目标网站,然后将所得到的应答回复给请求来源。 -Point 采用白名单机制,只接受已认证帐号的请求。 - -### 通信协议 -* Point 之间默认使用自有 VMess 协议,或第三方自定义协议。 -* Point 和客户端之间可使用以下协议: - * HTTP Proxy - * SOCKS Proxy - * PPTP / L2TP / SSTP 等 VPN 隧道 - * 其它自定义协议 -* Point 和目标网站之间使用以下协议: - * HTTP / HTTPS - * UDP (DNS) - -#### VMess -VMess 为 V2Ray 的原生协议,设计用于两个 Point 之间的通信。[详细设计](https://github.com/V2Ray/v2ray-core/blob/master/spec/vmess.md) - -### Point -* 每个 Point 有一个 ID,运行时生成 -* 每个 Point 可使用独立的配置文件,或从 Set 继承 -* 一个 Point 监听主机上的一个特定端口(可配置),用于接收和发送数据 -* 一个 Point 运行于一个独立的进程,可设定其使用的系统帐户 - -### Set -TODO - -### SuperSet -TODO - -## Point 详细设计 -一个 Point 包含五个部分: -* 配置文件处理:读取和解析配置文件 -* 输入(Inbound):负责与客户端建立连接(如 TCP),接收客户端的消息 -* 输出(Outbound):负责向客户端发送消息 - -### 配置文件 -配置文件使用 JSON / ProtoBuf 兼容格式 - -## 编程语言 -暂定为 golang。 +![](https://github.com/V2Ray/v2ray-core/blob/master/spec/v2ray_design.png) diff --git a/spec/v2ray_design.png b/spec/v2ray_design.png new file mode 100644 index 0000000000000000000000000000000000000000..d2845c1786320ac93216d5e6ef1e47108094b0ac GIT binary patch literal 20352 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