diff --git a/config.go b/config.go index e41002744..c714db3e0 100644 --- a/config.go +++ b/config.go @@ -6,12 +6,12 @@ type User struct { } type ConnectionConfig interface { - Protocol() string - Content() []byte + Protocol() string + Content() []byte } type PointConfig interface { - Port() uint16 - InboundConfig() ConnectionConfig - OutboundConfig() ConnectionConfig + Port() uint16 + InboundConfig() ConnectionConfig + OutboundConfig() ConnectionConfig } diff --git a/io/config/json/json.go b/io/config/json/json.go index 2a90d7eb5..59d8a6d8f 100644 --- a/io/config/json/json.go +++ b/io/config/json/json.go @@ -1,70 +1,70 @@ package json import ( - "encoding/json" - "io/ioutil" - "path/filepath" - - "github.com/v2ray/v2ray-core" - "github.com/v2ray/v2ray-core/log" + "encoding/json" + "io/ioutil" + "path/filepath" + + "github.com/v2ray/v2ray-core" + "github.com/v2ray/v2ray-core/log" ) type ConnectionConfig struct { ProtocolString string `json:"protocol"` - File string `json:"file"` + File string `json:"file"` } func (config *ConnectionConfig) Protocol() string { - return config.ProtocolString + return config.ProtocolString } func (config *ConnectionConfig) Content() []byte { - if len(config.File) == 0 { - return nil - } - content, err := ioutil.ReadFile(config.File) - if err != nil { - panic(log.Error("Failed to read config file (%s): %v", config.File, err)) - } - return content + if len(config.File) == 0 { + return nil + } + content, err := ioutil.ReadFile(config.File) + if err != nil { + panic(log.Error("Failed to read config file (%s): %v", config.File, err)) + } + return content } // Config is the config for Point server. type Config struct { - PortValue uint16 `json:"port"` // Port of this Point server. + PortValue uint16 `json:"port"` // Port of this Point server. InboundConfigValue *ConnectionConfig `json:"inbound"` OutboundConfigValue *ConnectionConfig `json:"outbound"` } func (config *Config) Port() uint16 { - return config.PortValue + return config.PortValue } func (config *Config) InboundConfig() core.ConnectionConfig { - return config.InboundConfigValue + return config.InboundConfigValue } func (config *Config) OutboundConfig() core.ConnectionConfig { - return config.OutboundConfigValue + return config.OutboundConfigValue } func LoadConfig(file string) (*Config, error) { - rawConfig, err := ioutil.ReadFile(file) - if err != nil { - log.Error("Failed to read point config file (%s): %v", file, err) - return nil, err - } - + rawConfig, err := ioutil.ReadFile(file) + if err != nil { + log.Error("Failed to read point config file (%s): %v", file, err) + return nil, err + } + config := &Config{} err = json.Unmarshal(rawConfig, config) - - if !filepath.IsAbs(config.InboundConfigValue.File) && len(config.InboundConfigValue.File) > 0 { - config.InboundConfigValue.File = filepath.Join(filepath.Dir(file), config.InboundConfigValue.File) - } - - if !filepath.IsAbs(config.OutboundConfigValue.File) && len(config.OutboundConfigValue.File) > 0 { - config.OutboundConfigValue.File = filepath.Join(filepath.Dir(file), config.OutboundConfigValue.File) - } - + + if !filepath.IsAbs(config.InboundConfigValue.File) && len(config.InboundConfigValue.File) > 0 { + config.InboundConfigValue.File = filepath.Join(filepath.Dir(file), config.InboundConfigValue.File) + } + + if !filepath.IsAbs(config.OutboundConfigValue.File) && len(config.OutboundConfigValue.File) > 0 { + config.OutboundConfigValue.File = filepath.Join(filepath.Dir(file), config.OutboundConfigValue.File) + } + return config, err } diff --git a/net/socks/socks_test.go b/net/socks/socks_test.go index 58b881834..e28c51cbc 100644 --- a/net/socks/socks_test.go +++ b/net/socks/socks_test.go @@ -1,39 +1,63 @@ package socks import ( - // "bytes" + "bytes" + "io/ioutil" + "net" "testing" - // "github.com/v2ray/v2ray-core" - // "github.com/v2ray/v2ray-core/testing/mocks" - // "github.com/v2ray/v2ray-core/testing/unit" + "golang.org/x/net/proxy" + + "github.com/v2ray/v2ray-core" + "github.com/v2ray/v2ray-core/testing/mocks" + "github.com/v2ray/v2ray-core/testing/unit" ) func TestSocksTcpConnect(t *testing.T) { - t.Skip("Not ready yet.") - /* - assert := unit.Assert(t) + assert := unit.Assert(t) + port := uint16(12385) - port := uint16(12384) + och := &mocks.OutboundConnectionHandler{ + Data2Send: bytes.NewBuffer(make([]byte, 0, 1024)), + Data2Return: []byte("The data to be returned to socks server."), + } - uuid := "2418d087-648d-4990-86e8-19dca1d006d3" - id, err := core.UUIDToID(uuid) - assert.Error(err).IsNil() + core.RegisterOutboundConnectionHandlerFactory("mock_och", och) - config := core.VConfig{ - port, - []core.User{core.User{id}}, - "", - []core.VNext{}} + config := mocks.Config{ + PortValue: port, + InboundConfigValue: &mocks.ConnectionConfig{ + ProtocolValue: "socks", + ContentValue: []byte("{\"auth\": \"noauth\"}"), + }, + OutboundConfigValue: &mocks.ConnectionConfig{ + ProtocolValue: "mock_och", + ContentValue: nil, + }, + } - och := new(mocks.FakeOutboundConnectionHandler) - och.Data2Send = bytes.NewBuffer(make([]byte, 1024)) - och.Data2Return = []byte("The data to be returned to socks server.") + point, err := core.NewPoint(&config) + assert.Error(err).IsNil() - vpoint, err := core.NewPoint(&config, SocksServerFactory{}, och) - assert.Error(err).IsNil() + err = point.Start() + assert.Error(err).IsNil() - err = vpoint.Start() - assert.Error(err).IsNil() - */ + socks5Client, err := proxy.SOCKS5("tcp", "127.0.0.1:12385", nil, proxy.Direct) + assert.Error(err).IsNil() + + conn, err := socks5Client.Dial("tcp", "google.com:80") + assert.Error(err).IsNil() + + data2Send := "The data to be sent to remote server." + conn.Write([]byte(data2Send)) + if tcpConn, ok := conn.(*net.TCPConn); ok { + tcpConn.CloseWrite() + } + + dataReturned, err := ioutil.ReadAll(conn) + assert.Error(err).IsNil() + conn.Close() + + assert.Bytes([]byte(data2Send)).Equals(och.Data2Send.Bytes()) + assert.Bytes(dataReturned).Equals(och.Data2Return) } diff --git a/point.go b/point.go index 5efd5357f..f6a64e500 100644 --- a/point.go +++ b/point.go @@ -42,7 +42,7 @@ func NewPoint(config PointConfig) (*Point, error) { panic(log.Error("Unknown inbound connection handler factory %s", config.InboundConfig().Protocol())) } vpoint.ichFactory = ichFactory - vpoint.ichConfig = config.InboundConfig().Content() + vpoint.ichConfig = config.InboundConfig().Content() ochFactory, ok := outboundFactories[config.OutboundConfig().Protocol()] if !ok { @@ -50,7 +50,7 @@ func NewPoint(config PointConfig) (*Point, error) { } vpoint.ochFactory = ochFactory - vpoint.ochConfig = config.OutboundConfig().Content() + vpoint.ochConfig = config.OutboundConfig().Content() return vpoint, nil } diff --git a/release/server/main.go b/release/server/main.go index e85511263..1eb410a83 100644 --- a/release/server/main.go +++ b/release/server/main.go @@ -5,7 +5,7 @@ import ( "fmt" "github.com/v2ray/v2ray-core" - jsonconf "github.com/v2ray/v2ray-core/io/config/json" + jsonconf "github.com/v2ray/v2ray-core/io/config/json" "github.com/v2ray/v2ray-core/log" // The following are neccesary as they register handlers in their init functions. @@ -43,7 +43,7 @@ func main() { if configFile == nil || len(*configFile) == 0 { panic(log.Error("Config file is not set.")) } - config, err := jsonconf.LoadConfig(*configFile) + config, err := jsonconf.LoadConfig(*configFile) if err != nil { panic(log.Error("Failed to read config file (%s): %v", *configFile, err)) } diff --git a/testing/mocks/config.go b/testing/mocks/config.go new file mode 100644 index 000000000..be2844fb0 --- /dev/null +++ b/testing/mocks/config.go @@ -0,0 +1,36 @@ +package mocks + +import ( + "github.com/v2ray/v2ray-core" +) + +type ConnectionConfig struct { + ProtocolValue string + ContentValue []byte +} + +func (config *ConnectionConfig) Protocol() string { + return config.ProtocolValue +} + +func (config *ConnectionConfig) Content() []byte { + return config.ContentValue +} + +type Config struct { + PortValue uint16 + InboundConfigValue *ConnectionConfig + OutboundConfigValue *ConnectionConfig +} + +func (config *Config) Port() uint16 { + return config.PortValue +} + +func (config *Config) InboundConfig() core.ConnectionConfig { + return config.InboundConfigValue +} + +func (config *Config) OutboundConfig() core.ConnectionConfig { + return config.OutboundConfigValue +} diff --git a/testing/mocks/fakeoutboundhandler.go b/testing/mocks/fakeoutboundhandler.go deleted file mode 100644 index be2944d41..000000000 --- a/testing/mocks/fakeoutboundhandler.go +++ /dev/null @@ -1,33 +0,0 @@ -package mocks - -import ( - "bytes" - - "github.com/v2ray/v2ray-core" - v2net "github.com/v2ray/v2ray-core/net" -) - -type FakeOutboundConnectionHandler struct { - Data2Send *bytes.Buffer - Data2Return []byte - Destination v2net.Address -} - -func (handler *FakeOutboundConnectionHandler) Start(ray core.OutboundRay) error { - input := ray.OutboundInput() - output := ray.OutboundOutput() - - output <- handler.Data2Return - for { - data, open := <-input - if !open { - break - } - handler.Data2Send.Write(data) - } - return nil -} - -func (handler *FakeOutboundConnectionHandler) Create(point *core.Point, dest v2net.Address) (core.OutboundConnectionHandler, error) { - return handler, nil -} diff --git a/testing/mocks/outboundhandler.go b/testing/mocks/outboundhandler.go new file mode 100644 index 000000000..91aa72c5c --- /dev/null +++ b/testing/mocks/outboundhandler.go @@ -0,0 +1,38 @@ +package mocks + +import ( + "bytes" + + "github.com/v2ray/v2ray-core" + v2net "github.com/v2ray/v2ray-core/net" +) + +type OutboundConnectionHandler struct { + Data2Send *bytes.Buffer + Data2Return []byte + Destination v2net.Address +} + +func (handler *OutboundConnectionHandler) Start(ray core.OutboundRay) error { + input := ray.OutboundInput() + output := ray.OutboundOutput() + + go func() { + for { + data, open := <-input + if !open { + break + } + handler.Data2Send.Write(data) + } + output <- handler.Data2Return + close(output) + }() + + return nil +} + +func (handler *OutboundConnectionHandler) Create(point *core.Point, config []byte, dest v2net.Address) (core.OutboundConnectionHandler, error) { + handler.Destination = dest + return handler, nil +}