Sfoglia il codice sorgente

Refactor socks json config

V2Ray 10 anni fa
parent
commit
654cdf18d9

+ 40 - 22
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)),
+		}
 	})
 }

+ 43 - 0
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")
+}

+ 6 - 15
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",
 				},
 			},
 		},

+ 1 - 3
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() {