From 72b4eeba8bb4abca69be9d348f1cee4f0de088b4 Mon Sep 17 00:00:00 2001 From: V2Ray Date: Tue, 6 Oct 2015 23:11:08 +0200 Subject: [PATCH] Simpilify configuration files --- config.go => config/config.go | 11 +++- config/json/config_cache.go | 20 +++++++ config/json/json.go | 38 ++++++------- config/json/json_test.go | 40 ++++++++------ point.go | 30 +++++----- proxy/freedom/config/json/json.go | 15 +++++ proxy/freedom/freedom_test.go | 11 ++-- proxy/freedom/freedomfactory.go | 6 +- proxy/socks/config/json/config.go | 11 ++-- proxy/socks/socks.go | 9 +-- proxy/socks/socks_test.go | 22 ++++++-- proxy/socks/socksfactory.go | 5 +- proxy/vmess/config.go | 21 ++++--- proxy/vmess/vmess_test.go | 47 +++++++++++++--- proxy/vmess/vmessin.go | 8 +-- proxy/vmess/vmessout.go | 18 +----- release/config/in_socks.json | 4 -- release/config/in_vmess.json | 6 -- release/config/out_vmess.json | 12 ---- release/config/vpoint_socks_vmess.json | 18 +++++- release/config/vpoint_vmess_freedom.json | 9 ++- release/server/main.go | 3 +- spec/guide.md | 70 +++++++++--------------- testing/mocks/config.go | 12 ++-- testing/mocks/inboundhandler.go | 2 +- testing/mocks/outboundhandler.go | 6 +- testing/unit/subject.go | 5 +- 27 files changed, 251 insertions(+), 208 deletions(-) rename config.go => config/config.go (53%) create mode 100644 config/json/config_cache.go create mode 100644 proxy/freedom/config/json/json.go delete mode 100644 release/config/in_socks.json delete mode 100644 release/config/in_vmess.json delete mode 100644 release/config/out_vmess.json diff --git a/config.go b/config/config.go similarity index 53% rename from config.go rename to config/config.go index bceee850..6f8237e9 100644 --- a/config.go +++ b/config/config.go @@ -1,8 +1,15 @@ -package core +package config + +type Type string + +const ( + TypeInbound = Type("inbound") + TypeOutbound = Type("outbound") +) type ConnectionConfig interface { Protocol() string - Content() []byte + Settings(configType Type) interface{} } type PointConfig interface { diff --git a/config/json/config_cache.go b/config/json/config_cache.go new file mode 100644 index 00000000..d6204a59 --- /dev/null +++ b/config/json/config_cache.go @@ -0,0 +1,20 @@ +package json + +import ( + "github.com/v2ray/v2ray-core/config" +) + +type ConfigObjectCreator func() interface{} + +var ( + configCache = make(map[string]ConfigObjectCreator) +) + +func getConfigKey(protocol string, cType config.Type) string { + return protocol + "_" + string(cType) +} + +func RegisterConfigType(protocol string, cType config.Type, creator ConfigObjectCreator) { + // TODO: check name + configCache[getConfigKey(protocol, cType)] = creator +} diff --git a/config/json/json.go b/config/json/json.go index 725168b3..16664335 100644 --- a/config/json/json.go +++ b/config/json/json.go @@ -4,30 +4,32 @@ import ( "encoding/json" "io/ioutil" "os" - "path/filepath" - "github.com/v2ray/v2ray-core" "github.com/v2ray/v2ray-core/common/log" + "github.com/v2ray/v2ray-core/config" ) type ConnectionConfig struct { - ProtocolString string `json:"protocol"` - File string `json:"file"` + ProtocolString string `json:"protocol"` + SettingsMessage json.RawMessage `json:"settings"` } func (config *ConnectionConfig) Protocol() string { return config.ProtocolString } -func (config *ConnectionConfig) Content() []byte { - if len(config.File) == 0 { - return nil +func (config *ConnectionConfig) Settings(configType config.Type) interface{} { + creator, found := configCache[getConfigKey(config.Protocol(), configType)] + if !found { + panic("Unknown protocol " + config.Protocol()) } - content, err := ioutil.ReadFile(config.File) + configObj := creator() + err := json.Unmarshal(config.SettingsMessage, configObj) if err != nil { - panic(log.Error("Failed to read config file (%s): %v", config.File, err)) + log.Error("Unable to parse connection config: %v", err) + panic("Failed to parse connection config.") } - return content + return configObj } // Config is the config for Point server. @@ -41,11 +43,11 @@ func (config *Config) Port() uint16 { return config.PortValue } -func (config *Config) InboundConfig() core.ConnectionConfig { +func (config *Config) InboundConfig() config.ConnectionConfig { return config.InboundConfigValue } -func (config *Config) OutboundConfig() core.ConnectionConfig { +func (config *Config) OutboundConfig() config.ConnectionConfig { return config.OutboundConfigValue } @@ -53,24 +55,16 @@ func LoadConfig(file string) (*Config, error) { fixedFile := os.ExpandEnv(file) rawConfig, err := ioutil.ReadFile(fixedFile) if err != nil { - log.Error("Failed to read point config file (%s): %v", file, err) + log.Error("Failed to read server config file (%s): %v", file, err) return nil, err } config := &Config{} err = json.Unmarshal(rawConfig, config) if err != nil { - log.Error("Failed to load point config: %v", err) + log.Error("Failed to load server config: %v", err) return nil, err } - if !filepath.IsAbs(config.InboundConfigValue.File) && len(config.InboundConfigValue.File) > 0 { - config.InboundConfigValue.File = filepath.Join(filepath.Dir(fixedFile), config.InboundConfigValue.File) - } - - if !filepath.IsAbs(config.OutboundConfigValue.File) && len(config.OutboundConfigValue.File) > 0 { - config.OutboundConfigValue.File = filepath.Join(filepath.Dir(fixedFile), config.OutboundConfigValue.File) - } - return config, err } diff --git a/config/json/json_test.go b/config/json/json_test.go index 7408b292..df4dc066 100644 --- a/config/json/json_test.go +++ b/config/json/json_test.go @@ -1,9 +1,15 @@ -package json +package json_test import ( "path/filepath" "testing" + "github.com/v2ray/v2ray-core/config" + "github.com/v2ray/v2ray-core/config/json" + _ "github.com/v2ray/v2ray-core/proxy/freedom/config/json" + _ "github.com/v2ray/v2ray-core/proxy/socks/config/json" + _ "github.com/v2ray/v2ray-core/proxy/vmess" + "github.com/v2ray/v2ray-core/testing/unit" ) @@ -13,18 +19,18 @@ func TestClientSampleConfig(t *testing.T) { // TODO: fix for Windows baseDir := "$GOPATH/src/github.com/v2ray/v2ray-core/release/config" - config, err := LoadConfig(filepath.Join(baseDir, "vpoint_socks_vmess.json")) + pointConfig, err := json.LoadConfig(filepath.Join(baseDir, "vpoint_socks_vmess.json")) assert.Error(err).IsNil() - assert.Uint16(config.Port()).Positive() - assert.Pointer(config.InboundConfig()).IsNotNil() - assert.Pointer(config.OutboundConfig()).IsNotNil() + assert.Uint16(pointConfig.Port()).Positive() + assert.Pointer(pointConfig.InboundConfig()).IsNotNil() + assert.Pointer(pointConfig.OutboundConfig()).IsNotNil() - assert.String(config.InboundConfig().Protocol()).Equals("socks") - assert.Int(len(config.InboundConfig().Content())).GreaterThan(0) + assert.String(pointConfig.InboundConfig().Protocol()).Equals("socks") + assert.Pointer(pointConfig.InboundConfig().Settings(config.TypeInbound)).IsNotNil() - assert.String(config.OutboundConfig().Protocol()).Equals("vmess") - assert.Int(len(config.OutboundConfig().Content())).GreaterThan(0) + assert.String(pointConfig.OutboundConfig().Protocol()).Equals("vmess") + assert.Pointer(pointConfig.OutboundConfig().Settings(config.TypeOutbound)).IsNotNil() } func TestServerSampleConfig(t *testing.T) { @@ -33,16 +39,16 @@ func TestServerSampleConfig(t *testing.T) { // TODO: fix for Windows baseDir := "$GOPATH/src/github.com/v2ray/v2ray-core/release/config" - config, err := LoadConfig(filepath.Join(baseDir, "vpoint_vmess_freedom.json")) + pointConfig, err := json.LoadConfig(filepath.Join(baseDir, "vpoint_vmess_freedom.json")) assert.Error(err).IsNil() - assert.Uint16(config.Port()).Positive() - assert.Pointer(config.InboundConfig()).IsNotNil() - assert.Pointer(config.OutboundConfig()).IsNotNil() + assert.Uint16(pointConfig.Port()).Positive() + assert.Pointer(pointConfig.InboundConfig()).IsNotNil() + assert.Pointer(pointConfig.OutboundConfig()).IsNotNil() - assert.String(config.InboundConfig().Protocol()).Equals("vmess") - assert.Int(len(config.InboundConfig().Content())).GreaterThan(0) + assert.String(pointConfig.InboundConfig().Protocol()).Equals("vmess") + assert.Pointer(pointConfig.InboundConfig().Settings(config.TypeInbound)).IsNotNil() - assert.String(config.OutboundConfig().Protocol()).Equals("freedom") - assert.Int(len(config.OutboundConfig().Content())).Equals(0) + assert.String(pointConfig.OutboundConfig().Protocol()).Equals("freedom") + assert.Pointer(pointConfig.OutboundConfig().Settings(config.TypeOutbound)).IsNotNil() } diff --git a/point.go b/point.go index 378fceb6..b921e75a 100644 --- a/point.go +++ b/point.go @@ -3,6 +3,7 @@ package core import ( "github.com/v2ray/v2ray-core/common/log" v2net "github.com/v2ray/v2ray-core/common/net" + "github.com/v2ray/v2ray-core/config" ) var ( @@ -26,37 +27,37 @@ func RegisterOutboundConnectionHandlerFactory(name string, factory OutboundConne type Point struct { port uint16 ichFactory InboundConnectionHandlerFactory - ichConfig []byte + ichConfig interface{} ochFactory OutboundConnectionHandlerFactory - ochConfig []byte + ochConfig interface{} } // NewPoint returns a new Point server based on given configuration. // The server is not started at this point. -func NewPoint(config PointConfig) (*Point, error) { +func NewPoint(pConfig config.PointConfig) (*Point, error) { var vpoint = new(Point) - vpoint.port = config.Port() + vpoint.port = pConfig.Port() - ichFactory, ok := inboundFactories[config.InboundConfig().Protocol()] + ichFactory, ok := inboundFactories[pConfig.InboundConfig().Protocol()] if !ok { - panic(log.Error("Unknown inbound connection handler factory %s", config.InboundConfig().Protocol())) + panic(log.Error("Unknown inbound connection handler factory %s", pConfig.InboundConfig().Protocol())) } vpoint.ichFactory = ichFactory - vpoint.ichConfig = config.InboundConfig().Content() + vpoint.ichConfig = pConfig.InboundConfig().Settings(config.TypeInbound) - ochFactory, ok := outboundFactories[config.OutboundConfig().Protocol()] + ochFactory, ok := outboundFactories[pConfig.OutboundConfig().Protocol()] if !ok { - panic(log.Error("Unknown outbound connection handler factory %s", config.OutboundConfig().Protocol)) + panic(log.Error("Unknown outbound connection handler factory %s", pConfig.OutboundConfig().Protocol)) } vpoint.ochFactory = ochFactory - vpoint.ochConfig = config.OutboundConfig().Content() + vpoint.ochConfig = pConfig.OutboundConfig().Settings(config.TypeOutbound) return vpoint, nil } type InboundConnectionHandlerFactory interface { - Create(vp *Point, config []byte) (InboundConnectionHandler, error) + Create(vp *Point, config interface{}) (InboundConnectionHandler, error) } type InboundConnectionHandler interface { @@ -64,8 +65,7 @@ type InboundConnectionHandler interface { } type OutboundConnectionHandlerFactory interface { - Initialize(config []byte) error - Create(VP *Point, firstPacket v2net.Packet) (OutboundConnectionHandler, error) + Create(VP *Point, config interface{}, firstPacket v2net.Packet) (OutboundConnectionHandler, error) } type OutboundConnectionHandler interface { @@ -79,8 +79,6 @@ func (vp *Point) Start() error { return log.Error("Invalid port %d", vp.port) } - vp.ochFactory.Initialize(vp.ochConfig) - inboundConnectionHandler, err := vp.ichFactory.Create(vp, vp.ichConfig) if err != nil { return err @@ -92,7 +90,7 @@ func (vp *Point) Start() error { func (p *Point) DispatchToOutbound(packet v2net.Packet) InboundRay { ray := NewRay() // TODO: handle error - och, _ := p.ochFactory.Create(p, packet) + och, _ := p.ochFactory.Create(p, p.ochConfig, packet) _ = och.Start(ray) return ray } diff --git a/proxy/freedom/config/json/json.go b/proxy/freedom/config/json/json.go new file mode 100644 index 00000000..40d005b2 --- /dev/null +++ b/proxy/freedom/config/json/json.go @@ -0,0 +1,15 @@ +package json + +import ( + "github.com/v2ray/v2ray-core/config" + "github.com/v2ray/v2ray-core/config/json" +) + +type FreedomConfiguration struct { +} + +func init() { + json.RegisterConfigType("freedom", config.TypeOutbound, func() interface{} { + return &FreedomConfiguration{} + }) +} diff --git a/proxy/freedom/freedom_test.go b/proxy/freedom/freedom_test.go index 28965d7f..91e356e3 100644 --- a/proxy/freedom/freedom_test.go +++ b/proxy/freedom/freedom_test.go @@ -11,6 +11,7 @@ import ( "github.com/v2ray/v2ray-core" v2net "github.com/v2ray/v2ray-core/common/net" _ "github.com/v2ray/v2ray-core/proxy/socks" + "github.com/v2ray/v2ray-core/proxy/socks/config/json" "github.com/v2ray/v2ray-core/testing/mocks" "github.com/v2ray/v2ray-core/testing/servers/tcp" "github.com/v2ray/v2ray-core/testing/servers/udp" @@ -47,11 +48,11 @@ func TestUDPSend(t *testing.T) { PortValue: pointPort, InboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "mock_ich", - ContentValue: nil, + SettingsValue: nil, }, OutboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "freedom", - ContentValue: nil, + SettingsValue: nil, }, } @@ -89,11 +90,13 @@ func TestSocksTcpConnect(t *testing.T) { PortValue: pointPort, InboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "socks", - ContentValue: []byte("{\"auth\": \"noauth\"}"), + SettingsValue: &json.SocksConfig{ + AuthMethod: "auth", + }, }, OutboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "freedom", - ContentValue: nil, + SettingsValue: nil, }, } diff --git a/proxy/freedom/freedomfactory.go b/proxy/freedom/freedomfactory.go index a6e438bd..d65784fb 100644 --- a/proxy/freedom/freedomfactory.go +++ b/proxy/freedom/freedomfactory.go @@ -8,11 +8,7 @@ import ( type FreedomFactory struct { } -func (factory FreedomFactory) Initialize(config []byte) error { - return nil -} - -func (factory FreedomFactory) Create(vp *core.Point, firstPacket v2net.Packet) (core.OutboundConnectionHandler, error) { +func (factory FreedomFactory) Create(vp *core.Point, config interface{}, firstPacket v2net.Packet) (core.OutboundConnectionHandler, error) { return NewFreedomConnection(firstPacket), nil } diff --git a/proxy/socks/config/json/config.go b/proxy/socks/config/json/config.go index bdac9230..2772fbcf 100644 --- a/proxy/socks/config/json/config.go +++ b/proxy/socks/config/json/config.go @@ -1,7 +1,8 @@ package json import ( - "encoding/json" + "github.com/v2ray/v2ray-core/config" + "github.com/v2ray/v2ray-core/config/json" ) const ( @@ -24,8 +25,8 @@ func (config SocksConfig) IsPassword() bool { return config.AuthMethod == AuthMethodUserPass } -func Load(rawConfig []byte) (SocksConfig, error) { - config := SocksConfig{} - err := json.Unmarshal(rawConfig, &config) - return config, err +func init() { + json.RegisterConfigType("socks", config.TypeInbound, func() interface{} { + return new(SocksConfig) + }) } diff --git a/proxy/socks/socks.go b/proxy/socks/socks.go index 20415b56..821f3545 100644 --- a/proxy/socks/socks.go +++ b/proxy/socks/socks.go @@ -19,15 +19,10 @@ import ( type SocksServer struct { accepting bool vPoint *core.Point - config jsonconfig.SocksConfig + config *jsonconfig.SocksConfig } -func NewSocksServer(vp *core.Point, rawConfig []byte) *SocksServer { - config, err := jsonconfig.Load(rawConfig) - if err != nil { - log.Error("Unable to load socks config: %v", err) - panic(errors.NewConfigurationError()) - } +func NewSocksServer(vp *core.Point, config *jsonconfig.SocksConfig) *SocksServer { return &SocksServer{ vPoint: vp, config: config, diff --git a/proxy/socks/socks_test.go b/proxy/socks/socks_test.go index f730d3e4..2cd45375 100644 --- a/proxy/socks/socks_test.go +++ b/proxy/socks/socks_test.go @@ -9,6 +9,7 @@ import ( "golang.org/x/net/proxy" "github.com/v2ray/v2ray-core" + "github.com/v2ray/v2ray-core/proxy/socks/config/json" "github.com/v2ray/v2ray-core/testing/mocks" "github.com/v2ray/v2ray-core/testing/unit" ) @@ -28,11 +29,13 @@ func TestSocksTcpConnect(t *testing.T) { PortValue: port, InboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "socks", - ContentValue: []byte("{\"auth\": \"noauth\"}"), + SettingsValue: &json.SocksConfig{ + AuthMethod: "noauth", + }, }, OutboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "mock_och", - ContentValue: nil, + SettingsValue: nil, }, } @@ -79,11 +82,15 @@ func TestSocksTcpConnectWithUserPass(t *testing.T) { PortValue: port, InboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "socks", - ContentValue: []byte("{\"auth\": \"password\",\"user\": \"userx\",\"pass\": \"passy\"}"), + SettingsValue: &json.SocksConfig{ + AuthMethod: "noauth", + Username: "userx", + Password: "passy", + }, }, OutboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "mock_och", - ContentValue: nil, + SettingsValue: nil, }, } @@ -130,11 +137,14 @@ func TestSocksUdpSend(t *testing.T) { PortValue: port, InboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "socks", - ContentValue: []byte("{\"auth\": \"noauth\", \"udp\": true}"), + SettingsValue: &json.SocksConfig{ + AuthMethod: "noauth", + UDPEnabled: true, + }, }, OutboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "mock_och", - ContentValue: nil, + SettingsValue: nil, }, } diff --git a/proxy/socks/socksfactory.go b/proxy/socks/socksfactory.go index e5e728d5..ec44ba76 100644 --- a/proxy/socks/socksfactory.go +++ b/proxy/socks/socksfactory.go @@ -2,13 +2,14 @@ package socks import ( "github.com/v2ray/v2ray-core" + "github.com/v2ray/v2ray-core/proxy/socks/config/json" ) type SocksServerFactory struct { } -func (factory SocksServerFactory) Create(vp *core.Point, config []byte) (core.InboundConnectionHandler, error) { - return NewSocksServer(vp, config), nil +func (factory SocksServerFactory) Create(vp *core.Point, config interface{}) (core.InboundConnectionHandler, error) { + return NewSocksServer(vp, config.(*json.SocksConfig)), nil } func init() { diff --git a/proxy/vmess/config.go b/proxy/vmess/config.go index fcc59f16..823d9012 100644 --- a/proxy/vmess/config.go +++ b/proxy/vmess/config.go @@ -1,12 +1,13 @@ package vmess import ( - "encoding/json" "net" "strings" "github.com/v2ray/v2ray-core/common/log" v2net "github.com/v2ray/v2ray-core/common/net" + "github.com/v2ray/v2ray-core/config" + "github.com/v2ray/v2ray-core/config/json" "github.com/v2ray/v2ray-core/proxy/vmess/protocol/user" ) @@ -29,12 +30,6 @@ type VMessInboundConfig struct { UDPEnabled bool `json:"udp"` } -func loadInboundConfig(rawConfig []byte) (VMessInboundConfig, error) { - config := VMessInboundConfig{} - err := json.Unmarshal(rawConfig, &config) - return config, err -} - type VNextConfig struct { Address string `json:"address"` Port uint16 `json:"port"` @@ -76,8 +71,12 @@ type VMessOutboundConfig struct { VNextList []VNextConfig `json:"vnext"` } -func loadOutboundConfig(rawConfig []byte) (VMessOutboundConfig, error) { - config := VMessOutboundConfig{} - err := json.Unmarshal(rawConfig, &config) - return config, err +func init() { + json.RegisterConfigType("vmess", config.TypeInbound, func() interface{} { + return new(VMessInboundConfig) + }) + + json.RegisterConfigType("vmess", config.TypeOutbound, func() interface{} { + return new(VMessOutboundConfig) + }) } diff --git a/proxy/vmess/vmess_test.go b/proxy/vmess/vmess_test.go index 57c72b3d..38e3be9c 100644 --- a/proxy/vmess/vmess_test.go +++ b/proxy/vmess/vmess_test.go @@ -27,11 +27,22 @@ func TestVMessInAndOut(t *testing.T) { PortValue: portA, InboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "mock_ich", - ContentValue: nil, + SettingsValue: nil, }, OutboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "vmess", - ContentValue: []byte("{\"vnext\":[{\"address\": \"127.0.0.1\", \"network\": \"tcp\", \"port\": 13829, \"users\":[{\"id\": \"ad937d9d-6e23-4a5a-ba23-bce5092a7c51\"}]}]}"), + SettingsValue: &VMessOutboundConfig{ + []VNextConfig{ + VNextConfig{ + Address: "127.0.0.1", + Port: 13829, + Network: "tcp", + Users: []VMessUser{ + VMessUser{Id: "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"}, + }, + }, + }, + }, }, } @@ -54,11 +65,15 @@ func TestVMessInAndOut(t *testing.T) { PortValue: portB, InboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "vmess", - ContentValue: []byte("{\"clients\": [{\"id\": \"ad937d9d-6e23-4a5a-ba23-bce5092a7c51\"}]}"), + SettingsValue: &VMessInboundConfig{ + AllowedClients: []VMessUser{ + VMessUser{Id: "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"}, + }, + }, }, OutboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "mock_och", - ContentValue: nil, + SettingsValue: nil, }, } @@ -91,11 +106,22 @@ func TestVMessInAndOutUDP(t *testing.T) { PortValue: portA, InboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "mock_ich", - ContentValue: nil, + SettingsValue: nil, }, OutboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "vmess", - ContentValue: []byte("{\"vnext\":[{\"address\": \"127.0.0.1\", \"network\": \"udp\", \"port\": 13841, \"users\":[{\"id\": \"ad937d9d-6e23-4a5a-ba23-bce5092a7c51\"}]}]}"), + SettingsValue: &VMessOutboundConfig{ + []VNextConfig{ + VNextConfig{ + Address: "127.0.0.1", + Port: 13841, + Network: "udp", + Users: []VMessUser{ + VMessUser{Id: "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"}, + }, + }, + }, + }, }, } @@ -118,11 +144,16 @@ func TestVMessInAndOutUDP(t *testing.T) { PortValue: portB, InboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "vmess", - ContentValue: []byte("{\"clients\": [{\"id\": \"ad937d9d-6e23-4a5a-ba23-bce5092a7c51\"}], \"udp\": true}"), + SettingsValue: &VMessInboundConfig{ + AllowedClients: []VMessUser{ + VMessUser{Id: "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"}, + }, + UDPEnabled: true, + }, }, OutboundConfigValue: &mocks.ConnectionConfig{ ProtocolValue: "mock_och", - ContentValue: nil, + SettingsValue: nil, }, } diff --git a/proxy/vmess/vmessin.go b/proxy/vmess/vmessin.go index f81ee38f..0b20918e 100644 --- a/proxy/vmess/vmessin.go +++ b/proxy/vmess/vmessin.go @@ -136,11 +136,9 @@ func handleOutput(request *protocol.VMessRequest, writer io.Writer, output <-cha type VMessInboundHandlerFactory struct { } -func (factory *VMessInboundHandlerFactory) Create(vp *core.Point, rawConfig []byte) (core.InboundConnectionHandler, error) { - config, err := loadInboundConfig(rawConfig) - if err != nil { - panic(log.Error("VMessIn: Failed to load VMess inbound config: %v", err)) - } +func (factory *VMessInboundHandlerFactory) Create(vp *core.Point, rawConfig interface{}) (core.InboundConnectionHandler, error) { + config := rawConfig.(*VMessInboundConfig) + allowedClients := user.NewTimedUserSet() for _, client := range config.AllowedClients { user, err := client.ToUser() diff --git a/proxy/vmess/vmessout.go b/proxy/vmess/vmessout.go index f39b6714..3ca39b72 100644 --- a/proxy/vmess/vmessout.go +++ b/proxy/vmess/vmessout.go @@ -193,16 +193,10 @@ func handleResponse(conn net.Conn, request *protocol.VMessRequest, output chan<- } type VMessOutboundHandlerFactory struct { - servers []VNextServer - udpServers []VNextServer } -func (factory *VMessOutboundHandlerFactory) Initialize(rawConfig []byte) error { - config, err := loadOutboundConfig(rawConfig) - if err != nil { - panic(log.Error("Failed to load VMess outbound config: %v", err)) - return err - } +func (factory *VMessOutboundHandlerFactory) Create(vp *core.Point, rawConfig interface{}, firstPacket v2net.Packet) (core.OutboundConnectionHandler, error) { + config := rawConfig.(*VMessOutboundConfig) servers := make([]VNextServer, 0, len(config.VNextList)) udpServers := make([]VNextServer, 0, len(config.VNextList)) for _, server := range config.VNextList { @@ -213,13 +207,7 @@ func (factory *VMessOutboundHandlerFactory) Initialize(rawConfig []byte) error { udpServers = append(udpServers, server.ToVNextServer("udp")) } } - factory.servers = servers - factory.udpServers = udpServers - return nil -} - -func (factory *VMessOutboundHandlerFactory) Create(vp *core.Point, firstPacket v2net.Packet) (core.OutboundConnectionHandler, error) { - return NewVMessOutboundHandler(vp, factory.servers, factory.udpServers, firstPacket), nil + return NewVMessOutboundHandler(vp, servers, udpServers, firstPacket), nil } func init() { diff --git a/release/config/in_socks.json b/release/config/in_socks.json deleted file mode 100644 index 3eeb9f84..00000000 --- a/release/config/in_socks.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "auth": "noauth", - "udp": false -} diff --git a/release/config/in_vmess.json b/release/config/in_vmess.json deleted file mode 100644 index d15d92f6..00000000 --- a/release/config/in_vmess.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "clients": [ - {"id": "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"} - ], - "udp": false -} diff --git a/release/config/out_vmess.json b/release/config/out_vmess.json deleted file mode 100644 index 3b6ec06b..00000000 --- a/release/config/out_vmess.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "vnext": [ - { - "address": "127.0.0.1", - "port": 27183, - "users": [ - {"id": "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"} - ], - "network": "tcp" - } - ] -} diff --git a/release/config/vpoint_socks_vmess.json b/release/config/vpoint_socks_vmess.json index db43a157..fce0dfc8 100644 --- a/release/config/vpoint_socks_vmess.json +++ b/release/config/vpoint_socks_vmess.json @@ -2,10 +2,24 @@ "port": 1080, "inbound": { "protocol": "socks", - "file": "in_socks.json" + "settings": { + "auth": "noauth", + "udp": false + } }, "outbound": { "protocol": "vmess", - "file": "out_vmess.json" + "settings": { + "vnext": [ + { + "address": "127.0.0.1", + "port": 27183, + "users": [ + {"id": "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"} + ], + "network": "tcp" + } + ] + } } } diff --git a/release/config/vpoint_vmess_freedom.json b/release/config/vpoint_vmess_freedom.json index af5992cb..4351b991 100644 --- a/release/config/vpoint_vmess_freedom.json +++ b/release/config/vpoint_vmess_freedom.json @@ -2,10 +2,15 @@ "port": 27183, "inbound": { "protocol": "vmess", - "file": "in_vmess.json" + "settings": { + "clients": [ + {"id": "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"} + ], + "udp": false + } }, "outbound": { "protocol": "freedom", - "file": "" + "settings": {} } } diff --git a/release/server/main.go b/release/server/main.go index af2e4420..957a94e0 100644 --- a/release/server/main.go +++ b/release/server/main.go @@ -9,7 +9,8 @@ import ( jsonconf "github.com/v2ray/v2ray-core/config/json" // The following are neccesary as they register handlers in their init functions. - _ "github.com/v2ray/v2ray-core/proxy/freedom" + _ "github.com/v2ray/v2ray-core/proxy/freedom/config/json" + _ "github.com/v2ray/v2ray-core/proxy/freedom" _ "github.com/v2ray/v2ray-core/proxy/socks" _ "github.com/v2ray/v2ray-core/proxy/vmess" ) diff --git a/spec/guide.md b/spec/guide.md index 475a8176..ed29dcfc 100644 --- a/spec/guide.md +++ b/spec/guide.md @@ -19,38 +19,27 @@ "port": 1080, // 监听端口 "inbound": { "protocol": "socks", // 传入数据所用协议 - "file": "in_socks.json" // socks 配置文件 + "settings": { + "auth": "noauth", // 认证方式,暂时只支持匿名 + "udp": false // 如果要使用 UDP 转发,请改成 true + } }, "outbound": { - "protocol": "vmess", // 中继协议 - "file": "out_vmess.json" // vmess 配置文件 - } -} -``` - -另外还需要两个文件,保存于同一文件夹下: - -```javascript -// in_socks.json -{ - "auth": "noauth" // 认证方式,暂时只支持匿名 - "udp": false // 如果要使用 UDP 转发,请改成 true -} -``` - -```javascript -// out_vmess.json -{ - "vnext": [ - { - "address": "127.0.0.1", // Point B 的 IP 地址,IPv4 或 IPv6,不支持域名 - "port": 27183, // Point B 的监听端口,请更换成其它的值 - "users": [ - {"id": "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"} // 用户 ID,必须包含在 Point B 的配置文件中。此 ID 将被用于通信的认证,请自行更换随机的 ID,可以使用 https://www.uuidgenerator.net/ 来生成新的 ID。 - ], - "network": "tcp" // 如果要使用 UDP 转发,请改成 "tcp,udp" + "protocol": "vmess", // 中继协议,暂时只有这个 + "settings": { + "vnext": [ + { + "address": "127.0.0.1", // Point B 的 IP 地址,IPv4 或 IPv6,不支持域名 + "port": 27183, // Point B 的监听端口,请更换成其它的值 + "users": [ + // 用户 ID,必须包含在 Point B 的配置文件中。此 ID 将被用于通信的认证,请自行更换随机的 ID,可以使用 https://www.uuidgenerator.net/ 来生成新的 ID。 + {"id": "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"} + ], + "network": "tcp" // 如果要使用 UDP 转发,请改成 "tcp,udp" + } + ] } - ] + } } ``` @@ -58,29 +47,24 @@ 示例配置保存于 vpoint_vmess_freedom.json 文件中,格式如下: ```javascript { - "port": 27183, // 监听端口,必须和 out_vmess.json 中指定的一致 + "port": 27183, // 监听端口,必须和 Point A 中指定的一致 "inbound": { "protocol": "vmess", // 中继协议,不用改 - "file": "in_vmess.json" // vmess 配置文件 + "settings": { + "clients": [ + // 认可的用户 ID,必须包含 Point A 中的用户 ID + {"id": "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"} + ], + "udp": false // 如果要使用 UDP 转发,请改成 true + } }, "outbound": { "protocol": "freedom", // 出口协议,不用改 - "file": "" // 暂无配置 + "settings": {} // 暂无配置 } } ``` -另外还需要 in_vmess.json: -```javascript -// in_vmess.json -{ - "clients": [ - {"id": "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"} // 认可的用户 ID,必须包含 out_vmess.json 中的用户 ID - ], - "udp": false // 如果要使用 UDP 转发,请改成 true -} -``` - ### 其它 * V2Ray 的用户验证基于时间,请确保 A 和 B 所在机器的系统时间误差在一分钟以内。 * json 配置文件实际上不支持注释(即“//”之后的部分,在使用时请务必删去)。 diff --git a/testing/mocks/config.go b/testing/mocks/config.go index be2844fb..441e0a41 100644 --- a/testing/mocks/config.go +++ b/testing/mocks/config.go @@ -1,20 +1,20 @@ package mocks import ( - "github.com/v2ray/v2ray-core" + "github.com/v2ray/v2ray-core/config" ) type ConnectionConfig struct { ProtocolValue string - ContentValue []byte + SettingsValue interface{} } func (config *ConnectionConfig) Protocol() string { return config.ProtocolValue } -func (config *ConnectionConfig) Content() []byte { - return config.ContentValue +func (config *ConnectionConfig) Settings(config.Type) interface{} { + return config.SettingsValue } type Config struct { @@ -27,10 +27,10 @@ func (config *Config) Port() uint16 { return config.PortValue } -func (config *Config) InboundConfig() core.ConnectionConfig { +func (config *Config) InboundConfig() config.ConnectionConfig { return config.InboundConfigValue } -func (config *Config) OutboundConfig() core.ConnectionConfig { +func (config *Config) OutboundConfig() config.ConnectionConfig { return config.OutboundConfigValue } diff --git a/testing/mocks/inboundhandler.go b/testing/mocks/inboundhandler.go index a3e93d8a..0fb73e48 100644 --- a/testing/mocks/inboundhandler.go +++ b/testing/mocks/inboundhandler.go @@ -32,7 +32,7 @@ func (handler *InboundConnectionHandler) Communicate(packet v2net.Packet) error return nil } -func (handler *InboundConnectionHandler) Create(point *core.Point, config []byte) (core.InboundConnectionHandler, error) { +func (handler *InboundConnectionHandler) Create(point *core.Point, config interface{}) (core.InboundConnectionHandler, error) { handler.Server = point return handler, nil } diff --git a/testing/mocks/outboundhandler.go b/testing/mocks/outboundhandler.go index faf7b04c..bed93678 100644 --- a/testing/mocks/outboundhandler.go +++ b/testing/mocks/outboundhandler.go @@ -34,11 +34,7 @@ func (handler *OutboundConnectionHandler) Start(ray core.OutboundRay) error { return nil } -func (handler *OutboundConnectionHandler) Initialize(config []byte) error { - return nil -} - -func (handler *OutboundConnectionHandler) Create(point *core.Point, packet v2net.Packet) (core.OutboundConnectionHandler, error) { +func (handler *OutboundConnectionHandler) Create(point *core.Point, config interface{}, packet v2net.Packet) (core.OutboundConnectionHandler, error) { handler.Destination = packet.Destination() if packet.Chunk() != nil { handler.Data2Send.Write(packet.Chunk()) diff --git a/testing/unit/subject.go b/testing/unit/subject.go index 9f7cb79a..1d803ed2 100644 --- a/testing/unit/subject.go +++ b/testing/unit/subject.go @@ -22,7 +22,10 @@ func NewSubject(assert *Assertion) *Subject { // decorate prefixes the string with the file and line of the call site // and inserts the final newline if needed and indentation tabs for formatting. func decorate(s string) string { - _, file, line, ok := runtime.Caller(4) // decorate + log + public function. + _, file, line, ok := runtime.Caller(3) + if strings.Contains(file, "testing") { + _, file, line, ok = runtime.Caller(4) + } if ok { // Truncate file name at last file name separator. if index := strings.LastIndex(file, "/"); index >= 0 {