Pārlūkot izejas kodu

protobuf for vmess

Darien Raymond 9 gadi atpakaļ
vecāks
revīzija
24e575f2cd

+ 7 - 7
proxy/vmess/account.pb.go

@@ -30,7 +30,7 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 
 type AccountPB struct {
 	Id      string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
-	AlterId uint32 `protobuf:"varint,2,opt,name=alterId" json:"alterId,omitempty"`
+	AlterId uint32 `protobuf:"varint,2,opt,name=alter_id,json=alterId" json:"alter_id,omitempty"`
 }
 
 func (m *AccountPB) Reset()                    { *m = AccountPB{} }
@@ -45,14 +45,14 @@ func init() {
 func init() { proto.RegisterFile("v2ray.com/core/proxy/vmess/account.proto", fileDescriptor0) }
 
 var fileDescriptor0 = []byte{
-	// 138 bytes of a gzipped FileDescriptorProto
+	// 142 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xd2, 0x28, 0x33, 0x2a, 0x4a,
 	0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x2f, 0x28, 0xca, 0xaf, 0xa8,
 	0xd4, 0x2f, 0xcb, 0x4d, 0x2d, 0x2e, 0xd6, 0x4f, 0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0xd1, 0x2b,
 	0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x4a, 0xce, 0xcf, 0xd5, 0x83, 0xa9, 0x2e, 0x4a, 0xd5, 0x03,
-	0xab, 0xd4, 0x03, 0xab, 0x54, 0x32, 0xe5, 0xe2, 0x74, 0x84, 0x28, 0x0e, 0x70, 0x12, 0xe2, 0xe3,
-	0x62, 0xca, 0x4c, 0x91, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0xca, 0x4c, 0x11, 0x92, 0xe0,
-	0x62, 0x4f, 0xcc, 0x29, 0x49, 0x2d, 0xf2, 0x4c, 0x91, 0x60, 0x52, 0x60, 0xd4, 0xe0, 0x0d, 0x82,
-	0x71, 0x9d, 0xd8, 0xa3, 0x58, 0xc1, 0xfa, 0x93, 0xd8, 0xc0, 0x56, 0x18, 0x03, 0x02, 0x00, 0x00,
-	0xff, 0xff, 0xe4, 0xea, 0x97, 0xa3, 0x8e, 0x00, 0x00, 0x00,
+	0xab, 0xd4, 0x03, 0xab, 0x54, 0x32, 0xe3, 0xe2, 0x74, 0x84, 0x28, 0x0e, 0x70, 0x12, 0xe2, 0xe3,
+	0x62, 0xca, 0x4c, 0x91, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0xca, 0x4c, 0x11, 0x92, 0xe4,
+	0xe2, 0x48, 0xcc, 0x29, 0x49, 0x2d, 0x8a, 0xcf, 0x4c, 0x91, 0x60, 0x52, 0x60, 0xd4, 0xe0, 0x0d,
+	0x62, 0x07, 0xf3, 0x3d, 0x53, 0x9c, 0xd8, 0xa3, 0x58, 0xc1, 0x06, 0x24, 0xb1, 0x81, 0xed, 0x30,
+	0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xc8, 0x3e, 0xde, 0x4b, 0x8f, 0x00, 0x00, 0x00,
 }

+ 1 - 1
proxy/vmess/account.proto

@@ -5,5 +5,5 @@ option go_package = "vmess";
 
 message AccountPB {
   string id = 1;
-  uint32 alterId = 2;
+  uint32 alter_id = 2;
 }

+ 1 - 1
proxy/vmess/inbound/command.go

@@ -8,7 +8,7 @@ import (
 
 func (this *VMessInboundHandler) generateCommand(request *protocol.RequestHeader) protocol.ResponseCommand {
 	if this.detours != nil {
-		tag := this.detours.ToTag
+		tag := this.detours.To
 		if this.inboundHandlerManager != nil {
 			handler, availableMin := this.inboundHandlerManager.GetHandler(tag)
 			inboundHandler, ok := handler.(*VMessInboundHandler)

+ 1 - 23
proxy/vmess/inbound/config.go

@@ -1,25 +1,3 @@
 package inbound
 
-import (
-	"v2ray.com/core/common/protocol"
-)
-
-type DetourConfig struct {
-	ToTag string
-}
-
-type FeaturesConfig struct {
-	Detour *DetourConfig
-}
-
-type DefaultConfig struct {
-	AlterIDs uint16
-	Level    uint32
-}
-
-type Config struct {
-	AllowedUsers []*protocol.User
-	Features     *FeaturesConfig
-	Defaults     *DefaultConfig
-	DetourConfig *DetourConfig
-}
+import ()

+ 113 - 0
proxy/vmess/inbound/config.pb.go

@@ -0,0 +1,113 @@
+// Code generated by protoc-gen-go.
+// source: v2ray.com/core/proxy/vmess/inbound/config.proto
+// DO NOT EDIT!
+
+/*
+Package inbound is a generated protocol buffer package.
+
+It is generated from these files:
+	v2ray.com/core/proxy/vmess/inbound/config.proto
+
+It has these top-level messages:
+	DetourConfig
+	DefaultConfig
+	Config
+*/
+package inbound
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import com_v2ray_core_common_protocol "v2ray.com/core/common/protocol"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type DetourConfig struct {
+	To string `protobuf:"bytes,1,opt,name=to" json:"to,omitempty"`
+}
+
+func (m *DetourConfig) Reset()                    { *m = DetourConfig{} }
+func (m *DetourConfig) String() string            { return proto.CompactTextString(m) }
+func (*DetourConfig) ProtoMessage()               {}
+func (*DetourConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+
+type DefaultConfig struct {
+	AlterId uint32 `protobuf:"varint,1,opt,name=alter_id,json=alterId" json:"alter_id,omitempty"`
+	Level   uint32 `protobuf:"varint,2,opt,name=level" json:"level,omitempty"`
+}
+
+func (m *DefaultConfig) Reset()                    { *m = DefaultConfig{} }
+func (m *DefaultConfig) String() string            { return proto.CompactTextString(m) }
+func (*DefaultConfig) ProtoMessage()               {}
+func (*DefaultConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
+
+type Config struct {
+	User    []*com_v2ray_core_common_protocol.User `protobuf:"bytes,1,rep,name=user" json:"user,omitempty"`
+	Default *DefaultConfig                         `protobuf:"bytes,2,opt,name=default" json:"default,omitempty"`
+	Detour  *DetourConfig                          `protobuf:"bytes,3,opt,name=detour" json:"detour,omitempty"`
+}
+
+func (m *Config) Reset()                    { *m = Config{} }
+func (m *Config) String() string            { return proto.CompactTextString(m) }
+func (*Config) ProtoMessage()               {}
+func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
+
+func (m *Config) GetUser() []*com_v2ray_core_common_protocol.User {
+	if m != nil {
+		return m.User
+	}
+	return nil
+}
+
+func (m *Config) GetDefault() *DefaultConfig {
+	if m != nil {
+		return m.Default
+	}
+	return nil
+}
+
+func (m *Config) GetDetour() *DetourConfig {
+	if m != nil {
+		return m.Detour
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterType((*DetourConfig)(nil), "com.v2ray.core.proxy.vmess.inbound.DetourConfig")
+	proto.RegisterType((*DefaultConfig)(nil), "com.v2ray.core.proxy.vmess.inbound.DefaultConfig")
+	proto.RegisterType((*Config)(nil), "com.v2ray.core.proxy.vmess.inbound.Config")
+}
+
+func init() { proto.RegisterFile("v2ray.com/core/proxy/vmess/inbound/config.proto", fileDescriptor0) }
+
+var fileDescriptor0 = []byte{
+	// 274 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x90, 0x31, 0x4f, 0xf3, 0x40,
+	0x0c, 0x86, 0x95, 0xf4, 0xfb, 0x12, 0xea, 0x52, 0x86, 0x88, 0x21, 0x30, 0xa0, 0x2a, 0x62, 0x28,
+	0x8b, 0x0f, 0xc2, 0xc2, 0x88, 0xa0, 0x03, 0x88, 0x2d, 0x12, 0x0b, 0x0b, 0x4a, 0x2f, 0x2e, 0x8a,
+	0x94, 0xc4, 0xd5, 0xe5, 0x12, 0xd1, 0x9f, 0xca, 0xbf, 0x41, 0x38, 0x17, 0x21, 0xba, 0xc0, 0xe8,
+	0x3b, 0x3f, 0x8f, 0x5f, 0x1b, 0x54, 0x9f, 0x9a, 0x7c, 0x87, 0x9a, 0x6b, 0xa5, 0xd9, 0x90, 0xda,
+	0x1a, 0x7e, 0xdf, 0xa9, 0xbe, 0xa6, 0xb6, 0x55, 0x65, 0xb3, 0xe6, 0xae, 0x29, 0x94, 0xe6, 0x66,
+	0x53, 0xbe, 0xe1, 0xd6, 0xb0, 0xe5, 0x28, 0xd1, 0x5c, 0xe3, 0x08, 0x19, 0x42, 0x01, 0x50, 0x00,
+	0x74, 0xc0, 0xe9, 0xc5, 0x9e, 0x54, 0x73, 0x5d, 0x73, 0xa3, 0x44, 0xa0, 0xb9, 0x52, 0x5d, 0x4b,
+	0x66, 0xd0, 0x25, 0x67, 0x70, 0xb8, 0x22, 0xcb, 0x9d, 0xb9, 0x97, 0x21, 0xd1, 0x11, 0xf8, 0x96,
+	0x63, 0x6f, 0xe1, 0x2d, 0xa7, 0x99, 0x6f, 0x39, 0xb9, 0x85, 0xf9, 0x8a, 0x36, 0x79, 0x57, 0x59,
+	0xd7, 0x70, 0x02, 0x07, 0x79, 0x65, 0xc9, 0xbc, 0x96, 0x85, 0xb4, 0xcd, 0xb3, 0x50, 0xea, 0xc7,
+	0x22, 0x3a, 0x86, 0xff, 0x15, 0xf5, 0x54, 0xc5, 0xbe, 0xbc, 0x0f, 0x45, 0xf2, 0xe1, 0x41, 0xe0,
+	0xd8, 0x1b, 0xf8, 0xf7, 0x35, 0x3a, 0xf6, 0x16, 0x93, 0xe5, 0x2c, 0x3d, 0xc7, 0xbd, 0x55, 0x86,
+	0x98, 0x38, 0xc6, 0xc4, 0xe7, 0x96, 0x4c, 0x26, 0x44, 0xf4, 0x04, 0x61, 0x31, 0xc4, 0x10, 0xf9,
+	0x2c, 0xbd, 0xc2, 0xdf, 0xef, 0x80, 0x3f, 0x92, 0x67, 0xa3, 0x21, 0x7a, 0x80, 0xa0, 0x90, 0x9d,
+	0xe3, 0x89, 0xb8, 0x2e, 0xff, 0xe6, 0xfa, 0xbe, 0x52, 0xe6, 0xf8, 0xbb, 0xe9, 0x4b, 0xe8, 0xfe,
+	0xd7, 0x81, 0xc4, 0xbe, 0xfe, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xc5, 0x81, 0xbc, 0xcb, 0xd1, 0x01,
+	0x00, 0x00,
+}

+ 21 - 0
proxy/vmess/inbound/config.proto

@@ -0,0 +1,21 @@
+syntax = "proto3";
+
+package com.v2ray.core.proxy.vmess.inbound;
+option go_package = "inbound";
+
+import "v2ray.com/core/common/protocol/user.proto";
+
+message DetourConfig {
+  string to = 1;
+}
+
+message DefaultConfig {
+  uint32 alter_id = 1;
+  uint32 level = 2;
+}
+
+message Config {
+  repeated com.v2ray.core.common.protocol.User user = 1;
+  DefaultConfig default = 2;
+  DetourConfig detour = 3;
+}

+ 16 - 25
proxy/vmess/inbound/config_json.go

@@ -23,20 +23,12 @@ func (this *DetourConfig) UnmarshalJSON(data []byte) error {
 	if err := json.Unmarshal(data, jsonConfig); err != nil {
 		return errors.New("VMess|Inbound: Failed to parse detour config: " + err.Error())
 	}
-	this.ToTag = jsonConfig.ToTag
+	this.To = jsonConfig.ToTag
 	return nil
 }
 
-func (this *FeaturesConfig) UnmarshalJSON(data []byte) error {
-	type JsonFeaturesConfig struct {
-		Detour *DetourConfig `json:"detour"`
-	}
-	jsonConfig := new(JsonFeaturesConfig)
-	if err := json.Unmarshal(data, jsonConfig); err != nil {
-		return errors.New("VMess|Inbound: Failed to parse features config: " + err.Error())
-	}
-	this.Detour = jsonConfig.Detour
-	return nil
+type FeaturesConfig struct {
+	Detour *DetourConfig `json:"detour"`
 }
 
 func (this *DefaultConfig) UnmarshalJSON(data []byte) error {
@@ -48,9 +40,9 @@ func (this *DefaultConfig) UnmarshalJSON(data []byte) error {
 	if err := json.Unmarshal(data, jsonConfig); err != nil {
 		return errors.New("VMess|Inbound: Failed to parse default config: " + err.Error())
 	}
-	this.AlterIDs = jsonConfig.AlterIDs
-	if this.AlterIDs == 0 {
-		this.AlterIDs = 32
+	this.AlterId = uint32(jsonConfig.AlterIDs)
+	if this.AlterId == 0 {
+		this.AlterId = 32
 	}
 	this.Level = uint32(jsonConfig.Level)
 	return nil
@@ -67,20 +59,19 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 	if err := json.Unmarshal(data, jsonConfig); err != nil {
 		return errors.New("VMess|Inbound: Failed to parse config: " + err.Error())
 	}
-	this.Features = jsonConfig.Features // Backward compatibility
-	this.Defaults = jsonConfig.Defaults
-	if this.Defaults == nil {
-		this.Defaults = &DefaultConfig{
-			Level:    0,
-			AlterIDs: 32,
+	this.Default = jsonConfig.Defaults
+	if this.Default == nil {
+		this.Default = &DefaultConfig{
+			Level:   0,
+			AlterId: 32,
 		}
 	}
-	this.DetourConfig = jsonConfig.DetourConfig
+	this.Detour = jsonConfig.DetourConfig
 	// Backward compatibility
-	if this.Features != nil && this.DetourConfig == nil {
-		this.DetourConfig = this.Features.Detour
+	if jsonConfig.Features != nil && jsonConfig.DetourConfig == nil {
+		this.Detour = jsonConfig.Features.Detour
 	}
-	this.AllowedUsers = make([]*protocol.User, len(jsonConfig.Users))
+	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 {
@@ -96,7 +87,7 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 			return common.ErrBadConfiguration
 		}
 		user.Account = anyAccount
-		this.AllowedUsers[idx] = user
+		this.User[idx] = user
 	}
 
 	return nil

+ 4 - 4
proxy/vmess/inbound/inbound.go

@@ -39,7 +39,7 @@ func NewUserByEmail(users []*protocol.User, config *DefaultConfig) *userByEmail
 	return &userByEmail{
 		cache:           cache,
 		defaultLevel:    config.Level,
-		defaultAlterIDs: config.AlterIDs,
+		defaultAlterIDs: uint16(config.AlterId),
 	}
 }
 
@@ -260,15 +260,15 @@ func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.
 	config := rawConfig.(*Config)
 
 	allowedClients := vmess.NewTimedUserValidator(protocol.DefaultIDHash)
-	for _, user := range config.AllowedUsers {
+	for _, user := range config.User {
 		allowedClients.Add(user)
 	}
 
 	handler := &VMessInboundHandler{
 		packetDispatcher: space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher),
 		clients:          allowedClients,
-		detours:          config.DetourConfig,
-		usersByEmail:     NewUserByEmail(config.AllowedUsers, config.Defaults),
+		detours:          config.Detour,
+		usersByEmail:     NewUserByEmail(config.User, config.Default),
 		meta:             meta,
 	}
 

+ 1 - 7
proxy/vmess/outbound/config.go

@@ -1,9 +1,3 @@
 package outbound
 
-import (
-	"v2ray.com/core/common/protocol"
-)
-
-type Config struct {
-	Receivers []*protocol.ServerSpec
-}
+import ()

+ 68 - 0
proxy/vmess/outbound/config.pb.go

@@ -0,0 +1,68 @@
+// Code generated by protoc-gen-go.
+// source: v2ray.com/core/proxy/vmess/outbound/config.proto
+// DO NOT EDIT!
+
+/*
+Package outbound is a generated protocol buffer package.
+
+It is generated from these files:
+	v2ray.com/core/proxy/vmess/outbound/config.proto
+
+It has these top-level messages:
+	Config
+*/
+package outbound
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import com_v2ray_core_common_protocol1 "v2ray.com/core/common/protocol"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type Config struct {
+	Receiver []*com_v2ray_core_common_protocol1.ServerSpecPB `protobuf:"bytes,1,rep,name=Receiver,json=receiver" json:"Receiver,omitempty"`
+}
+
+func (m *Config) Reset()                    { *m = Config{} }
+func (m *Config) String() string            { return proto.CompactTextString(m) }
+func (*Config) ProtoMessage()               {}
+func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+
+func (m *Config) GetReceiver() []*com_v2ray_core_common_protocol1.ServerSpecPB {
+	if m != nil {
+		return m.Receiver
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterType((*Config)(nil), "com.v2ray.core.proxy.vmess.outbound.Config")
+}
+
+func init() { proto.RegisterFile("v2ray.com/core/proxy/vmess/outbound/config.proto", fileDescriptor0) }
+
+var fileDescriptor0 = []byte{
+	// 179 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x5c, 0xce, 0xb1, 0x8a, 0xc2, 0x40,
+	0x10, 0xc6, 0x71, 0x8e, 0x83, 0x10, 0xf6, 0xba, 0x54, 0xc7, 0x55, 0x87, 0x36, 0x16, 0x32, 0x23,
+	0xf1, 0x0d, 0x62, 0x63, 0x29, 0x49, 0x67, 0x23, 0x66, 0x1c, 0x25, 0xe0, 0x66, 0x96, 0xd9, 0x64,
+	0x31, 0x6f, 0x2f, 0x6c, 0xdc, 0x26, 0xfd, 0xfc, 0x7f, 0xdf, 0x98, 0x5d, 0x28, 0xf5, 0x3a, 0x01,
+	0x89, 0x45, 0x12, 0x65, 0x74, 0x2a, 0xaf, 0x09, 0x83, 0x65, 0xef, 0x51, 0xc6, 0xa1, 0x95, 0xb1,
+	0xbf, 0x21, 0x49, 0x7f, 0xef, 0x1e, 0xe0, 0x54, 0x06, 0x29, 0xd6, 0x24, 0x16, 0x52, 0xa5, 0x0c,
+	0xb1, 0x80, 0x58, 0x40, 0x2a, 0xfe, 0x96, 0x2c, 0x89, 0xb5, 0xd2, 0x63, 0x14, 0x48, 0x9e, 0xe8,
+	0x59, 0x03, 0xeb, 0xc5, 0x3b, 0xa6, 0x99, 0x5d, 0xd5, 0x26, 0x3b, 0xc4, 0x99, 0xe2, 0x68, 0xf2,
+	0x9a, 0x89, 0xbb, 0xc0, 0xfa, 0xfb, 0xf5, 0xff, 0xbd, 0xf9, 0x29, 0xb7, 0xb0, 0xd8, 0x9c, 0x39,
+	0x48, 0x1c, 0x34, 0x91, 0x6b, 0x1c, 0xd3, 0xa9, 0xaa, 0x73, 0xfd, 0xd4, 0x95, 0x39, 0xe7, 0xe9,
+	0xa3, 0x36, 0x8b, 0xc7, 0xfb, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc3, 0x12, 0x96, 0x23, 0xf1,
+	0x00, 0x00, 0x00,
+}

+ 10 - 0
proxy/vmess/outbound/config.proto

@@ -0,0 +1,10 @@
+syntax = "proto3";
+
+package com.v2ray.core.proxy.vmess.outbound;
+option go_package = "outbound";
+
+import "v2ray.com/core/common/protocol/server_spec.proto";
+
+message Config {
+  repeated com.v2ray.core.common.protocol.ServerSpecPB Receiver = 1;
+}

+ 7 - 5
proxy/vmess/outbound/config_json.go

@@ -35,7 +35,7 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 		log.Error("VMessOut: 0 VMess receiver configured.")
 		return common.ErrBadConfiguration
 	}
-	serverSpecs := make([]*protocol.ServerSpec, len(rawOutbound.Receivers))
+	serverSpecs := make([]*protocol.ServerSpecPB, len(rawOutbound.Receivers))
 	for idx, rec := range rawOutbound.Receivers {
 		if len(rec.Users) == 0 {
 			log.Error("VMess: 0 user configured for VMess outbound.")
@@ -50,7 +50,10 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 				Ip: serial.Uint32ToBytes(757086633, nil),
 			}
 		}
-		spec := protocol.NewServerSpec(vmess.NewAccount, v2net.TCPDestination(rec.Address.AsAddress(), rec.Port), protocol.AlwaysValid())
+		spec := &protocol.ServerSpecPB{
+			Address: rec.Address,
+			Port:    uint32(rec.Port),
+		}
 		for _, rawUser := range rec.Users {
 			user := new(protocol.User)
 			if err := json.Unmarshal(rawUser, user); err != nil {
@@ -68,12 +71,11 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 				return common.ErrBadConfiguration
 			}
 			user.Account = anyAccount
-
-			spec.AddUser(user)
+			spec.Users = append(spec.Users, user)
 		}
 		serverSpecs[idx] = spec
 	}
-	this.Receivers = serverSpecs
+	this.Receiver = serverSpecs
 	return nil
 }
 

+ 5 - 2
proxy/vmess/outbound/config_json_test.go

@@ -6,7 +6,8 @@ import (
 	"encoding/json"
 	"testing"
 
-	//"v2ray.com/core/common/protocol"
+	"v2ray.com/core/common/protocol"
+	"v2ray.com/core/proxy/vmess"
 	. "v2ray.com/core/proxy/vmess/outbound"
 	"v2ray.com/core/testing/assert"
 )
@@ -31,5 +32,7 @@ func TestConfigTargetParsing(t *testing.T) {
 	config := new(Config)
 	err := json.Unmarshal([]byte(rawJson), &config)
 	assert.Error(err).IsNil()
-	assert.Destination(config.Receivers[0].Destination()).EqualsString("tcp:127.0.0.1:80")
+	specPB := config.Receiver[0]
+	spec := protocol.NewServerSpecFromPB(vmess.NewAccount, *specPB)
+	assert.Destination(spec.Destination()).EqualsString("tcp:127.0.0.1:80")
 }

+ 3 - 2
proxy/vmess/outbound/outbound.go

@@ -13,6 +13,7 @@ import (
 	"v2ray.com/core/common/retry"
 	"v2ray.com/core/proxy"
 	"v2ray.com/core/proxy/registry"
+	"v2ray.com/core/proxy/vmess"
 	"v2ray.com/core/proxy/vmess/encoding"
 	vmessio "v2ray.com/core/proxy/vmess/io"
 	"v2ray.com/core/transport/internet"
@@ -167,8 +168,8 @@ func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.
 	vOutConfig := rawConfig.(*Config)
 
 	serverList := protocol.NewServerList()
-	for _, rec := range vOutConfig.Receivers {
-		serverList.AddServer(rec)
+	for _, rec := range vOutConfig.Receiver {
+		serverList.AddServer(protocol.NewServerSpecFromPB(vmess.NewAccount, *rec))
 	}
 	handler := &VMessOutboundHandler{
 		serverList:   serverList,