mirror of
https://github.com/v2fly/v2ray-core
synced 2024-02-27 03:18:06 +00:00
json config parser
This commit is contained in:
@@ -3,10 +3,8 @@ package blackhole
|
||||
import (
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/common/alloc"
|
||||
"v2ray.com/core/common/loader"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/proxy"
|
||||
"v2ray.com/core/proxy/registry"
|
||||
"v2ray.com/core/transport/ray"
|
||||
)
|
||||
|
||||
@@ -49,7 +47,3 @@ func (this *Factory) StreamCapability() v2net.NetworkList {
|
||||
func (this *Factory) Create(space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
||||
return NewBlackHole(space, config.(*Config), meta)
|
||||
}
|
||||
|
||||
func init() {
|
||||
registry.MustRegisterOutboundHandlerCreator(loader.GetType(new(Config)), new(Factory))
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package blackhole
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"v2ray.com/core/common/loader"
|
||||
)
|
||||
|
||||
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||
type JSONConfig struct {
|
||||
Response json.RawMessage `json:"response"`
|
||||
}
|
||||
jsonConfig := new(JSONConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("Blackhole: Failed to parse config: " + err.Error())
|
||||
}
|
||||
|
||||
if jsonConfig.Response != nil {
|
||||
response, _, err := configLoader.Load(jsonConfig.Response)
|
||||
if err != nil {
|
||||
return errors.New("Blackhole: Failed to parse response config: " + err.Error())
|
||||
}
|
||||
this.Response = loader.NewTypedSettings(response.(proto.Message))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
configLoader = loader.NewJSONConfigLoader(
|
||||
loader.NamedTypeMap{
|
||||
"none": loader.GetType(new(NoneResponse)),
|
||||
"http": loader.GetType(new(HTTPResponse)),
|
||||
},
|
||||
"type",
|
||||
"")
|
||||
)
|
||||
@@ -1,31 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package blackhole_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
. "v2ray.com/core/proxy/blackhole"
|
||||
"v2ray.com/core/testing/assert"
|
||||
)
|
||||
|
||||
func TestHTTPResponseJSON(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
rawJson := `{
|
||||
"response": {
|
||||
"type": "http"
|
||||
}
|
||||
}`
|
||||
config := new(Config)
|
||||
err := json.Unmarshal([]byte(rawJson), config)
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
assert.Int(int(config.Response.Type)).Equals(int(Response_HTTP))
|
||||
response, err := config.Response.GetInternalResponse()
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
_, ok := response.(*HTTPResponse)
|
||||
assert.Bool(ok).IsTrue()
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package blackhole
|
||||
|
||||
import (
|
||||
"v2ray.com/core/common/loader"
|
||||
"v2ray.com/core/proxy/registry"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Must listed after config.pb.go
|
||||
registry.MustRegisterOutboundHandlerCreator(loader.GetType(new(Config)), new(Factory))
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package dokodemo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
v2net "v2ray.com/core/common/net"
|
||||
)
|
||||
|
||||
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||
type DokodemoConfig struct {
|
||||
Host *v2net.IPOrDomain `json:"address"`
|
||||
PortValue v2net.Port `json:"port"`
|
||||
NetworkList *v2net.NetworkList `json:"network"`
|
||||
TimeoutValue uint32 `json:"timeout"`
|
||||
Redirect bool `json:"followRedirect"`
|
||||
}
|
||||
rawConfig := new(DokodemoConfig)
|
||||
if err := json.Unmarshal(data, rawConfig); err != nil {
|
||||
return errors.New("Dokodemo: Failed to parse config: " + err.Error())
|
||||
}
|
||||
if rawConfig.Host != nil {
|
||||
this.Address = rawConfig.Host
|
||||
}
|
||||
this.Port = uint32(rawConfig.PortValue)
|
||||
this.NetworkList = rawConfig.NetworkList
|
||||
this.Timeout = rawConfig.TimeoutValue
|
||||
this.FollowRedirect = rawConfig.Redirect
|
||||
return nil
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package freedom
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||
type JsonConfig struct {
|
||||
DomainStrategy string `json:"domainStrategy"`
|
||||
Timeout uint32 `json:"timeout"`
|
||||
}
|
||||
jsonConfig := new(JsonConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("Freedom: Failed to parse config: " + err.Error())
|
||||
}
|
||||
this.DomainStrategy = Config_AS_IS
|
||||
domainStrategy := strings.ToLower(jsonConfig.DomainStrategy)
|
||||
if domainStrategy == "useip" || domainStrategy == "use_ip" {
|
||||
this.DomainStrategy = Config_USE_IP
|
||||
}
|
||||
this.Timeout = jsonConfig.Timeout
|
||||
return nil
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler
|
||||
func (this *ServerConfig) UnmarshalJSON(data []byte) error {
|
||||
type JsonConfig struct {
|
||||
Timeout uint32 `json:"timeout"`
|
||||
}
|
||||
jsonConfig := new(JsonConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("HTTP: Failed to parse config: " + err.Error())
|
||||
}
|
||||
this.Timeout = jsonConfig.Timeout
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package http_test
|
||||
@@ -45,7 +45,7 @@ func MustRegisterOutboundHandlerCreator(name string, creator OutboundHandlerFact
|
||||
func CreateInboundHandler(name string, space app.Space, config interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
||||
creator, found := inboundFactories[name]
|
||||
if !found {
|
||||
return nil, common.ErrObjectNotFound
|
||||
return nil, errors.New("Proxy|Registry: Unknown inbound name: " + name)
|
||||
}
|
||||
if meta.StreamSettings == nil {
|
||||
meta.StreamSettings = &internet.StreamConfig{
|
||||
@@ -63,7 +63,7 @@ func CreateInboundHandler(name string, space app.Space, config interface{}, meta
|
||||
func CreateOutboundHandler(name string, space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
||||
creator, found := outboundFactories[name]
|
||||
if !found {
|
||||
return nil, common.ErrObjectNotFound
|
||||
return nil, errors.New("Proxy|Registry: Unknown outbound name: " + name)
|
||||
}
|
||||
if meta.StreamSettings == nil {
|
||||
meta.StreamSettings = &internet.StreamConfig{
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package shadowsocks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/loader"
|
||||
"v2ray.com/core/common/log"
|
||||
"v2ray.com/core/common/protocol"
|
||||
)
|
||||
|
||||
func (this *ServerConfig) UnmarshalJSON(data []byte) error {
|
||||
type JsonConfig struct {
|
||||
Cipher string `json:"method"`
|
||||
Password string `json:"password"`
|
||||
UDP bool `json:"udp"`
|
||||
Level byte `json:"level"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
jsonConfig := new(JsonConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("Shadowsocks: Failed to parse config: " + err.Error())
|
||||
}
|
||||
|
||||
this.UdpEnabled = jsonConfig.UDP
|
||||
|
||||
if len(jsonConfig.Password) == 0 {
|
||||
log.Error("Shadowsocks: Password is not specified.")
|
||||
return common.ErrBadConfiguration
|
||||
}
|
||||
account := &Account{
|
||||
Password: jsonConfig.Password,
|
||||
}
|
||||
jsonConfig.Cipher = strings.ToLower(jsonConfig.Cipher)
|
||||
switch jsonConfig.Cipher {
|
||||
case "aes-256-cfb":
|
||||
account.CipherType = CipherType_AES_256_CFB
|
||||
case "aes-128-cfb":
|
||||
account.CipherType = CipherType_AES_128_CFB
|
||||
case "chacha20":
|
||||
account.CipherType = CipherType_CHACHA20
|
||||
case "chacha20-ietf":
|
||||
account.CipherType = CipherType_CHACHA20_IEFT
|
||||
default:
|
||||
log.Error("Shadowsocks: Unknown cipher method: ", jsonConfig.Cipher)
|
||||
return common.ErrBadConfiguration
|
||||
}
|
||||
|
||||
this.User = &protocol.User{
|
||||
Email: jsonConfig.Email,
|
||||
Level: uint32(jsonConfig.Level),
|
||||
Account: loader.NewTypedSettings(account),
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package shadowsocks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"v2ray.com/core/testing/assert"
|
||||
)
|
||||
|
||||
func TestConfigParsing(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
rawJson := `{
|
||||
"method": "aes-128-cfb",
|
||||
"password": "v2ray-password"
|
||||
}`
|
||||
|
||||
config := new(ServerConfig)
|
||||
err := json.Unmarshal([]byte(rawJson), config)
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
rawAccount, err = config.User.GetTypedAccount()
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
account, ok := rawAccount.(*Account)
|
||||
assert.Bool(ok).IsTrue()
|
||||
|
||||
cipher, err := account.GetCipher()
|
||||
assert.Error(err).IsNil()
|
||||
assert.Int(cipher.KeySize()).Equals(16)
|
||||
assert.Bytes(account.GetCipherKey()).Equals([]byte{160, 224, 26, 2, 22, 110, 9, 80, 65, 52, 80, 20, 38, 243, 224, 241})
|
||||
}
|
||||
@@ -1,11 +1,6 @@
|
||||
package socks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/log"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/protocol"
|
||||
|
||||
@@ -49,48 +44,3 @@ func (this *ServerConfig) GetNetAddress() v2net.Address {
|
||||
}
|
||||
return this.Address.AsAddress()
|
||||
}
|
||||
|
||||
const (
|
||||
AuthMethodNoAuth = "noauth"
|
||||
AuthMethodUserPass = "password"
|
||||
)
|
||||
|
||||
func (this *ServerConfig) UnmarshalJSON(data []byte) error {
|
||||
type SocksConfig struct {
|
||||
AuthMethod string `json:"auth"`
|
||||
Accounts []*Account `json:"accounts"`
|
||||
UDP bool `json:"udp"`
|
||||
Host *v2net.IPOrDomain `json:"ip"`
|
||||
Timeout uint32 `json:"timeout"`
|
||||
}
|
||||
|
||||
rawConfig := new(SocksConfig)
|
||||
if err := json.Unmarshal(data, rawConfig); err != nil {
|
||||
return errors.New("Socks: Failed to parse config: " + err.Error())
|
||||
}
|
||||
if rawConfig.AuthMethod == AuthMethodNoAuth {
|
||||
this.AuthType = AuthType_NO_AUTH
|
||||
} else if rawConfig.AuthMethod == AuthMethodUserPass {
|
||||
this.AuthType = AuthType_PASSWORD
|
||||
} else {
|
||||
log.Error("Socks: Unknown auth method: ", rawConfig.AuthMethod)
|
||||
return common.ErrBadConfiguration
|
||||
}
|
||||
|
||||
if len(rawConfig.Accounts) > 0 {
|
||||
this.Accounts = make(map[string]string, len(rawConfig.Accounts))
|
||||
for _, account := range rawConfig.Accounts {
|
||||
this.Accounts[account.Username] = account.Password
|
||||
}
|
||||
}
|
||||
|
||||
this.UdpEnabled = rawConfig.UDP
|
||||
if rawConfig.Host != nil {
|
||||
this.Address = rawConfig.Host
|
||||
}
|
||||
|
||||
if rawConfig.Timeout >= 0 {
|
||||
this.Timeout = rawConfig.Timeout
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package socks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"v2ray.com/core/common/loader"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/protocol"
|
||||
)
|
||||
|
||||
func (this *Account) UnmarshalJSON(data []byte) error {
|
||||
type JsonConfig struct {
|
||||
Username string `json:"user"`
|
||||
Password string `json:"pass"`
|
||||
}
|
||||
jsonConfig := new(JsonConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("Socks: Failed to parse account: " + err.Error())
|
||||
}
|
||||
this.Username = jsonConfig.Username
|
||||
this.Password = jsonConfig.Password
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *ClientConfig) UnmarshalJSON(data []byte) error {
|
||||
type ServerConfig struct {
|
||||
Address *v2net.IPOrDomain `json:"address"`
|
||||
Port v2net.Port `json:"port"`
|
||||
Users []json.RawMessage `json:"users"`
|
||||
}
|
||||
type JsonConfig struct {
|
||||
Servers []*ServerConfig `json:"servers"`
|
||||
}
|
||||
jsonConfig := new(JsonConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("Socks|Client: Failed to parse config: " + err.Error())
|
||||
}
|
||||
this.Server = make([]*protocol.ServerEndpoint, len(jsonConfig.Servers))
|
||||
for idx, serverConfig := range jsonConfig.Servers {
|
||||
server := &protocol.ServerEndpoint{
|
||||
Address: serverConfig.Address,
|
||||
Port: uint32(serverConfig.Port),
|
||||
}
|
||||
for _, rawUser := range serverConfig.Users {
|
||||
user := new(protocol.User)
|
||||
if err := json.Unmarshal(rawUser, user); err != nil {
|
||||
return errors.New("Socks|Client: Failed to parse user: " + err.Error())
|
||||
}
|
||||
account := new(Account)
|
||||
if err := json.Unmarshal(rawUser, account); err != nil {
|
||||
return errors.New("Socks|Client: Failed to parse socks account: " + err.Error())
|
||||
}
|
||||
user.Account = loader.NewTypedSettings(account)
|
||||
server.User = append(server.User, user)
|
||||
}
|
||||
this.Server[idx] = server
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package socks_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"v2ray.com/core/proxy/registry"
|
||||
. "v2ray.com/core/proxy/socks"
|
||||
"v2ray.com/core/testing/assert"
|
||||
)
|
||||
|
||||
func TestDefaultIPAddress(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
socksConfig, err := registry.CreateInboundConfig("socks", []byte(`{
|
||||
"auth": "noauth"
|
||||
}`))
|
||||
assert.Error(err).IsNil()
|
||||
assert.Address(socksConfig.(*ServerConfig).GetNetAddress()).EqualsString("127.0.0.1")
|
||||
}
|
||||
@@ -4,14 +4,13 @@ import (
|
||||
"testing"
|
||||
|
||||
"v2ray.com/core/common/alloc"
|
||||
"v2ray.com/core/common/loader"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/protocol"
|
||||
"v2ray.com/core/common/uuid"
|
||||
"v2ray.com/core/proxy/vmess"
|
||||
. "v2ray.com/core/proxy/vmess/encoding"
|
||||
"v2ray.com/core/testing/assert"
|
||||
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
)
|
||||
|
||||
func TestRequestSerialization(t *testing.T) {
|
||||
@@ -25,9 +24,7 @@ func TestRequestSerialization(t *testing.T) {
|
||||
Id: uuid.New().String(),
|
||||
AlterId: 0,
|
||||
}
|
||||
anyAccount, err := ptypes.MarshalAny(account)
|
||||
assert.Error(err).IsNil()
|
||||
user.Account = anyAccount
|
||||
user.Account = loader.NewTypedSettings(account)
|
||||
|
||||
expectedRequest := &protocol.RequestHeader{
|
||||
Version: 1,
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
package inbound
|
||||
|
||||
import ()
|
||||
|
||||
func (this *Config) GetDefaultValue() *DefaultConfig {
|
||||
if this.GetDefault() == nil {
|
||||
return &DefaultConfig{
|
||||
AlterId: 32,
|
||||
Level: 0,
|
||||
}
|
||||
}
|
||||
return this.Default
|
||||
}
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package inbound
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"v2ray.com/core/common/loader"
|
||||
"v2ray.com/core/common/protocol"
|
||||
"v2ray.com/core/proxy/vmess"
|
||||
)
|
||||
|
||||
func (this *DetourConfig) UnmarshalJSON(data []byte) error {
|
||||
type JsonDetourConfig struct {
|
||||
ToTag string `json:"to"`
|
||||
}
|
||||
jsonConfig := new(JsonDetourConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("VMess|Inbound: Failed to parse detour config: " + err.Error())
|
||||
}
|
||||
this.To = jsonConfig.ToTag
|
||||
return nil
|
||||
}
|
||||
|
||||
type FeaturesConfig struct {
|
||||
Detour *DetourConfig `json:"detour"`
|
||||
}
|
||||
|
||||
func (this *DefaultConfig) UnmarshalJSON(data []byte) error {
|
||||
type JsonDefaultConfig struct {
|
||||
AlterIDs uint16 `json:"alterId"`
|
||||
Level byte `json:"level"`
|
||||
}
|
||||
jsonConfig := new(JsonDefaultConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("VMess|Inbound: Failed to parse default config: " + err.Error())
|
||||
}
|
||||
this.AlterId = uint32(jsonConfig.AlterIDs)
|
||||
if this.AlterId == 0 {
|
||||
this.AlterId = 32
|
||||
}
|
||||
this.Level = uint32(jsonConfig.Level)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||
type JsonConfig struct {
|
||||
Users []json.RawMessage `json:"clients"`
|
||||
Features *FeaturesConfig `json:"features"`
|
||||
Defaults *DefaultConfig `json:"default"`
|
||||
DetourConfig *DetourConfig `json:"detour"`
|
||||
}
|
||||
jsonConfig := new(JsonConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("VMess|Inbound: Failed to parse config: " + err.Error())
|
||||
}
|
||||
this.Default = jsonConfig.Defaults
|
||||
if this.Default == nil {
|
||||
this.Default = &DefaultConfig{
|
||||
Level: 0,
|
||||
AlterId: 32,
|
||||
}
|
||||
}
|
||||
this.Detour = jsonConfig.DetourConfig
|
||||
// Backward compatibility
|
||||
if jsonConfig.Features != nil && jsonConfig.DetourConfig == nil {
|
||||
this.Detour = jsonConfig.Features.Detour
|
||||
}
|
||||
this.User = make([]*protocol.User, len(jsonConfig.Users))
|
||||
for idx, rawData := range jsonConfig.Users {
|
||||
user := new(protocol.User)
|
||||
if err := json.Unmarshal(rawData, user); err != nil {
|
||||
return errors.New("VMess|Inbound: Invalid user: " + err.Error())
|
||||
}
|
||||
account := new(vmess.Account)
|
||||
if err := json.Unmarshal(rawData, account); err != nil {
|
||||
return errors.New("VMess|Inbound: Invalid user: " + err.Error())
|
||||
}
|
||||
user.Account = loader.NewTypedSettings(account)
|
||||
this.User[idx] = user
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -268,7 +268,7 @@ func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.
|
||||
packetDispatcher: space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher),
|
||||
clients: allowedClients,
|
||||
detours: config.Detour,
|
||||
usersByEmail: NewUserByEmail(config.User, config.Default),
|
||||
usersByEmail: NewUserByEmail(config.User, config.GetDefaultValue()),
|
||||
meta: meta,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package outbound
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/loader"
|
||||
"v2ray.com/core/common/log"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/protocol"
|
||||
"v2ray.com/core/common/serial"
|
||||
"v2ray.com/core/proxy/vmess"
|
||||
)
|
||||
|
||||
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||
type RawConfigTarget struct {
|
||||
Address *v2net.IPOrDomain `json:"address"`
|
||||
Port v2net.Port `json:"port"`
|
||||
Users []json.RawMessage `json:"users"`
|
||||
}
|
||||
type RawOutbound struct {
|
||||
Receivers []*RawConfigTarget `json:"vnext"`
|
||||
}
|
||||
rawOutbound := &RawOutbound{}
|
||||
err := json.Unmarshal(data, rawOutbound)
|
||||
if err != nil {
|
||||
return errors.New("VMessOut: Failed to parse config: " + err.Error())
|
||||
}
|
||||
if len(rawOutbound.Receivers) == 0 {
|
||||
log.Error("VMessOut: 0 VMess receiver configured.")
|
||||
return common.ErrBadConfiguration
|
||||
}
|
||||
serverSpecs := make([]*protocol.ServerEndpoint, len(rawOutbound.Receivers))
|
||||
for idx, rec := range rawOutbound.Receivers {
|
||||
if len(rec.Users) == 0 {
|
||||
log.Error("VMess: 0 user configured for VMess outbound.")
|
||||
return common.ErrBadConfiguration
|
||||
}
|
||||
if rec.Address == nil {
|
||||
log.Error("VMess: Address is not set in VMess outbound config.")
|
||||
return common.ErrBadConfiguration
|
||||
}
|
||||
if rec.Address.AsAddress().String() == string([]byte{118, 50, 114, 97, 121, 46, 99, 111, 111, 108}) {
|
||||
rec.Address.Address = &v2net.IPOrDomain_Ip{
|
||||
Ip: serial.Uint32ToBytes(757086633, nil),
|
||||
}
|
||||
}
|
||||
spec := &protocol.ServerEndpoint{
|
||||
Address: rec.Address,
|
||||
Port: uint32(rec.Port),
|
||||
}
|
||||
for _, rawUser := range rec.Users {
|
||||
user := new(protocol.User)
|
||||
if err := json.Unmarshal(rawUser, user); err != nil {
|
||||
log.Error("VMess|Outbound: Invalid user: ", err)
|
||||
return err
|
||||
}
|
||||
account := new(vmess.Account)
|
||||
if err := json.Unmarshal(rawUser, account); err != nil {
|
||||
log.Error("VMess|Outbound: Invalid user: ", err)
|
||||
return err
|
||||
}
|
||||
user.Account = loader.NewTypedSettings(account)
|
||||
spec.User = append(spec.User, user)
|
||||
}
|
||||
serverSpecs[idx] = spec
|
||||
}
|
||||
this.Receiver = serverSpecs
|
||||
return nil
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package outbound_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"v2ray.com/core/common/protocol"
|
||||
"v2ray.com/core/proxy/vmess"
|
||||
. "v2ray.com/core/proxy/vmess/outbound"
|
||||
"v2ray.com/core/testing/assert"
|
||||
)
|
||||
|
||||
func TestConfigTargetParsing(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
rawJson := `{
|
||||
"vnext": [{
|
||||
"address": "127.0.0.1",
|
||||
"port": 80,
|
||||
"users": [
|
||||
{
|
||||
"id": "e641f5ad-9397-41e3-bf1a-e8740dfed019",
|
||||
"email": "love@v2ray.com",
|
||||
"level": 255
|
||||
}
|
||||
]
|
||||
}]
|
||||
}`
|
||||
|
||||
config := new(Config)
|
||||
err := json.Unmarshal([]byte(rawJson), &config)
|
||||
assert.Error(err).IsNil()
|
||||
specPB := config.Receiver[0]
|
||||
spec := protocol.NewServerSpecFromPB(vmess.NewAccount, *specPB)
|
||||
assert.Destination(spec.Destination()).EqualsString("tcp:127.0.0.1:80")
|
||||
}
|
||||
Reference in New Issue
Block a user