diff --git a/config.go b/config.go new file mode 100644 index 000000000..58781d57f --- /dev/null +++ b/config.go @@ -0,0 +1,28 @@ +package core + +import ( + "encoding/json" +) + +// User is the user account that is used for connection to a Point +type User struct { + Id ID `json:"id"` // The ID of this User. +} + +type ConnectionConfig struct { + Protocol string `json:"protocol"` + File string `json:"file"` +} + +// Config is the config for Point server. +type Config struct { + Port uint16 `json:"port"` // Port of this Point server. + InboundConfig ConnectionConfig `json:"inbound"` + OutboundConfig ConnectionConfig `json:"outbound"` +} + +func LoadConfig(rawConfig []byte) (Config, error) { + config := Config{} + err := json.Unmarshal(rawConfig, &config) + return config, err +} diff --git a/vid.go b/id.go similarity index 78% rename from vid.go rename to id.go index f14879a09..0acb38930 100644 --- a/vid.go +++ b/id.go @@ -8,10 +8,10 @@ import ( ) // The ID of en entity, in the form of an UUID. -type VID [16]byte +type ID [16]byte -// Hash generates a MD5 hash based on current VID and a suffix string. -func (v VID) Hash(suffix []byte) []byte { +// Hash generates a MD5 hash based on current ID and a suffix string. +func (v ID) Hash(suffix []byte) []byte { md5 := md5.New() md5.Write(v[:]) md5.Write(suffix) @@ -21,7 +21,7 @@ func (v VID) Hash(suffix []byte) []byte { var byteGroups = []int{8, 4, 4, 4, 12} // TODO: leverage a full functional UUID library -func UUIDToVID(uuid string) (v VID, err error) { +func UUIDToID(uuid string) (v ID, err error) { text := []byte(uuid) if len(text) < 32 { err = log.Error("uuid: invalid UUID string: %s", text) diff --git a/vid_test.go b/id_test.go similarity index 83% rename from vid_test.go rename to id_test.go index aeda48ded..3346e4f76 100644 --- a/vid_test.go +++ b/id_test.go @@ -6,12 +6,12 @@ import ( "github.com/v2ray/v2ray-core/testing/unit" ) -func TestUUIDToVID(t *testing.T) { +func TestUUIDToID(t *testing.T) { assert := unit.Assert(t) uuid := "2418d087-648d-4990-86e8-19dca1d006d3" expectedBytes := []byte{0x24, 0x18, 0xd0, 0x87, 0x64, 0x8d, 0x49, 0x90, 0x86, 0xe8, 0x19, 0xdc, 0xa1, 0xd0, 0x06, 0xd3} - actualBytes, _ := UUIDToVID(uuid) + actualBytes, _ := UUIDToID(uuid) assert.Bytes(actualBytes[:]).Named("UUID").Equals(expectedBytes) } diff --git a/io/bufferset.go b/io/bufferset.go index d6bf5bf75..720257200 100644 --- a/io/bufferset.go +++ b/io/bufferset.go @@ -14,21 +14,21 @@ var ( ErrorNoChannel = errors.New("No suitable channels found.") ) -type VBufferSet struct { +type BufferSet struct { small chan []byte medium chan []byte large chan []byte } -func NewVBufferSet() *VBufferSet { - bSet := new(VBufferSet) +func NewBufferSet() *BufferSet { + bSet := new(BufferSet) bSet.small = make(chan []byte, 128) bSet.medium = make(chan []byte, 128) bSet.large = make(chan []byte, 128) return bSet } -func (bSet *VBufferSet) detectBucket(size int, strict bool) (chan []byte, error) { +func (bSet *BufferSet) detectBucket(size int, strict bool) (chan []byte, error) { if strict { if size == SizeSmall { return bSet.small, nil @@ -49,7 +49,7 @@ func (bSet *VBufferSet) detectBucket(size int, strict bool) (chan []byte, error) return nil, ErrorNoChannel } -func (bSet *VBufferSet) FetchBuffer(minSize int) []byte { +func (bSet *BufferSet) FetchBuffer(minSize int) []byte { var buffer []byte byteChan, err := bSet.detectBucket(minSize, false) if err != nil { @@ -63,7 +63,7 @@ func (bSet *VBufferSet) FetchBuffer(minSize int) []byte { return buffer } -func (bSet *VBufferSet) ReturnBuffer(buffer []byte) { +func (bSet *BufferSet) ReturnBuffer(buffer []byte) { byteChan, err := bSet.detectBucket(len(buffer), true) if err != nil { return diff --git a/io/socks/socks.go b/io/socks/socks.go index d9cc0e8d1..0c1bc3f8f 100644 --- a/io/socks/socks.go +++ b/io/socks/socks.go @@ -186,7 +186,7 @@ func ReadRequest(reader io.Reader) (request *Socks5Request, err error) { return } -func (request *Socks5Request) Destination() v2net.VAddress { +func (request *Socks5Request) Destination() v2net.Address { switch request.AddrType { case AddrTypeIPv4: return v2net.IPAddress(request.IPv4[:], request.Port) diff --git a/io/vmess/vmess.go b/io/vmess/vmess.go index dc60eae6c..86cb46815 100644 --- a/io/vmess/vmess.go +++ b/io/vmess/vmess.go @@ -35,19 +35,19 @@ var ( type VMessRequest struct { Version byte - UserId core.VID + UserId core.ID RequestIV [16]byte RequestKey [16]byte ResponseHeader [4]byte Command byte - Address v2net.VAddress + Address v2net.Address } type VMessRequestReader struct { - vUserSet *core.VUserSet + vUserSet *core.UserSet } -func NewVMessRequestReader(vUserSet *core.VUserSet) *VMessRequestReader { +func NewVMessRequestReader(vUserSet *core.UserSet) *VMessRequestReader { reader := new(VMessRequestReader) reader.vUserSet = vUserSet return reader diff --git a/io/vmess/vmess_test.go b/io/vmess/vmess_test.go index 057c7ae6d..43a37cfed 100644 --- a/io/vmess/vmess_test.go +++ b/io/vmess/vmess_test.go @@ -13,13 +13,13 @@ import ( func TestVMessSerialization(t *testing.T) { assert := unit.Assert(t) - userId, err := core.UUIDToVID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51") + userId, err := core.UUIDToID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51") if err != nil { t.Fatal(err) } - userSet := core.NewVUserSet() - userSet.AddUser(core.VUser{userId}) + userSet := core.NewUserSet() + userSet.AddUser(core.User{userId}) request := new(VMessRequest) request.Version = byte(0x01) diff --git a/net/freedom/freedom.go b/net/freedom/freedom.go index 5204b301c..17fbb5ad0 100644 --- a/net/freedom/freedom.go +++ b/net/freedom/freedom.go @@ -9,19 +9,19 @@ import ( v2net "github.com/v2ray/v2ray-core/net" ) -type VFreeConnection struct { - dest v2net.VAddress +type FreedomConnection struct { + dest v2net.Address } -func NewVFreeConnection(dest v2net.VAddress) *VFreeConnection { - conn := new(VFreeConnection) +func NewFreedomConnection(dest v2net.Address) *FreedomConnection { + conn := new(FreedomConnection) conn.dest = dest return conn } -func (vconn *VFreeConnection) Start(vRay core.OutboundVRay) error { - input := vRay.OutboundInput() - output := vRay.OutboundOutput() +func (vconn *FreedomConnection) Start(ray core.OutboundRay) error { + input := ray.OutboundInput() + output := ray.OutboundOutput() conn, err := net.Dial("tcp", vconn.dest.String()) if err != nil { return log.Error("Failed to open tcp: %s", vconn.dest.String()) @@ -35,7 +35,7 @@ func (vconn *VFreeConnection) Start(vRay core.OutboundVRay) error { return nil } -func (vconn *VFreeConnection) DumpInput(conn net.Conn, input <-chan []byte, finish chan<- bool) { +func (vconn *FreedomConnection) DumpInput(conn net.Conn, input <-chan []byte, finish chan<- bool) { for { data, open := <-input if !open { @@ -48,7 +48,7 @@ func (vconn *VFreeConnection) DumpInput(conn net.Conn, input <-chan []byte, fini } } -func (vconn *VFreeConnection) DumpOutput(conn net.Conn, output chan<- []byte, finish chan<- bool) { +func (vconn *FreedomConnection) DumpOutput(conn net.Conn, output chan<- []byte, finish chan<- bool) { for { buffer := make([]byte, 512) nBytes, err := conn.Read(buffer) @@ -63,7 +63,7 @@ func (vconn *VFreeConnection) DumpOutput(conn net.Conn, output chan<- []byte, fi } } -func (vconn *VFreeConnection) CloseConn(conn net.Conn, finish <-chan bool) { +func (vconn *FreedomConnection) CloseConn(conn net.Conn, finish <-chan bool) { for i := 0; i < 2; i++ { <-finish } diff --git a/net/freedom/freedomfactory.go b/net/freedom/freedomfactory.go index 11261cd6a..a1383fee8 100644 --- a/net/freedom/freedomfactory.go +++ b/net/freedom/freedomfactory.go @@ -8,8 +8,8 @@ import ( type FreedomFactory struct { } -func (factory FreedomFactory) Create(vp *core.VPoint, config []byte, dest v2net.VAddress) (core.OutboundConnectionHandler, error) { - return NewVFreeConnection(dest), nil +func (factory FreedomFactory) Create(vp *core.Point, config []byte, dest v2net.Address) (core.OutboundConnectionHandler, error) { + return NewFreedomConnection(dest), nil } func init() { diff --git a/net/socks/socks.go b/net/socks/socks.go index e84c3b064..bbc189941 100644 --- a/net/socks/socks.go +++ b/net/socks/socks.go @@ -19,11 +19,11 @@ var ( // SocksServer is a SOCKS 5 proxy server type SocksServer struct { accepting bool - vPoint *core.VPoint + vPoint *core.Point config SocksConfig } -func NewSocksServer(vp *core.VPoint, rawConfig []byte) *SocksServer { +func NewSocksServer(vp *core.Point, rawConfig []byte) *SocksServer { server := new(SocksServer) server.vPoint = vp config, err := loadConfig(rawConfig) diff --git a/net/socks/socks_test.go b/net/socks/socks_test.go index 97a2e02cd..58b881834 100644 --- a/net/socks/socks_test.go +++ b/net/socks/socks_test.go @@ -17,12 +17,12 @@ func TestSocksTcpConnect(t *testing.T) { port := uint16(12384) uuid := "2418d087-648d-4990-86e8-19dca1d006d3" - vid, err := core.UUIDToVID(uuid) + id, err := core.UUIDToID(uuid) assert.Error(err).IsNil() config := core.VConfig{ port, - []core.VUser{core.VUser{vid}}, + []core.User{core.User{id}}, "", []core.VNext{}} @@ -30,7 +30,7 @@ func TestSocksTcpConnect(t *testing.T) { och.Data2Send = bytes.NewBuffer(make([]byte, 1024)) och.Data2Return = []byte("The data to be returned to socks server.") - vpoint, err := core.NewVPoint(&config, SocksServerFactory{}, och) + vpoint, err := core.NewPoint(&config, SocksServerFactory{}, och) assert.Error(err).IsNil() err = vpoint.Start() diff --git a/net/socks/socksfactory.go b/net/socks/socksfactory.go index 9461b6767..e5e728d51 100644 --- a/net/socks/socksfactory.go +++ b/net/socks/socksfactory.go @@ -7,7 +7,7 @@ import ( type SocksServerFactory struct { } -func (factory SocksServerFactory) Create(vp *core.VPoint, config []byte) (core.InboundConnectionHandler, error) { +func (factory SocksServerFactory) Create(vp *core.Point, config []byte) (core.InboundConnectionHandler, error) { return NewSocksServer(vp, config), nil } diff --git a/net/vdest.go b/net/vdest.go index 769e23b5b..6855b4053 100644 --- a/net/vdest.go +++ b/net/vdest.go @@ -10,43 +10,43 @@ const ( AddrTypeDomain = byte(0x03) ) -type VAddress struct { +type Address struct { Type byte IP net.IP Domain string Port uint16 } -func IPAddress(ip []byte, port uint16) VAddress { +func IPAddress(ip []byte, port uint16) Address { // TODO: check IP length - return VAddress{ + return Address{ AddrTypeIP, net.IP(ip), "", port} } -func DomainAddress(domain string, port uint16) VAddress { - return VAddress{ +func DomainAddress(domain string, port uint16) Address { + return Address{ AddrTypeDomain, nil, domain, port} } -func (addr VAddress) IsIPv4() bool { +func (addr Address) IsIPv4() bool { return addr.Type == AddrTypeIP && len(addr.IP) == net.IPv4len } -func (addr VAddress) IsIPv6() bool { +func (addr Address) IsIPv6() bool { return addr.Type == AddrTypeIP && len(addr.IP) == net.IPv6len } -func (addr VAddress) IsDomain() bool { +func (addr Address) IsDomain() bool { return addr.Type == AddrTypeDomain } -func (addr VAddress) String() string { +func (addr Address) String() string { var host string switch addr.Type { case AddrTypeIP: diff --git a/net/vmess/config.go b/net/vmess/config.go index da902bf20..b823a3034 100644 --- a/net/vmess/config.go +++ b/net/vmess/config.go @@ -13,9 +13,9 @@ type VMessUser struct { Email string `json:"email"` } -func (u *VMessUser) ToVUser() (core.VUser, error) { - id, err := core.UUIDToVID(u.Id) - return core.VUser{id}, err +func (u *VMessUser) ToUser() (core.User, error) { + id, err := core.UUIDToID(u.Id) + return core.User{id}, err } type VMessInboundConfig struct { @@ -35,11 +35,11 @@ type VNextConfig struct { } func (config VNextConfig) ToVNextServer() VNextServer { - users := make([]core.VUser, 0, len(config.Users)) + users := make([]core.User, 0, len(config.Users)) for _, user := range config.Users { - vuser, err := user.ToVUser() + vuser, err := user.ToUser() if err != nil { - panic(log.Error("Failed to convert %v to VUser.", user)) + panic(log.Error("Failed to convert %v to User.", user)) } users = append(users, vuser) } diff --git a/net/vmess/vmessin.go b/net/vmess/vmessin.go index df404b6e4..3e440e9c3 100644 --- a/net/vmess/vmessin.go +++ b/net/vmess/vmessin.go @@ -13,12 +13,12 @@ import ( ) type VMessInboundHandler struct { - vPoint *core.VPoint - clients *core.VUserSet + vPoint *core.Point + clients *core.UserSet accepting bool } -func NewVMessInboundHandler(vp *core.VPoint, clients *core.VUserSet) *VMessInboundHandler { +func NewVMessInboundHandler(vp *core.Point, clients *core.UserSet) *VMessInboundHandler { handler := new(VMessInboundHandler) handler.vPoint = vp handler.clients = clients @@ -128,14 +128,14 @@ func (handler *VMessInboundHandler) waitForFinish(finish <-chan bool) { type VMessInboundHandlerFactory struct { } -func (factory *VMessInboundHandlerFactory) Create(vp *core.VPoint, rawConfig []byte) (core.InboundConnectionHandler, error) { +func (factory *VMessInboundHandlerFactory) Create(vp *core.Point, rawConfig []byte) (core.InboundConnectionHandler, error) { config, err := loadInboundConfig(rawConfig) if err != nil { panic(log.Error("Failed to load VMess inbound config: %v", err)) } - allowedClients := core.NewVUserSet() + allowedClients := core.NewUserSet() for _, client := range config.AllowedClients { - user, err := client.ToVUser() + user, err := client.ToUser() if err != nil { panic(log.Error("Failed to parse user id %s: %v", client.Id, err)) } diff --git a/net/vmess/vmessout.go b/net/vmess/vmessout.go index ef862618a..5284eadb3 100644 --- a/net/vmess/vmessout.go +++ b/net/vmess/vmessout.go @@ -14,19 +14,19 @@ import ( v2net "github.com/v2ray/v2ray-core/net" ) -// VNext is the next VPoint server in the connection chain. +// VNext is the next Point server in the connection chain. type VNextServer struct { - Address v2net.VAddress // Address of VNext server - Users []core.VUser // User accounts for accessing VNext. + Address v2net.Address // Address of VNext server + Users []core.User // User accounts for accessing VNext. } type VMessOutboundHandler struct { - vPoint *core.VPoint - dest v2net.VAddress + vPoint *core.Point + dest v2net.Address vNextList []VNextServer } -func NewVMessOutboundHandler(vp *core.VPoint, vNextList []VNextServer, dest v2net.VAddress) *VMessOutboundHandler { +func NewVMessOutboundHandler(vp *core.Point, vNextList []VNextServer, dest v2net.Address) *VMessOutboundHandler { handler := new(VMessOutboundHandler) handler.vPoint = vp handler.dest = dest @@ -34,7 +34,7 @@ func NewVMessOutboundHandler(vp *core.VPoint, vNextList []VNextServer, dest v2ne return handler } -func (handler *VMessOutboundHandler) pickVNext() (v2net.VAddress, core.VUser) { +func (handler *VMessOutboundHandler) pickVNext() (v2net.Address, core.User) { vNextLen := len(handler.vNextList) if vNextLen == 0 { panic("Zero vNext is configured.") @@ -50,7 +50,7 @@ func (handler *VMessOutboundHandler) pickVNext() (v2net.VAddress, core.VUser) { return vNext.Address, vNextUser } -func (handler *VMessOutboundHandler) Start(ray core.OutboundVRay) error { +func (handler *VMessOutboundHandler) Start(ray core.OutboundRay) error { vNextAddress, vNextUser := handler.pickVNext() request := new(vmessio.VMessRequest) @@ -66,7 +66,7 @@ func (handler *VMessOutboundHandler) Start(ray core.OutboundVRay) error { return nil } -func (handler *VMessOutboundHandler) startCommunicate(request *vmessio.VMessRequest, dest v2net.VAddress, ray core.OutboundVRay) error { +func (handler *VMessOutboundHandler) startCommunicate(request *vmessio.VMessRequest, dest v2net.Address, ray core.OutboundRay) error { conn, err := net.Dial("tcp", dest.String()) log.Debug("VMessOutbound dialing tcp: %s", dest.String()) if err != nil { @@ -155,7 +155,7 @@ func (handler *VMessOutboundHandler) waitForFinish(finish <-chan bool) { type VMessOutboundHandlerFactory struct { } -func (factory *VMessOutboundHandlerFactory) Create(vp *core.VPoint, rawConfig []byte, destination v2net.VAddress) (core.OutboundConnectionHandler, error) { +func (factory *VMessOutboundHandlerFactory) Create(vp *core.Point, rawConfig []byte, destination v2net.Address) (core.OutboundConnectionHandler, error) { config, err := loadOutboundConfig(rawConfig) if err != nil { panic(log.Error("Failed to load VMess outbound config: %v", err)) diff --git a/vpoint.go b/point.go similarity index 79% rename from vpoint.go rename to point.go index 5a3fb4506..beab557a3 100644 --- a/vpoint.go +++ b/point.go @@ -24,8 +24,8 @@ func RegisterOutboundConnectionHandlerFactory(name string, factory OutboundConne return nil } -// VPoint is an single server in V2Ray system. -type VPoint struct { +// Point is an single server in V2Ray system. +type Point struct { port uint16 ichFactory InboundConnectionHandlerFactory ichConfig []byte @@ -33,10 +33,10 @@ type VPoint struct { ochConfig []byte } -// NewVPoint returns a new VPoint server based on given configuration. +// NewPoint returns a new Point server based on given configuration. // The server is not started at this point. -func NewVPoint(config VConfig) (*VPoint, error) { - var vpoint = new(VPoint) +func NewPoint(config Config) (*Point, error) { + var vpoint = new(Point) vpoint.port = config.Port ichFactory, ok := inboundFactories[config.InboundConfig.Protocol] @@ -70,7 +70,7 @@ func NewVPoint(config VConfig) (*VPoint, error) { } type InboundConnectionHandlerFactory interface { - Create(vp *VPoint, config []byte) (InboundConnectionHandler, error) + Create(vp *Point, config []byte) (InboundConnectionHandler, error) } type InboundConnectionHandler interface { @@ -78,16 +78,16 @@ type InboundConnectionHandler interface { } type OutboundConnectionHandlerFactory interface { - Create(VP *VPoint, config []byte, dest v2net.VAddress) (OutboundConnectionHandler, error) + Create(VP *Point, config []byte, dest v2net.Address) (OutboundConnectionHandler, error) } type OutboundConnectionHandler interface { - Start(vray OutboundVRay) error + Start(ray OutboundRay) error } -// Start starts the VPoint server, and return any error during the process. +// Start starts the Point server, and return any error during the process. // In the case of any errors, the state of the server is unpredicatable. -func (vp *VPoint) Start() error { +func (vp *Point) Start() error { if vp.port <= 0 { return log.Error("Invalid port %d", vp.port) } @@ -99,8 +99,8 @@ func (vp *VPoint) Start() error { return nil } -func (vp *VPoint) NewInboundConnectionAccepted(destination v2net.VAddress) InboundVRay { - ray := NewVRay() +func (vp *Point) NewInboundConnectionAccepted(destination v2net.Address) InboundRay { + ray := NewRay() // TODO: handle error och, _ := vp.ochFactory.Create(vp, vp.ochConfig, destination) _ = och.Start(ray) diff --git a/ray.go b/ray.go new file mode 100644 index 000000000..bcfa013af --- /dev/null +++ b/ray.go @@ -0,0 +1,36 @@ +package core + +type Ray struct { + Input chan []byte + Output chan []byte +} + +func NewRay() Ray { + return Ray{make(chan []byte, 128), make(chan []byte, 128)} +} + +type OutboundRay interface { + OutboundInput() <-chan []byte + OutboundOutput() chan<- []byte +} + +type InboundRay interface { + InboundInput() chan<- []byte + InboundOutput() <-chan []byte +} + +func (ray Ray) OutboundInput() <-chan []byte { + return ray.Input +} + +func (ray Ray) OutboundOutput() chan<- []byte { + return ray.Output +} + +func (ray Ray) InboundInput() chan<- []byte { + return ray.Input +} + +func (ray Ray) InboundOutput() <-chan []byte { + return ray.Output +} diff --git a/release/server/main.go b/release/server/main.go index c8c16b9c5..34e9206be 100644 --- a/release/server/main.go +++ b/release/server/main.go @@ -14,7 +14,7 @@ import ( ) var ( - configFile = flag.String("config", "", "Config file for this VPoint server.") + configFile = flag.String("config", "", "Config file for this Point server.") ) func main() { @@ -29,9 +29,9 @@ func main() { if err != nil { panic(log.Error("Failed to read config file (%s): %v", *configFile, err)) } - vconfig, err := core.LoadVConfig(rawVConfig) + vconfig, err := core.LoadConfig(rawVConfig) if err != nil { - panic(log.Error("Failed to parse VConfig: %v", err)) + panic(log.Error("Failed to parse Config: %v", err)) } if !path.IsAbs(vconfig.InboundConfig.File) && len(vconfig.InboundConfig.File) > 0 { @@ -42,14 +42,14 @@ func main() { vconfig.OutboundConfig.File = path.Join(path.Dir(*configFile), vconfig.OutboundConfig.File) } - vPoint, err := core.NewVPoint(vconfig) + vPoint, err := core.NewPoint(vconfig) if err != nil { - panic(log.Error("Failed to create VPoint server: %v", err)) + panic(log.Error("Failed to create Point server: %v", err)) } err = vPoint.Start() if err != nil { - log.Error("Error starting VPoint server.") + log.Error("Error starting Point server: %v", err) } finish := make(chan bool) diff --git a/spec/design.md b/spec/design.md index 84ee30d6e..6048fde81 100644 --- a/spec/design.md +++ b/spec/design.md @@ -8,13 +8,13 @@ ## 架构 ### 术语 -* VPoint:一个 V2Ray 服务器称为 VPoint -* VSet:本机上的一组 VPoint -* VSuperSet:多机环境中的多个 VSet -* VSource:用户所使用的需要翻墙的软件,比如浏览器 -* VEnd:用户需要访问的网站 -* VUser:一个受到 VPoint 认证的帐号 -* [VID](https://github.com/V2Ray/v2ray-core/blob/master/spec/vid.md):全局唯一的 ID,类似于 UUID +* Point:一个 V2Ray 服务器称为 VPoint +* Set:本机上的一组 VPoint +* SuperSet:多机环境中的多个 VSet +* Source:用户所使用的需要翻墙的软件,比如浏览器 +* End:用户需要访问的网站 +* User:一个受到 VPoint 认证的帐号 +* [ID](https://github.com/V2Ray/v2ray-core/blob/master/spec/id.md):全局唯一的 ID,类似于 UUID ### 工作流程 @@ -35,29 +35,29 @@ VPoint 采用白名单机制,只接受已认证帐号的请求。 #### VMess VMess 为 V2Ray 的原生协议,设计用于两个 VPoint 之间的通信。[详细设计](https://github.com/V2Ray/v2ray-core/blob/master/spec/vmess.md) -### VUser -* 每个 VUser 有一个 VID +### User +* 每个 User 有一个 ID -### VPoint -* 每个 VPoint 有一个 VID,运行时生成 -* 每个 VPoint 可使用独立的配置文件,或从 VSet 继承 -* 一个 VPoint 监听主机上的一个特定端口(可配置),用于接收和发送数据 -* 一个 VPoint 运行于一个独立的进程,可设定其使用的系统帐户 +### Point +* 每个 Point 有一个 ID,运行时生成 +* 每个 Point 可使用独立的配置文件,或从 VSet 继承 +* 一个 Point 监听主机上的一个特定端口(可配置),用于接收和发送数据 +* 一个 Point 运行于一个独立的进程,可设定其使用的系统帐户 -### VSet +### Set TODO -### VSuperSet +### SuperSet TODO -## VPoint 详细设计 -一个 VPoint 包含五个部分: +## Point 详细设计 +一个 Point 包含五个部分: * 配置文件处理:读取和解析配置文件 * 输入:负责与客户端建立连接(如 TCP),接收客户端的消息 * 控制中心:负责处理事件 * 加密解密 - * VPoint 负载均衡 -* VPoint 进程间通信 + * Point 负载均衡 +* Point 进程间通信 * 输出:负责向客户端发送消息 ### 配置文件 @@ -73,16 +73,16 @@ TODO 控制中心响应以下事件: **INIT** -* 输入:用户 VID -* 输出:如果用户 VID 有效:"OK",否则关闭连接 +* 输入:用户 ID +* 输出:如果用户 ID 有效:"OK",否则关闭连接 **MSG** * 输入:VMess 消息 * 输出:对应的响应消息 **END** -* 输入:用户 VID -* 输出:如果用户 VID 有效:关闭连接 +* 输入:用户 ID +* 输出:如果用户 ID 有效:关闭连接 ## 编程语言 暂定为 golang。 diff --git a/spec/id.md b/spec/id.md new file mode 100644 index 000000000..1a4c69b64 --- /dev/null +++ b/spec/id.md @@ -0,0 +1,14 @@ +# ID 的定义和使用 + +ID 等价于 [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier),是一个 16 字节长的随机数,它的作用相当于一个令牌(Token)。 + +## 设计 +一个 ID 形如:de305d54-75b4-431b-adb2-eb6b9e546014,几乎完全随机,可以使用任何的 UUID 生成器来生成,比如[这个](https://www.uuidgenerator.net/)。 + +## 使用 +ID 在消息传递过程中用于验证客户端的有效性,只有当服务器认可当前 ID 时,才进行后续操作,否则关闭连接甚至加入黑名单。 + +在多用户环境中,用户帐号应与 ID 分开存放,即用户帐号和 ID 有一对一或一对多的关系,在 Point 系统中,只负责管理 ID,用户帐号(及权限、费用等)由另外的系统管理。 + +在后续版本中,Point 之间应有能力进行沟通而生成新的临时 ID,从而减少通讯的可探测性。 + diff --git a/spec/vid.md b/spec/vid.md deleted file mode 100644 index 39549c9d9..000000000 --- a/spec/vid.md +++ /dev/null @@ -1,14 +0,0 @@ -# VID 的定义和使用 - -VID 等价于 [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier),是一个 16 字节长的随机数,它的作用相当于一个令牌(Token)。 - -## 设计 -一个 VID 形如:de305d54-75b4-431b-adb2-eb6b9e546014,几乎完全随机,可以使用任何的 UUID 生成器来生成,比如[这个](https://www.uuidgenerator.net/)。 - -## 使用 -VID 在消息传递过程中用于验证客户端的有效性,只有当服务器认可当前 VID 时,才进行后续操作,否则关闭连接甚至加入黑名单。 - -在多用户环境中,用户帐号应与 VID 分开存放,即用户帐号和 VID 有一对一或一对多的关系,在 VPoint 系统中,只负责管理 VID,用户帐号(及权限、费用等)由另外的系统管理。 - -在后续版本中,VPoint 之间应有能力进行沟通而生成新的临时 VID,从而减少通讯的可探测性。 - diff --git a/spec/vmess.md b/spec/vmess.md index 11fb6f17c..a57eaf8ed 100644 --- a/spec/vmess.md +++ b/spec/vmess.md @@ -7,7 +7,7 @@ * 1 字节:版本号,目前为 0x1 认证部分: -* 16 字节:md5(用户 VID + 'ASK') +* 16 字节:md5(用户 ID + 'ASK') 指令部分: * 1 字节:随机填充长度 M (0 < M <= 32) @@ -34,7 +34,7 @@ 数据部分 * N 字节:请求数据 -其中指令部分经过 AES-128 加密,Key 为 md5(用户 VID + 'PWD');数据部分使用 AES-128-CBC 加密 +其中指令部分经过 AES-128 加密,Key 为 md5(用户 ID + 'PWD');数据部分使用 AES-128-CBC 加密 ## 数据应答 认证部分: diff --git a/testing/mocks/fakeoutboundhandler.go b/testing/mocks/fakeoutboundhandler.go index 4521f85c9..be2944d41 100644 --- a/testing/mocks/fakeoutboundhandler.go +++ b/testing/mocks/fakeoutboundhandler.go @@ -10,10 +10,10 @@ import ( type FakeOutboundConnectionHandler struct { Data2Send *bytes.Buffer Data2Return []byte - Destination v2net.VAddress + Destination v2net.Address } -func (handler *FakeOutboundConnectionHandler) Start(ray core.OutboundVRay) error { +func (handler *FakeOutboundConnectionHandler) Start(ray core.OutboundRay) error { input := ray.OutboundInput() output := ray.OutboundOutput() @@ -28,6 +28,6 @@ func (handler *FakeOutboundConnectionHandler) Start(ray core.OutboundVRay) error return nil } -func (handler *FakeOutboundConnectionHandler) Create(vPoint *core.VPoint, dest v2net.VAddress) (core.OutboundConnectionHandler, error) { +func (handler *FakeOutboundConnectionHandler) Create(point *core.Point, dest v2net.Address) (core.OutboundConnectionHandler, error) { return handler, nil } diff --git a/vuserset.go b/userset.go similarity index 70% rename from vuserset.go rename to userset.go index 6f7f3db55..f861f2159 100644 --- a/vuserset.go +++ b/userset.go @@ -4,14 +4,14 @@ import ( "encoding/base64" ) -type VUserSet struct { - validUserIds []VID +type UserSet struct { + validUserIds []ID userIdsAskHash map[string]int } -func NewVUserSet() *VUserSet { - vuSet := new(VUserSet) - vuSet.validUserIds = make([]VID, 0, 16) +func NewUserSet() *UserSet { + vuSet := new(UserSet) + vuSet.validUserIds = make([]ID, 0, 16) vuSet.userIdsAskHash = make(map[string]int) return vuSet } @@ -20,7 +20,7 @@ func hashBytesToString(hash []byte) string { return base64.StdEncoding.EncodeToString(hash) } -func (us *VUserSet) AddUser(user VUser) error { +func (us *UserSet) AddUser(user User) error { id := user.Id us.validUserIds = append(us.validUserIds, id) @@ -30,7 +30,7 @@ func (us *VUserSet) AddUser(user VUser) error { return nil } -func (us VUserSet) IsValidUserId(askHash []byte) (*VID, bool) { +func (us UserSet) IsValidUserId(askHash []byte) (*ID, bool) { askBase64 := hashBytesToString(askHash) idIndex, found := us.userIdsAskHash[askBase64] if found { diff --git a/vconfig.go b/vconfig.go deleted file mode 100644 index b8f8a4162..000000000 --- a/vconfig.go +++ /dev/null @@ -1,28 +0,0 @@ -package core - -import ( - "encoding/json" -) - -// VUser is the user account that is used for connection to a VPoint -type VUser struct { - Id VID `json:"id"` // The ID of this VUser. -} - -type VConnectionConfig struct { - Protocol string `json:"protocol"` - File string `json:"file"` -} - -// VConfig is the config for VPoint server. -type VConfig struct { - Port uint16 `json:"port"` // Port of this VPoint server. - InboundConfig VConnectionConfig `json:"inbound"` - OutboundConfig VConnectionConfig `json:"outbound"` -} - -func LoadVConfig(rawConfig []byte) (VConfig, error) { - config := VConfig{} - err := json.Unmarshal(rawConfig, &config) - return config, err -} diff --git a/vray.go b/vray.go deleted file mode 100644 index 9c4599cfc..000000000 --- a/vray.go +++ /dev/null @@ -1,36 +0,0 @@ -package core - -type VRay struct { - Input chan []byte - Output chan []byte -} - -func NewVRay() VRay { - return VRay{make(chan []byte, 128), make(chan []byte, 128)} -} - -type OutboundVRay interface { - OutboundInput() <-chan []byte - OutboundOutput() chan<- []byte -} - -type InboundVRay interface { - InboundInput() chan<- []byte - InboundOutput() <-chan []byte -} - -func (ray VRay) OutboundInput() <-chan []byte { - return ray.Input -} - -func (ray VRay) OutboundOutput() chan<- []byte { - return ray.Output -} - -func (ray VRay) InboundInput() chan<- []byte { - return ray.Input -} - -func (ray VRay) InboundOutput() <-chan []byte { - return ray.Output -}