From 654cdf18d9b0c5910846a26e3a83ddb0c01df9f2 Mon Sep 17 00:00:00 2001 From: V2Ray Date: Tue, 3 Nov 2015 22:09:07 +0100 Subject: [PATCH] Refactor socks json config --- proxy/socks/config/json/config.go | 62 +++++++++++++++++--------- proxy/socks/config/json/config_test.go | 43 ++++++++++++++++++ proxy/socks/socks_test.go | 21 +++------ proxy/socks/socksfactory.go | 4 +- 4 files changed, 90 insertions(+), 40 deletions(-) create mode 100644 proxy/socks/config/json/config_test.go diff --git a/proxy/socks/config/json/config.go b/proxy/socks/config/json/config.go index 756ff7e49..cc5e82bd2 100644 --- a/proxy/socks/config/json/config.go +++ b/proxy/socks/config/json/config.go @@ -1,9 +1,11 @@ package json import ( + "encoding/json" + "errors" "net" - "github.com/v2ray/v2ray-core/proxy/common/config/json" + jsonconfig "github.com/v2ray/v2ray-core/proxy/common/config/json" ) const ( @@ -16,28 +18,42 @@ type SocksAccount struct { Password string `json:"pass"` } -type SocksConfig struct { - AuthMethod string `json:"auth"` - Accounts []SocksAccount `json:"accounts"` - UDPEnabled bool `json:"udp"` - HostIP string `json:"ip"` +type SocksAccountMap map[string]string - accountMap map[string]string - ip net.IP +func (this *SocksAccountMap) UnmarshalJSON(data []byte) error { + var accounts []SocksAccount + err := json.Unmarshal(data, &accounts) + if err != nil { + return err + } + *this = make(map[string]string) + for _, account := range accounts { + (*this)[account.Username] = account.Password + } + return nil } -func (sc *SocksConfig) Initialize() { - sc.accountMap = make(map[string]string) - for _, account := range sc.Accounts { - sc.accountMap[account.Username] = account.Password - } +type IPAddress net.IP - if len(sc.HostIP) > 0 { - sc.ip = net.ParseIP(sc.HostIP) - if sc.ip == nil { - sc.ip = net.IPv4(127, 0, 0, 1) - } +func (this *IPAddress) UnmarshalJSON(data []byte) error { + var ipStr string + err := json.Unmarshal(data, &ipStr) + if err != nil { + return err } + ip := net.ParseIP(ipStr) + if ip == nil { + return errors.New("Unknown IP format: " + ipStr) + } + *this = IPAddress(ip) + return nil +} + +type SocksConfig struct { + AuthMethod string `json:"auth"` + Accounts SocksAccountMap `json:"accounts"` + UDPEnabled bool `json:"udp"` + HostIP IPAddress `json:"ip"` } func (sc *SocksConfig) IsNoAuth() bool { @@ -49,18 +65,20 @@ func (sc *SocksConfig) IsPassword() bool { } func (sc *SocksConfig) HasAccount(user, pass string) bool { - if actualPass, found := sc.accountMap[user]; found { + if actualPass, found := sc.Accounts[user]; found { return actualPass == pass } return false } func (sc *SocksConfig) IP() net.IP { - return sc.ip + return net.IP(sc.HostIP) } func init() { - json.RegisterInboundConnectionConfig("socks", func() interface{} { - return new(SocksConfig) + jsonconfig.RegisterInboundConnectionConfig("socks", func() interface{} { + return &SocksConfig{ + HostIP: IPAddress(net.IPv4(127, 0, 0, 1)), + } }) } diff --git a/proxy/socks/config/json/config_test.go b/proxy/socks/config/json/config_test.go new file mode 100644 index 000000000..9c0115760 --- /dev/null +++ b/proxy/socks/config/json/config_test.go @@ -0,0 +1,43 @@ +package json + +import ( + "encoding/json" + "net" + "testing" + + "github.com/v2ray/v2ray-core/proxy/common/config" + jsonconfig "github.com/v2ray/v2ray-core/proxy/common/config/json" + "github.com/v2ray/v2ray-core/testing/unit" +) + +func TestAccountMapParsing(t *testing.T) { + assert := unit.Assert(t) + + var accountMap SocksAccountMap + err := json.Unmarshal([]byte("[{\"user\": \"a\", \"pass\":\"b\"}, {\"user\": \"c\", \"pass\":\"d\"}]"), &accountMap) + assert.Error(err).IsNil() + + value, found := accountMap["a"] + assert.Bool(found).IsTrue() + assert.String(value).Equals("b") + + value, found = accountMap["c"] + assert.Bool(found).IsTrue() + assert.String(value).Equals("d") +} + +func TestDefaultIPAddress(t *testing.T) { + assert := unit.Assert(t) + + socksConfig := jsonconfig.CreateConfig("socks", config.TypeInbound).(*SocksConfig) + assert.String(socksConfig.IP().String()).Equals("127.0.0.1") +} + +func TestIPAddressParsing(t *testing.T) { + assert := unit.Assert(t) + + var ipAddress IPAddress + err := json.Unmarshal([]byte("\"1.2.3.4\""), &ipAddress) + assert.Error(err).IsNil() + assert.String(net.IP(ipAddress).String()).Equals("1.2.3.4") +} diff --git a/proxy/socks/socks_test.go b/proxy/socks/socks_test.go index 93bf11bd5..de043060b 100644 --- a/proxy/socks/socks_test.go +++ b/proxy/socks/socks_test.go @@ -92,11 +92,8 @@ func TestSocksTcpConnectWithUserPass(t *testing.T) { ProtocolValue: "socks", SettingsValue: &json.SocksConfig{ AuthMethod: "password", - Accounts: []json.SocksAccount{ - json.SocksAccount{ - Username: "userx", - Password: "passy", - }, + Accounts: json.SocksAccountMap{ + "userx": "passy", }, }, }, @@ -153,11 +150,8 @@ func TestSocksTcpConnectWithWrongUserPass(t *testing.T) { ProtocolValue: "socks", SettingsValue: &json.SocksConfig{ AuthMethod: "password", - Accounts: []json.SocksAccount{ - json.SocksAccount{ - Username: "userx", - Password: "passy", - }, + Accounts: json.SocksAccountMap{ + "userx": "passy", }, }, }, @@ -200,11 +194,8 @@ func TestSocksTcpConnectWithWrongAuthMethod(t *testing.T) { ProtocolValue: "socks", SettingsValue: &json.SocksConfig{ AuthMethod: "password", - Accounts: []json.SocksAccount{ - json.SocksAccount{ - Username: "userx", - Password: "passy", - }, + Accounts: json.SocksAccountMap{ + "userx": "passy", }, }, }, diff --git a/proxy/socks/socksfactory.go b/proxy/socks/socksfactory.go index 0682f8870..aa607f976 100644 --- a/proxy/socks/socksfactory.go +++ b/proxy/socks/socksfactory.go @@ -10,9 +10,7 @@ type SocksServerFactory struct { } func (factory SocksServerFactory) Create(dispatcher app.PacketDispatcher, rawConfig interface{}) (connhandler.InboundConnectionHandler, error) { - config := rawConfig.(*json.SocksConfig) - config.Initialize() - return NewSocksServer(dispatcher, config), nil + return NewSocksServer(dispatcher, rawConfig.(*json.SocksConfig)), nil } func init() {