V2Ray 10 سال پیش
کامیت
4c03bf0d45
10فایلهای تغییر یافته به همراه338 افزوده شده و 0 حذف شده
  1. 22 0
      LICENSE
  2. 22 0
      README.md
  3. 38 0
      io/jsonvconfigmarshaller.go
  4. 32 0
      io/vmessreader.go
  5. 9 0
      net/vmesshandler.go
  6. 88 0
      spec/design.md
  7. 42 0
      spec/vmess.md
  8. 20 0
      vconfig.go
  9. 38 0
      vid.go
  10. 27 0
      vpoint.go

+ 22 - 0
LICENSE

@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 V2 Ray
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+

+ 22 - 0
README.md

@@ -0,0 +1,22 @@
+# Project V2Ray
+
+V2Ray 是一个翻墙工具包,用于简化和复用其它翻墙工具,加速二次开发。
+
+“V2”来源于 [V2 火箭](https://zh.wikipedia.org/wiki/V-2%E7%81%AB%E7%AE%AD),Ray 即射线,意指新一代的翻墙工具。
+
+## 主要特点
+* 多对多服务器支持,负载均衡
+* 支持多用户
+* 开放协议支持,兼容 ShadowSocks 和 GoAgent
+
+## 概要设计
+[链接](https://github.com/V2Ray/v2ray-core/blob/master/spec/design.md)
+
+## 开发日程
+
+2015.11 **1.0** 完成,单服务器模式,可独立运行
+2016.01 **1.5** 完成,兼容 ShadowSocks 协议
+2016.04 **2.0** 完成,多服务器模式
+
+## 关于
+我是只是一名普通的开发人员,已肉翻,本已不依赖这些翻墙工具,但 ShadowSock 和 GoAgent 被迫删除代码的事件实在太恶心,不得不做点什么了。

+ 38 - 0
io/jsonvconfigmarshaller.go

@@ -0,0 +1,38 @@
+package io
+
+import (
+  "encoding/json"
+  _ "fmt"
+  "github.com/v2ray/v2ray-core"
+)
+
+type JsonVUser struct {
+  id string `json:"id"`
+  email string `json:"email"`
+}
+
+type JsonVConfig struct {
+  RunAs string `json:"runas"`
+  Port uint8 `json:"port"`
+  Clients []JsonVUser `json:"users"`
+  Protocol string `json:"protocol"`
+}
+
+type JsonVConfigUnmarshaller struct {
+  
+}
+
+func StringToVUser(id string) (u core.VUser, err error) {
+  return
+}
+
+func (*JsonVConfigUnmarshaller) Unmarshall(data []byte) (*core.VConfig, error) {
+  var jsonConfig JsonVConfig
+  err := json.Unmarshal(data, &jsonConfig)
+  if err != nil {
+    return nil, err
+  }
+  var vconfig = new(core.VConfig)
+  vconfig.RunAs = core.VUser{}
+  return vconfig, nil
+}

+ 32 - 0
io/vmessreader.go

@@ -0,0 +1,32 @@
+package io
+
+import (
+  "net"
+)
+
+type VMessInput struct {
+  version byte
+  userHash [16]byte
+  randHash [256]byte
+  respKey [32]byte
+  iv [16]byte
+  command byte
+  port uint16
+  target [256]byte
+  data []byte
+}
+
+type VMessReader struct {
+  conn *net.Conn
+}
+
+func NewVMessReader(conn *net.Conn) (VMessReader, error) {
+  var reader VMessReader
+  reader.conn = conn
+  return reader, nil
+}
+
+func (*VMessReader) Read() (VMessInput, error) {
+  var input VMessInput
+  return input, nil
+}

+ 9 - 0
net/vmesshandler.go

@@ -0,0 +1,9 @@
+package net
+
+type VMessHandler struct {
+  
+}
+
+func (*VMessHandler) Listen(port uint8) error {
+  return nil
+}

+ 88 - 0
spec/design.md

@@ -0,0 +1,88 @@
+# V2Ray 设计概要
+
+## 目标
+* V2Ray 自身提供基础的翻墙功能,单独使用可满足日常需求;
+* V2Ray 可被用于二次开发,可为用户提供个性化的翻墙体验,从而也达到难以统一屏蔽之效果;
+* V2Ray 为模块化设计,模块之间互相独立。每个模块可单独使用,也可和其它模块搭配使用。
+
+## 架构
+
+### 术语
+* VPoint:一个 V2Ray 服务器称为 VPoint
+* VSet:本机上的一组 VPoint
+* VSuperSet:多机环境中的多个 VSet
+* VSource:用户所使用的需要翻墙的软件,比如浏览器
+* VEnd:用户需要访问的网站
+* VUser:一个受到 VPoint 认证的帐号
+* VID:全局唯一的 ID,类似于 UUID
+
+
+### 工作流程
+VPoint 可提收来自 VSource 或其它 VPoint 的请求,并将请求转发至配置中的下一个 VPoint(或 VSet 或 VSuperSet) 或目标网站,然后将所得到的应答回复给请求来源。
+VPoint 采用白名单机制,只接受已认证帐号的请求。
+
+### 通信协议
+* VPoint 之间默认使用自有 VMess 协议,或第三方自定义协议。
+* VPoint 和客户端之间可使用以下协议:
+  * HTTP Proxy
+  * SOCKS 5 Proxy
+  * PPTP / L2TP / SSTP 等 VPN 隧道
+  * 其它自定义协议
+* VPoint 和目标网站之间使用以下协议:
+  * HTTP / HTTPS
+  * UDP (DNS)
+
+#### VMess
+VMess 为 V2Ray 的原生协议,设计用于两个 VPoint 之间的通信。[详细设计](https://github.com/V2Ray/v2ray-core/blob/master/spec/vmess.md)
+
+### VUser
+* 每个 VUser 有一个 VID
+
+### VPoint
+* 每个 VPoint 有一个 VID,运行时生成
+* 每个 VPoint 可使用独立的配置文件,或从 VSet 继承
+* 一个 VPoint 监听主机上的一个特定端口(可配置),用于接收和发送数据
+* 一个 VPoint 运行于一个独立的进程,可设定其使用的系统帐户
+
+### VSet
+TODO
+
+### VSuperSet
+TODO
+
+## VPoint 详细设计
+一个 VPoint 包含五个部分:
+* 配置文件处理:读取和解析配置文件
+* 输入:负责与客户端建立连接(如 TCP),接收客户端的消息
+* 控制中心:负责处理事件
+  * 加密解密
+  * VPoint 负载均衡
+* VPoint 进程间通信
+* 输出:负责向客户端发送消息
+
+### 配置文件
+配置文件使用 JSON / ProtoBuf 兼容格式,定义 TODO
+
+### 加密
+TODO
+
+### 任务处理
+TODO
+
+### 控制中心
+控制中心响应以下事件:
+
+**INIT**
+* 输入:用户 VID
+* 输出:如果用户 VID 有效:"OK",否则关闭连接
+
+**MSG**
+* 输入:VMess 消息
+* 输出:对应的响应消息
+
+**END**
+* 输入:用户 VID
+* 输出:如果用户 VID 有效:关闭连接
+
+## 编程语言
+暂定为 golang。

+ 42 - 0
spec/vmess.md

@@ -0,0 +1,42 @@
+# VMess 设计
+## 摘要
+* 版本:1
+
+## 数据请求
+* 1 字节:版本号,目前为 0x1
+* 16 字节:md5(用户 VID + 'ASK')
+* 1 字节:余下字节数 L
+* 1 字节:随机填充长度 M (M <= 32)
+* M 字节:随机填充内容
+* 32 字节:应答所使用的 AES Key AK
+* 1 字节:保留
+* X 字节:实际请求内容
+  * 16 字节:IV
+  * 1 字节:指令
+    * 0x0:保留
+    * 0x1:TCP 请求
+    * 0x2:UDP 请求
+  * 2 字节:目标端口
+  * 1 字节:目标类型
+    * 0x01:IPv4
+    * 0x02:域名
+    * 0x03:IPv6
+  * 目标地址:
+    * 4 字节:IPv4
+    * 2 字节长度 + 域名
+    * 16 字节:IPv6
+  * 4 字节:请求长度 N
+  * N 字节:请求数据
+
+其中第 18 字节开始所有内容经过 AES-256 加密,Key 为 left(用户 VID, 32)。
+
+## 数据应答
+* 1 字节:版本号,目前为 0x1
+* 16 字节:md5(用户 VID + 'ANS')
+* 1 字节:余下字节数 L
+* L 字节
+  * 16 字节:IV
+  * 1 字节:数据长度
+  * N 字节:应答数据
+
+其中第 18 字节开始所有内容经过 AES-256 加密,Key 为 AK。

+ 20 - 0
vconfig.go

@@ -0,0 +1,20 @@
+package core
+
+type VUser struct {
+  id VID
+}
+
+type VConfig struct {
+  RunAs VUser
+  Port uint16
+  AllowedClients []VUser
+  AllowedProtocol string
+}
+
+type VConfigMarshaller interface {
+  Marshal(config VConfig) ([]byte, error)
+}
+
+type VConfigUnmarshaller interface {
+  Unmarshal(data []byte) (VConfig, error)
+}

+ 38 - 0
vid.go

@@ -0,0 +1,38 @@
+package core
+
+import (
+  "encoding/hex"
+  "fmt"
+)
+
+type VID [16]byte
+
+var byteGroups = []int{8, 4, 4, 4, 12}
+
+// TODO: leverage a full functional UUID library
+func UUIDToVID(uuid string) (v VID, err error) {
+  text := []byte(uuid)
+  if len(text) < 32 {
+		err = fmt.Errorf("uuid: invalid UUID string: %s", text)
+		return
+	}
+
+	b := v[:]
+
+	for _, byteGroup := range byteGroups {
+		if text[0] == '-' {
+			text = text[1:]
+		}
+
+		_, err = hex.Decode(b[:byteGroup/2], text[:byteGroup])
+
+		if err != nil {
+			return
+		}
+
+		text = text[byteGroup:]
+		b = b[byteGroup/2:]
+	}
+
+	return
+}

+ 27 - 0
vpoint.go

@@ -0,0 +1,27 @@
+package core
+
+import (
+  "fmt"
+)
+
+type VPoint struct {
+  config VConfig
+  connHandler ConnectionHandler
+}
+
+func NewVPoint(config *VConfig) (*VPoint, error) {
+  var vpoint *VPoint
+  return vpoint, nil
+}
+
+type ConnectionHandler interface {
+  Listen(port uint16) error
+}
+
+func (vp *VPoint) Start() error {
+  if vp.config.Port <= 0 {
+    return fmt.Errorf("Invalid port %d", vp.config.Port)
+  }
+  vp.connHandler.Listen(vp.config.Port)
+  return nil
+}