Jelajahi Sumber

remove use of any

Darien Raymond 9 tahun lalu
induk
melakukan
e33b7df34c
72 mengubah file dengan 727 tambahan dan 791 penghapusan
  1. 5 3
      common/loader/json_conf.go
  2. 50 0
      common/loader/type.go
  3. 59 0
      common/loader/type.pb.go
  4. 11 0
      common/loader/type.proto
  5. 0 42
      common/log/config_json.go
  6. 0 27
      common/net/address_json.go
  7. 0 40
      common/net/address_json_test.go
  8. 2 2
      common/protocol/server_spec.go
  9. 15 15
      common/protocol/user.go
  10. 19 18
      common/protocol/user.pb.go
  11. 2 2
      common/protocol/user.proto
  12. 0 1
      config.go
  13. 65 67
      config.pb.go
  14. 4 7
      config.proto
  15. 1 1
      inbound_detour_always.go
  16. 2 2
      inbound_detour_dynamic.go
  17. 13 1
      main/main.go
  18. 3 2
      proxy/blackhole/blackhole.go
  19. 4 23
      proxy/blackhole/config.go
  20. 10 16
      proxy/blackhole/config_json.go
  21. 0 5
      proxy/dokodemo/config_json.go
  22. 2 1
      proxy/dokodemo/dokodemo.go
  23. 0 6
      proxy/freedom/config_json.go
  24. 2 1
      proxy/freedom/freedom.go
  25. 0 6
      proxy/http/config_json.go
  26. 2 1
      proxy/http/server.go
  27. 0 50
      proxy/registry/config_cache.go
  28. 0 25
      proxy/registry/config_cache_json.go
  29. 2 13
      proxy/shadowsocks/config_json.go
  30. 4 2
      proxy/shadowsocks/config_json_test.go
  31. 8 3
      proxy/shadowsocks/server.go
  32. 4 9
      proxy/socks/config.go
  33. 3 11
      proxy/socks/config_json.go
  34. 2 1
      proxy/socks/server.go
  35. 1 1
      proxy/vmess/encoding/client.go
  36. 2 1
      proxy/vmess/encoding/server.go
  37. 1 1
      proxy/vmess/inbound/command.go
  38. 2 15
      proxy/vmess/inbound/config_json.go
  39. 3 5
      proxy/vmess/inbound/inbound.go
  40. 3 4
      proxy/vmess/outbound/command.go
  41. 2 13
      proxy/vmess/outbound/config_json.go
  42. 2 1
      proxy/vmess/outbound/outbound.go
  43. 1 1
      proxy/vmess/vmess.go
  44. 76 0
      tools/conf/common.go
  45. 80 0
      tools/conf/common_test.go
  46. 43 0
      tools/conf/log.go
  47. 28 0
      tools/conf/v2ray.go
  48. 4 17
      transport/config_json.go
  49. 0 43
      transport/internet/authenticator.go
  50. 18 19
      transport/internet/authenticator.pb.go
  51. 2 2
      transport/internet/authenticator.proto
  52. 0 23
      transport/internet/authenticator_json.go
  53. 2 2
      transport/internet/authenticators/noop/noop.go
  54. 2 2
      transport/internet/authenticators/srtp/srtp.go
  55. 2 2
      transport/internet/authenticators/utp/utp.go
  56. 11 51
      transport/internet/config.go
  57. 30 73
      transport/internet/config.pb.go
  58. 4 15
      transport/internet/config.proto
  59. 5 13
      transport/internet/connection_json.go
  60. 7 4
      transport/internet/kcp/config.go
  61. 38 37
      transport/internet/kcp/config.pb.go
  62. 2 2
      transport/internet/kcp/config.proto
  63. 15 8
      transport/internet/kcp/config_json.go
  64. 10 7
      transport/internet/kcp/dialer.go
  65. 6 3
      transport/internet/kcp/listener.go
  66. 1 3
      transport/internet/tcp/config.go
  67. 9 6
      transport/internet/tcp/dialer.go
  68. 6 3
      transport/internet/tcp/hub.go
  69. 1 3
      transport/internet/ws/config.go
  70. 8 5
      transport/internet/ws/dialer.go
  71. 5 2
      transport/internet/ws/hub.go
  72. 1 1
      v2ray.go

+ 5 - 3
common/loader/json_conf.go

@@ -9,13 +9,15 @@ import (
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/log"
 )
 )
 
 
+type NamedTypeMap map[string]string
+
 type JSONConfigLoader struct {
 type JSONConfigLoader struct {
-	cache     ConfigCreatorCache
+	cache     NamedTypeMap
 	idKey     string
 	idKey     string
 	configKey string
 	configKey string
 }
 }
 
 
-func NewJSONConfigLoader(cache ConfigCreatorCache, idKey string, configKey string) *JSONConfigLoader {
+func NewJSONConfigLoader(cache NamedTypeMap, idKey string, configKey string) *JSONConfigLoader {
 	return &JSONConfigLoader{
 	return &JSONConfigLoader{
 		idKey:     idKey,
 		idKey:     idKey,
 		configKey: configKey,
 		configKey: configKey,
@@ -24,7 +26,7 @@ func NewJSONConfigLoader(cache ConfigCreatorCache, idKey string, configKey strin
 }
 }
 
 
 func (this *JSONConfigLoader) LoadWithID(raw []byte, id string) (interface{}, error) {
 func (this *JSONConfigLoader) LoadWithID(raw []byte, id string) (interface{}, error) {
-	config, err := this.cache.CreateConfig(id)
+	config, err := GetInstance(this.cache[id])
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}

+ 50 - 0
common/loader/type.go

@@ -0,0 +1,50 @@
+package loader
+
+import (
+	"errors"
+	"reflect"
+
+	"github.com/golang/protobuf/proto"
+)
+
+func NewTypedSettings(message proto.Message) *TypedSettings {
+	if message == nil {
+		return nil
+	}
+	settings, _ := proto.Marshal(message)
+	return &TypedSettings{
+		Type:     GetType(message),
+		Settings: settings,
+	}
+}
+
+func GetType(message proto.Message) string {
+	return proto.MessageName(message)
+}
+
+func GetInstance(messageType string) (interface{}, error) {
+	mType := proto.MessageType(messageType)
+	if mType == nil {
+		return nil, errors.New("Unknown type: " + messageType)
+	}
+	return reflect.New(mType).Interface(), nil
+}
+
+func (this *TypedSettings) Load(message proto.Message) error {
+	targetType := GetType(message)
+	if targetType != this.Type {
+		return errors.New("Have type " + this.Type + ", but retrieved for " + targetType)
+	}
+	return proto.Unmarshal(this.Settings, message)
+}
+
+func (this *TypedSettings) GetInstance() (interface{}, error) {
+	instance, err := GetInstance(this.Type)
+	if err != nil {
+		return nil, err
+	}
+	if err := proto.Unmarshal(this.Settings, instance.(proto.Message)); err != nil {
+		return nil, err
+	}
+	return instance, nil
+}

+ 59 - 0
common/loader/type.pb.go

@@ -0,0 +1,59 @@
+// Code generated by protoc-gen-go.
+// source: v2ray.com/core/common/loader/type.proto
+// DO NOT EDIT!
+
+/*
+Package loader is a generated protocol buffer package.
+
+It is generated from these files:
+	v2ray.com/core/common/loader/type.proto
+
+It has these top-level messages:
+	TypedSettings
+*/
+package loader
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+// 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 TypedSettings struct {
+	Type     string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"`
+	Settings []byte `protobuf:"bytes,2,opt,name=settings,proto3" json:"settings,omitempty"`
+}
+
+func (m *TypedSettings) Reset()                    { *m = TypedSettings{} }
+func (m *TypedSettings) String() string            { return proto.CompactTextString(m) }
+func (*TypedSettings) ProtoMessage()               {}
+func (*TypedSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+
+func init() {
+	proto.RegisterType((*TypedSettings)(nil), "v2ray.core.common.loader.TypedSettings")
+}
+
+func init() { proto.RegisterFile("v2ray.com/core/common/loader/type.proto", fileDescriptor0) }
+
+var fileDescriptor0 = []byte{
+	// 151 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x52, 0x2f, 0x33, 0x2a, 0x4a,
+	0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0xce, 0xcf, 0xcd, 0xcd,
+	0xcf, 0xd3, 0xcf, 0xc9, 0x4f, 0x4c, 0x49, 0x2d, 0xd2, 0x2f, 0xa9, 0x2c, 0x48, 0xd5, 0x2b, 0x28,
+	0xca, 0x2f, 0xc9, 0x17, 0x92, 0x80, 0x29, 0x2c, 0x4a, 0xd5, 0x83, 0x28, 0xd2, 0x83, 0x28, 0x52,
+	0xb2, 0xe7, 0xe2, 0x0d, 0xa9, 0x2c, 0x48, 0x4d, 0x09, 0x4e, 0x2d, 0x29, 0xc9, 0xcc, 0x4b, 0x2f,
+	0x16, 0x12, 0xe2, 0x62, 0x01, 0x69, 0x94, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x02, 0xb3, 0x85,
+	0xa4, 0xb8, 0x38, 0x8a, 0xa1, 0xf2, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0x3c, 0x41, 0x70, 0xbe, 0x93,
+	0x21, 0x97, 0x4c, 0x72, 0x7e, 0xae, 0x1e, 0x2e, 0x0b, 0x9c, 0x38, 0x41, 0xc6, 0x07, 0x80, 0x5c,
+	0x11, 0xc5, 0x06, 0x11, 0x4a, 0x62, 0x03, 0x3b, 0xca, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x24,
+	0xa2, 0x4d, 0x76, 0xbf, 0x00, 0x00, 0x00,
+}

+ 11 - 0
common/loader/type.proto

@@ -0,0 +1,11 @@
+syntax = "proto3";
+
+package v2ray.core.common.loader;
+option go_package = "loader";
+option java_package = "com.v2ray.core.common.loader";
+option java_outer_classname = "TypeProto";
+
+message TypedSettings {
+  string type = 1;
+  bytes settings = 2;
+}

+ 0 - 42
common/log/config_json.go

@@ -1,42 +0,0 @@
-package log
-
-import (
-	"encoding/json"
-	"errors"
-	"strings"
-)
-
-func (this *Config) UnmarshalJSON(data []byte) error {
-	type JsonLogConfig struct {
-		AccessLog string `json:"access"`
-		ErrorLog  string `json:"error"`
-		LogLevel  string `json:"loglevel"`
-	}
-	jsonConfig := new(JsonLogConfig)
-	if err := json.Unmarshal(data, jsonConfig); err != nil {
-		return errors.New("Log: Failed to parse log config: " + err.Error())
-	}
-	if len(jsonConfig.AccessLog) > 0 {
-		this.AccessLogPath = jsonConfig.AccessLog
-		this.AccessLogType = LogType_File
-	}
-	if len(jsonConfig.ErrorLog) > 0 {
-		this.ErrorLogPath = jsonConfig.ErrorLog
-		this.ErrorLogType = LogType_File
-	}
-
-	level := strings.ToLower(jsonConfig.LogLevel)
-	switch level {
-	case "debug":
-		this.ErrorLogLevel = LogLevel_Debug
-	case "info":
-		this.ErrorLogLevel = LogLevel_Info
-	case "error":
-		this.ErrorLogLevel = LogLevel_Error
-	case "none":
-		this.ErrorLogType = LogType_None
-	default:
-		this.ErrorLogLevel = LogLevel_Warning
-	}
-	return nil
-}

+ 0 - 27
common/net/address_json.go

@@ -1,27 +0,0 @@
-// +build json
-
-package net
-
-import (
-	"encoding/json"
-)
-
-func (this *IPOrDomain) UnmarshalJSON(data []byte) error {
-	var rawStr string
-	if err := json.Unmarshal(data, &rawStr); err != nil {
-		return err
-	}
-	addr := ParseAddress(rawStr)
-	switch addr.Family() {
-	case AddressFamilyIPv4, AddressFamilyIPv6:
-		this.Address = &IPOrDomain_Ip{
-			Ip: []byte(addr.IP()),
-		}
-	case AddressFamilyDomain:
-		this.Address = &IPOrDomain_Domain{
-			Domain: addr.Domain(),
-		}
-	}
-
-	return nil
-}

+ 0 - 40
common/net/address_json_test.go

@@ -1,40 +0,0 @@
-// +build json
-
-package net_test
-
-import (
-	"encoding/json"
-	"testing"
-
-	. "v2ray.com/core/common/net"
-	"v2ray.com/core/testing/assert"
-)
-
-func TestIPParsing(t *testing.T) {
-	assert := assert.On(t)
-
-	rawJson := "\"8.8.8.8\""
-	var address IPOrDomain
-	err := json.Unmarshal([]byte(rawJson), &address)
-	assert.Error(err).IsNil()
-	assert.Bytes(address.GetIp()).Equals([]byte{8, 8, 8, 8})
-}
-
-func TestDomainParsing(t *testing.T) {
-	assert := assert.On(t)
-
-	rawJson := "\"v2ray.com\""
-	var address IPOrDomain
-	err := json.Unmarshal([]byte(rawJson), &address)
-	assert.Error(err).IsNil()
-	assert.String(address.GetDomain()).Equals("v2ray.com")
-}
-
-func TestInvalidAddressJson(t *testing.T) {
-	assert := assert.On(t)
-
-	rawJson := "1234"
-	var address IPOrDomain
-	err := json.Unmarshal([]byte(rawJson), &address)
-	assert.Error(err).IsNotNil()
-}

+ 2 - 2
common/protocol/server_spec.go

@@ -73,12 +73,12 @@ func (this *ServerSpec) HasUser(user *User) bool {
 	this.RLock()
 	this.RLock()
 	defer this.RUnlock()
 	defer this.RUnlock()
 
 
-	accountA, err := user.GetTypedAccount(this.newAccount())
+	accountA, err := user.GetTypedAccount()
 	if err != nil {
 	if err != nil {
 		return false
 		return false
 	}
 	}
 	for _, u := range this.users {
 	for _, u := range this.users {
-		accountB, err := u.GetTypedAccount(this.newAccount())
+		accountB, err := u.GetTypedAccount()
 		if err == nil && accountA.Equals(accountB) {
 		if err == nil && accountA.Equals(accountB) {
 			return true
 			return true
 		}
 		}

+ 15 - 15
common/protocol/user.go

@@ -2,31 +2,31 @@ package protocol
 
 
 import (
 import (
 	"errors"
 	"errors"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/ptypes"
 )
 )
 
 
 var (
 var (
-	ErrUserMissing    = errors.New("User is not specified.")
-	ErrAccountMissing = errors.New("Account is not specified.")
-	ErrNonMessageType = errors.New("Not a protobuf message.")
+	ErrUserMissing        = errors.New("User is not specified.")
+	ErrAccountMissing     = errors.New("Account is not specified.")
+	ErrNonMessageType     = errors.New("Not a protobuf message.")
+	ErrUnknownAccountType = errors.New("Unknown account type.")
 )
 )
 
 
-func (this *User) GetTypedAccount(account AsAccount) (Account, error) {
-	anyAccount := this.GetAccount()
-	if anyAccount == nil {
+func (this *User) GetTypedAccount() (Account, error) {
+	if this.GetAccount() == nil {
 		return nil, ErrAccountMissing
 		return nil, ErrAccountMissing
 	}
 	}
-	protoAccount, ok := account.(proto.Message)
-	if !ok {
-		return nil, ErrNonMessageType
-	}
-	err := ptypes.UnmarshalAny(anyAccount, protoAccount)
+
+	rawAccount, err := this.Account.GetInstance()
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	return account.AsAccount()
+	if asAccount, ok := rawAccount.(AsAccount); ok {
+		return asAccount.AsAccount()
+	}
+	if account, ok := rawAccount.(Account); ok {
+		return account, nil
+	}
+	return nil, errors.New("Unknown account type: " + this.Account.Type)
 }
 }
 
 
 func (this *User) GetSettings() UserSettings {
 func (this *User) GetSettings() UserSettings {

+ 19 - 18
common/protocol/user.pb.go

@@ -7,7 +7,7 @@ package protocol
 import proto "github.com/golang/protobuf/proto"
 import proto "github.com/golang/protobuf/proto"
 import fmt "fmt"
 import fmt "fmt"
 import math "math"
 import math "math"
-import google_protobuf "github.com/golang/protobuf/ptypes/any"
+import v2ray_core_common_loader "v2ray.com/core/common/loader"
 
 
 // Reference imports to suppress errors if they are not otherwise used.
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
 var _ = proto.Marshal
@@ -15,9 +15,9 @@ var _ = fmt.Errorf
 var _ = math.Inf
 var _ = math.Inf
 
 
 type User struct {
 type User struct {
-	Level   uint32               `protobuf:"varint,1,opt,name=level" json:"level,omitempty"`
-	Email   string               `protobuf:"bytes,2,opt,name=email" json:"email,omitempty"`
-	Account *google_protobuf.Any `protobuf:"bytes,3,opt,name=account" json:"account,omitempty"`
+	Level   uint32                                  `protobuf:"varint,1,opt,name=level" json:"level,omitempty"`
+	Email   string                                  `protobuf:"bytes,2,opt,name=email" json:"email,omitempty"`
+	Account *v2ray_core_common_loader.TypedSettings `protobuf:"bytes,3,opt,name=account" json:"account,omitempty"`
 }
 }
 
 
 func (m *User) Reset()                    { *m = User{} }
 func (m *User) Reset()                    { *m = User{} }
@@ -25,7 +25,7 @@ func (m *User) String() string            { return proto.CompactTextString(m) }
 func (*User) ProtoMessage()               {}
 func (*User) ProtoMessage()               {}
 func (*User) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
 func (*User) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
 
 
-func (m *User) GetAccount() *google_protobuf.Any {
+func (m *User) GetAccount() *v2ray_core_common_loader.TypedSettings {
 	if m != nil {
 	if m != nil {
 		return m.Account
 		return m.Account
 	}
 	}
@@ -39,17 +39,18 @@ func init() {
 func init() { proto.RegisterFile("v2ray.com/core/common/protocol/user.proto", fileDescriptor1) }
 func init() { proto.RegisterFile("v2ray.com/core/common/protocol/user.proto", fileDescriptor1) }
 
 
 var fileDescriptor1 = []byte{
 var fileDescriptor1 = []byte{
-	// 192 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x8e, 0xbd, 0xea, 0xc2, 0x30,
-	0x14, 0xc5, 0xc9, 0xff, 0x43, 0x6d, 0xc4, 0xa5, 0x74, 0xa8, 0x1d, 0xa4, 0x38, 0xd5, 0xe5, 0x06,
-	0x2a, 0x3e, 0x80, 0x7d, 0x02, 0x29, 0xb8, 0xb8, 0xa5, 0xe1, 0x5a, 0x84, 0x24, 0x57, 0xd2, 0x0f,
-	0xe8, 0xdb, 0x4b, 0x1b, 0x32, 0xba, 0xe5, 0x77, 0xf2, 0xbb, 0x9c, 0xc3, 0x4f, 0x63, 0xe9, 0xe4,
-	0x04, 0x8a, 0x8c, 0x50, 0xe4, 0x50, 0x28, 0x32, 0x86, 0xac, 0x78, 0x3b, 0xea, 0x49, 0x91, 0x16,
-	0x43, 0x87, 0x0e, 0x16, 0x8a, 0xb3, 0xa0, 0x3a, 0x04, 0xaf, 0x41, 0xd0, 0xb2, 0x7d, 0x4b, 0xd4,
-	0x6a, 0xf4, 0x77, 0xcd, 0xf0, 0x14, 0xd2, 0x4e, 0xfe, 0xf7, 0xd8, 0xf0, 0xbf, 0x7b, 0x87, 0x2e,
-	0x4e, 0xf8, 0xbf, 0xc6, 0x11, 0x75, 0xca, 0x72, 0x56, 0xec, 0x6a, 0x0f, 0x73, 0x8a, 0x46, 0xbe,
-	0x74, 0xfa, 0x93, 0xb3, 0x22, 0xaa, 0x3d, 0xc4, 0xc0, 0xd7, 0x52, 0x29, 0x1a, 0x6c, 0x9f, 0xfe,
-	0xe6, 0xac, 0xd8, 0x96, 0x09, 0xf8, 0x02, 0x08, 0x05, 0x70, 0xb5, 0x53, 0x1d, 0xa4, 0xea, 0xc2,
-	0x0f, 0x8a, 0x0c, 0x7c, 0x1f, 0x58, 0x45, 0xf3, 0x86, 0xdb, 0x4c, 0x8f, 0x4d, 0x08, 0x9b, 0xd5,
-	0xf2, 0x3a, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xfc, 0x46, 0xc6, 0x05, 0x01, 0x00, 0x00,
+	// 200 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x8f, 0x3f, 0xef, 0x82, 0x30,
+	0x10, 0x86, 0xd3, 0xdf, 0x5f, 0xa9, 0x71, 0x21, 0x0e, 0x84, 0xc1, 0x10, 0x17, 0x70, 0x69, 0x13,
+	0x8c, 0x1f, 0x40, 0x3e, 0x81, 0x41, 0x5d, 0xdc, 0x6a, 0xb9, 0x18, 0x92, 0x96, 0x23, 0xa5, 0x90,
+	0xf0, 0xed, 0x0d, 0x34, 0x9d, 0xd4, 0xad, 0xcf, 0x9b, 0xa7, 0x77, 0xef, 0xd1, 0xdd, 0x90, 0x1b,
+	0x31, 0x32, 0x89, 0x9a, 0x4b, 0x34, 0xc0, 0x25, 0x6a, 0x8d, 0x0d, 0x6f, 0x0d, 0x5a, 0x94, 0xa8,
+	0x78, 0xdf, 0x81, 0x61, 0x33, 0x85, 0xb1, 0x57, 0x0d, 0x30, 0xa7, 0x31, 0xaf, 0xc5, 0xe9, 0xfb,
+	0x31, 0x0a, 0x45, 0x05, 0x86, 0xdb, 0xb1, 0x05, 0xe7, 0x6e, 0x7b, 0xfa, 0x73, 0xed, 0xc0, 0x84,
+	0x6b, 0xfa, 0xab, 0x60, 0x00, 0x15, 0x91, 0x84, 0x64, 0xab, 0xd2, 0xc1, 0x94, 0x82, 0x16, 0xb5,
+	0x8a, 0xbe, 0x12, 0x92, 0x05, 0xa5, 0x83, 0xf0, 0x48, 0xff, 0x85, 0x94, 0xd8, 0x37, 0x36, 0xfa,
+	0x4e, 0x48, 0xb6, 0xcc, 0x53, 0xf6, 0x5a, 0xc5, 0xad, 0x62, 0x97, 0xb1, 0x85, 0xea, 0x0c, 0xd6,
+	0xd6, 0xcd, 0xa3, 0x2b, 0xfd, 0xbf, 0xe2, 0x40, 0x37, 0x12, 0x35, 0xfb, 0x7c, 0x41, 0x11, 0x4c,
+	0xb5, 0x4e, 0x13, 0xdd, 0x16, 0x3e, 0xbc, 0xff, 0xcd, 0xaf, 0xfd, 0x33, 0x00, 0x00, 0xff, 0xff,
+	0x68, 0x83, 0xed, 0x6b, 0x26, 0x01, 0x00, 0x00,
 }
 }

+ 2 - 2
common/protocol/user.proto

@@ -5,10 +5,10 @@ option go_package = "protocol";
 option java_package = "com.v2ray.core.common.protocol";
 option java_package = "com.v2ray.core.common.protocol";
 option java_outer_classname = "UserProto";
 option java_outer_classname = "UserProto";
 
 
-import "google/protobuf/any.proto";
+import "v2ray.com/core/common/loader/type.proto";
 
 
 message User {
 message User {
   uint32 level = 1;
   uint32 level = 1;
   string email = 2;
   string email = 2;
-  google.protobuf.Any account = 3;
+  v2ray.core.common.loader.TypedSettings account = 3;
 }
 }

+ 0 - 1
config.go

@@ -2,7 +2,6 @@ package core
 
 
 import (
 import (
 	"v2ray.com/core/common"
 	"v2ray.com/core/common"
-	"v2ray.com/core/proxy/registry"
 )
 )
 
 
 func (this *AllocationStrategyConcurrency) GetValue() uint32 {
 func (this *AllocationStrategyConcurrency) GetValue() uint32 {

+ 65 - 67
config.pb.go

@@ -23,12 +23,12 @@ import fmt "fmt"
 import math "math"
 import math "math"
 import v2ray_core_app_router "v2ray.com/core/app/router"
 import v2ray_core_app_router "v2ray.com/core/app/router"
 import v2ray_core_app_dns "v2ray.com/core/app/dns"
 import v2ray_core_app_dns "v2ray.com/core/app/dns"
+import v2ray_core_common_loader "v2ray.com/core/common/loader"
 import v2ray_core_common_net "v2ray.com/core/common/net"
 import v2ray_core_common_net "v2ray.com/core/common/net"
 import v2ray_core_common_net2 "v2ray.com/core/common/net"
 import v2ray_core_common_net2 "v2ray.com/core/common/net"
 import v2ray_core_common_log "v2ray.com/core/common/log"
 import v2ray_core_common_log "v2ray.com/core/common/log"
 import v2ray_core_transport_internet "v2ray.com/core/transport/internet"
 import v2ray_core_transport_internet "v2ray.com/core/transport/internet"
 import v2ray_core_transport "v2ray.com/core/transport"
 import v2ray_core_transport "v2ray.com/core/transport"
-import google_protobuf "github.com/golang/protobuf/ptypes/any"
 
 
 // Reference imports to suppress errors if they are not otherwise used.
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
 var _ = proto.Marshal
@@ -136,14 +136,13 @@ func (m *AllocationStrategy) GetRefresh() *AllocationStrategyRefresh {
 
 
 // Config for an inbound connection handler.
 // Config for an inbound connection handler.
 type InboundConnectionConfig struct {
 type InboundConnectionConfig struct {
-	Protocol               string                                      `protobuf:"bytes,1,opt,name=protocol" json:"protocol,omitempty"`
+	Settings               *v2ray_core_common_loader.TypedSettings     `protobuf:"bytes,1,opt,name=settings" json:"settings,omitempty"`
 	PortRange              *v2ray_core_common_net.PortRange            `protobuf:"bytes,2,opt,name=port_range,json=portRange" json:"port_range,omitempty"`
 	PortRange              *v2ray_core_common_net.PortRange            `protobuf:"bytes,2,opt,name=port_range,json=portRange" json:"port_range,omitempty"`
 	ListenOn               *v2ray_core_common_net2.IPOrDomain          `protobuf:"bytes,3,opt,name=listen_on,json=listenOn" json:"listen_on,omitempty"`
 	ListenOn               *v2ray_core_common_net2.IPOrDomain          `protobuf:"bytes,3,opt,name=listen_on,json=listenOn" json:"listen_on,omitempty"`
 	Tag                    string                                      `protobuf:"bytes,4,opt,name=tag" json:"tag,omitempty"`
 	Tag                    string                                      `protobuf:"bytes,4,opt,name=tag" json:"tag,omitempty"`
 	AllocationStrategy     *AllocationStrategy                         `protobuf:"bytes,5,opt,name=allocation_strategy,json=allocationStrategy" json:"allocation_strategy,omitempty"`
 	AllocationStrategy     *AllocationStrategy                         `protobuf:"bytes,5,opt,name=allocation_strategy,json=allocationStrategy" json:"allocation_strategy,omitempty"`
 	StreamSettings         *v2ray_core_transport_internet.StreamConfig `protobuf:"bytes,6,opt,name=stream_settings,json=streamSettings" json:"stream_settings,omitempty"`
 	StreamSettings         *v2ray_core_transport_internet.StreamConfig `protobuf:"bytes,6,opt,name=stream_settings,json=streamSettings" json:"stream_settings,omitempty"`
-	Settings               *google_protobuf.Any                        `protobuf:"bytes,7,opt,name=settings" json:"settings,omitempty"`
-	AllowPassiveConnection bool                                        `protobuf:"varint,8,opt,name=allow_passive_connection,json=allowPassiveConnection" json:"allow_passive_connection,omitempty"`
+	AllowPassiveConnection bool                                        `protobuf:"varint,7,opt,name=allow_passive_connection,json=allowPassiveConnection" json:"allow_passive_connection,omitempty"`
 }
 }
 
 
 func (m *InboundConnectionConfig) Reset()                    { *m = InboundConnectionConfig{} }
 func (m *InboundConnectionConfig) Reset()                    { *m = InboundConnectionConfig{} }
@@ -151,6 +150,13 @@ func (m *InboundConnectionConfig) String() string            { return proto.Comp
 func (*InboundConnectionConfig) ProtoMessage()               {}
 func (*InboundConnectionConfig) ProtoMessage()               {}
 func (*InboundConnectionConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
 func (*InboundConnectionConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
 
 
+func (m *InboundConnectionConfig) GetSettings() *v2ray_core_common_loader.TypedSettings {
+	if m != nil {
+		return m.Settings
+	}
+	return nil
+}
+
 func (m *InboundConnectionConfig) GetPortRange() *v2ray_core_common_net.PortRange {
 func (m *InboundConnectionConfig) GetPortRange() *v2ray_core_common_net.PortRange {
 	if m != nil {
 	if m != nil {
 		return m.PortRange
 		return m.PortRange
@@ -179,19 +185,11 @@ func (m *InboundConnectionConfig) GetStreamSettings() *v2ray_core_transport_inte
 	return nil
 	return nil
 }
 }
 
 
-func (m *InboundConnectionConfig) GetSettings() *google_protobuf.Any {
-	if m != nil {
-		return m.Settings
-	}
-	return nil
-}
-
 type OutboundConnectionConfig struct {
 type OutboundConnectionConfig struct {
-	Protocol       string                                      `protobuf:"bytes,1,opt,name=protocol" json:"protocol,omitempty"`
+	Settings       *v2ray_core_common_loader.TypedSettings     `protobuf:"bytes,1,opt,name=settings" json:"settings,omitempty"`
 	SendThrough    *v2ray_core_common_net2.IPOrDomain          `protobuf:"bytes,2,opt,name=send_through,json=sendThrough" json:"send_through,omitempty"`
 	SendThrough    *v2ray_core_common_net2.IPOrDomain          `protobuf:"bytes,2,opt,name=send_through,json=sendThrough" json:"send_through,omitempty"`
 	StreamSettings *v2ray_core_transport_internet.StreamConfig `protobuf:"bytes,3,opt,name=stream_settings,json=streamSettings" json:"stream_settings,omitempty"`
 	StreamSettings *v2ray_core_transport_internet.StreamConfig `protobuf:"bytes,3,opt,name=stream_settings,json=streamSettings" json:"stream_settings,omitempty"`
 	Tag            string                                      `protobuf:"bytes,4,opt,name=tag" json:"tag,omitempty"`
 	Tag            string                                      `protobuf:"bytes,4,opt,name=tag" json:"tag,omitempty"`
-	Settings       *google_protobuf.Any                        `protobuf:"bytes,5,opt,name=settings" json:"settings,omitempty"`
 }
 }
 
 
 func (m *OutboundConnectionConfig) Reset()                    { *m = OutboundConnectionConfig{} }
 func (m *OutboundConnectionConfig) Reset()                    { *m = OutboundConnectionConfig{} }
@@ -199,23 +197,23 @@ func (m *OutboundConnectionConfig) String() string            { return proto.Com
 func (*OutboundConnectionConfig) ProtoMessage()               {}
 func (*OutboundConnectionConfig) ProtoMessage()               {}
 func (*OutboundConnectionConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
 func (*OutboundConnectionConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
 
 
-func (m *OutboundConnectionConfig) GetSendThrough() *v2ray_core_common_net2.IPOrDomain {
+func (m *OutboundConnectionConfig) GetSettings() *v2ray_core_common_loader.TypedSettings {
 	if m != nil {
 	if m != nil {
-		return m.SendThrough
+		return m.Settings
 	}
 	}
 	return nil
 	return nil
 }
 }
 
 
-func (m *OutboundConnectionConfig) GetStreamSettings() *v2ray_core_transport_internet.StreamConfig {
+func (m *OutboundConnectionConfig) GetSendThrough() *v2ray_core_common_net2.IPOrDomain {
 	if m != nil {
 	if m != nil {
-		return m.StreamSettings
+		return m.SendThrough
 	}
 	}
 	return nil
 	return nil
 }
 }
 
 
-func (m *OutboundConnectionConfig) GetSettings() *google_protobuf.Any {
+func (m *OutboundConnectionConfig) GetStreamSettings() *v2ray_core_transport_internet.StreamConfig {
 	if m != nil {
 	if m != nil {
-		return m.Settings
+		return m.StreamSettings
 	}
 	}
 	return nil
 	return nil
 }
 }
@@ -290,52 +288,52 @@ func init() {
 func init() { proto.RegisterFile("v2ray.com/core/config.proto", fileDescriptor0) }
 func init() { proto.RegisterFile("v2ray.com/core/config.proto", fileDescriptor0) }
 
 
 var fileDescriptor0 = []byte{
 var fileDescriptor0 = []byte{
-	// 751 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x95, 0xed, 0x6e, 0xeb, 0x34,
-	0x1c, 0xc6, 0xd7, 0x97, 0x75, 0xe9, 0xbf, 0x63, 0x54, 0x66, 0x82, 0xac, 0x30, 0x54, 0xba, 0x17,
-	0x0a, 0x4c, 0x09, 0x0c, 0x4d, 0x20, 0x24, 0x18, 0x7b, 0x01, 0x69, 0x20, 0xd1, 0x2a, 0xdd, 0x27,
-	0xbe, 0x54, 0x5e, 0xe2, 0x65, 0x91, 0x12, 0x3b, 0xb2, 0xdd, 0x8d, 0x5c, 0x02, 0x37, 0x70, 0x6e,
-	0x6e, 0x37, 0x73, 0x14, 0xdb, 0x49, 0xdf, 0x77, 0x76, 0x74, 0xbe, 0x25, 0xf1, 0xf3, 0x7b, 0x6c,
-	0x3f, 0x8f, 0xdd, 0xc2, 0xe7, 0x8f, 0xa7, 0x1c, 0x67, 0x8e, 0xcf, 0x12, 0xd7, 0x67, 0x9c, 0xb8,
-	0x3e, 0xa3, 0xf7, 0x51, 0xe8, 0xa4, 0x9c, 0x49, 0x86, 0xa0, 0x18, 0xe4, 0xa4, 0x73, 0xbc, 0x20,
-	0xc4, 0x69, 0xea, 0x72, 0x36, 0x91, 0x84, 0xcf, 0x31, 0x9d, 0x83, 0x15, 0xba, 0x80, 0x8a, 0x79,
-	0xd1, 0xe1, 0xd2, 0xac, 0x49, 0xc2, 0xa8, 0x4b, 0x89, 0x74, 0x53, 0xc6, 0xa5, 0x51, 0x7d, 0xbd,
-	0x5e, 0x85, 0x83, 0x80, 0x13, 0x21, 0x8c, 0xf0, 0x78, 0xb5, 0x30, 0x66, 0xe1, 0xfc, 0xb4, 0xce,
-	0x82, 0x4e, 0x72, 0x4c, 0x45, 0x3e, 0xa1, 0x1b, 0x51, 0x49, 0x78, 0x6e, 0x3c, 0xa7, 0x3f, 0x5a,
-	0xab, 0x9f, 0x93, 0xed, 0x85, 0x8c, 0x85, 0x31, 0x71, 0xd5, 0xdb, 0xdd, 0xe4, 0xde, 0xc5, 0x34,
-	0xd3, 0x43, 0xbd, 0x33, 0xd8, 0xbf, 0x88, 0x63, 0xe6, 0x63, 0x19, 0x31, 0x3a, 0x92, 0x1c, 0x4b,
-	0x12, 0x66, 0x57, 0x8c, 0xfa, 0x13, 0xce, 0x09, 0xf5, 0x33, 0xb4, 0x0b, 0x9b, 0x8f, 0x38, 0x9e,
-	0x10, 0xbb, 0xd2, 0xad, 0xf4, 0x3f, 0xf2, 0xf4, 0x4b, 0xef, 0x07, 0xd8, 0x5b, 0xc6, 0x3c, 0x72,
-	0xcf, 0x89, 0x78, 0x58, 0x83, 0xfc, 0x5f, 0x05, 0xb4, 0xcc, 0xa0, 0x9f, 0xa0, 0x2e, 0xb3, 0x54,
-	0x6b, 0x77, 0x4e, 0x0f, 0x9c, 0x69, 0xa3, 0xce, 0xb2, 0xda, 0xb9, 0xcd, 0x52, 0xe2, 0x29, 0x00,
-	0xfd, 0x0d, 0x2d, 0x7f, 0xba, 0x4e, 0xbb, 0xda, 0xad, 0xf4, 0x5b, 0xa7, 0xdf, 0xbc, 0xcc, 0xcf,
-	0x6c, 0xcc, 0x9b, 0xa5, 0xd1, 0x39, 0x6c, 0x71, 0xbd, 0x7a, 0xbb, 0xa6, 0x8c, 0x8e, 0x5e, 0x36,
-	0x32, 0x5b, 0xf5, 0x0a, 0xaa, 0x77, 0x02, 0xf5, 0x7c, 0x6d, 0x08, 0xa0, 0x71, 0x11, 0x3f, 0xe1,
-	0x4c, 0xb4, 0x37, 0xf2, 0x67, 0x0f, 0xd3, 0x80, 0x25, 0xed, 0x0a, 0xda, 0x06, 0xeb, 0x8f, 0xff,
-	0xf2, 0x0a, 0x71, 0xdc, 0xae, 0xf6, 0x9e, 0x6b, 0xf0, 0xd9, 0x0d, 0xbd, 0x63, 0x13, 0x1a, 0x5c,
-	0x31, 0x4a, 0x89, 0x9f, 0x7b, 0x5f, 0xa9, 0xca, 0x50, 0x07, 0x2c, 0x55, 0x8d, 0xcf, 0x62, 0x15,
-	0x4a, 0xd3, 0x2b, 0xdf, 0xd1, 0x39, 0x40, 0xde, 0xee, 0x98, 0x63, 0x1a, 0x12, 0xb3, 0xe5, 0xee,
-	0xec, 0x4a, 0xf5, 0xc1, 0x72, 0x28, 0x91, 0xce, 0x90, 0x71, 0xe9, 0xe5, 0x3a, 0xaf, 0x99, 0x16,
-	0x8f, 0xe8, 0x37, 0x68, 0xc6, 0x91, 0x90, 0x84, 0x8e, 0x19, 0x35, 0x3b, 0xfd, 0x6a, 0x0d, 0x7f,
-	0x33, 0x1c, 0xf0, 0x6b, 0x96, 0xe0, 0x88, 0x7a, 0x96, 0x66, 0x06, 0x14, 0xb5, 0xa1, 0x26, 0x71,
-	0x68, 0xd7, 0xd5, 0xba, 0xf2, 0x47, 0x34, 0x80, 0x4f, 0x70, 0x19, 0xcf, 0x58, 0x98, 0x7c, 0xec,
-	0x4d, 0xe5, 0xfd, 0xe5, 0x3b, 0x52, 0x44, 0x78, 0xf9, 0x40, 0xdc, 0xc2, 0xc7, 0x42, 0x72, 0x82,
-	0x93, 0xb1, 0x20, 0x52, 0x46, 0x34, 0x14, 0x76, 0x43, 0x99, 0x7d, 0x37, 0x6b, 0x56, 0x9e, 0x74,
-	0xa7, 0xb8, 0x19, 0xce, 0x48, 0x51, 0x3a, 0x45, 0x6f, 0x47, 0x7b, 0x8c, 0x8c, 0x05, 0xfa, 0x1e,
-	0xac, 0xd2, 0x6e, 0x4b, 0xd9, 0xed, 0x3a, 0xfa, 0x56, 0x38, 0xc5, 0xad, 0x70, 0x2e, 0x68, 0xe6,
-	0x95, 0x2a, 0xf4, 0x33, 0xd8, 0xf9, 0xea, 0x9e, 0xc6, 0x29, 0x16, 0x22, 0x7a, 0x24, 0x63, 0xbf,
-	0x6c, 0xca, 0xb6, 0xba, 0x95, 0xbe, 0xe5, 0x7d, 0xaa, 0xc6, 0x87, 0x7a, 0x78, 0xda, 0x63, 0xef,
-	0x4d, 0x15, 0xec, 0xc1, 0x44, 0xbe, 0x7f, 0xbd, 0xd7, 0xb0, 0x2d, 0x08, 0x0d, 0xc6, 0xf2, 0x81,
-	0xb3, 0x49, 0xf8, 0x60, 0x0a, 0x7e, 0x45, 0x41, 0xad, 0x1c, 0xbb, 0xd5, 0xd4, 0xaa, 0x00, 0x6b,
-	0x1f, 0x1e, 0xe0, 0x72, 0xf3, 0xb3, 0x91, 0x6e, 0xbe, 0x26, 0xd2, 0xde, 0x73, 0x15, 0x1a, 0x26,
-	0x86, 0x5f, 0x61, 0x2b, 0xd2, 0x17, 0xc0, 0xae, 0x74, 0x6b, 0xfd, 0xd6, 0xfc, 0xcd, 0x5f, 0x73,
-	0x37, 0xbc, 0x82, 0x41, 0xbf, 0x83, 0xc5, 0x4c, 0xc2, 0x76, 0x55, 0xf1, 0x87, 0xb3, 0xfc, 0xba,
-	0xf4, 0xbd, 0x92, 0x42, 0x2e, 0xd4, 0x62, 0x16, 0x9a, 0x64, 0xf6, 0x57, 0x44, 0x1c, 0xb3, 0xd0,
-	0x31, 0x54, 0xae, 0x44, 0x67, 0xd0, 0xd0, 0x7f, 0x27, 0x2a, 0x83, 0x05, 0x06, 0xa7, 0xa9, 0xa3,
-	0x47, 0x0b, 0xc6, 0x88, 0xd1, 0x09, 0xd4, 0x02, 0x5a, 0x04, 0xd4, 0x59, 0x64, 0x02, 0x2a, 0xca,
-	0x49, 0x02, 0x2a, 0xd0, 0x2f, 0xd0, 0x2c, 0x8b, 0x31, 0xc7, 0xfe, 0x8b, 0xd5, 0xad, 0x19, 0x6a,
-	0x2a, 0xff, 0xf6, 0x18, 0xb6, 0xf5, 0xc7, 0x3f, 0x19, 0x4f, 0xb0, 0xcc, 0x7f, 0x72, 0x86, 0xa6,
-	0x87, 0xf6, 0x06, 0xb2, 0xa0, 0xfe, 0xd7, 0x68, 0xf0, 0x4f, 0xbb, 0x72, 0x79, 0x00, 0x3b, 0x3e,
-	0x4b, 0x66, 0x5c, 0x2f, 0x5b, 0x9a, 0x53, 0xea, 0x7f, 0xeb, 0xf9, 0xa7, 0xbb, 0x86, 0xaa, 0xf0,
-	0xc7, 0xb7, 0x01, 0x00, 0x00, 0xff, 0xff, 0xba, 0x3e, 0xa7, 0x09, 0x7f, 0x07, 0x00, 0x00,
+	// 737 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x95, 0xdf, 0x6e, 0xdb, 0x36,
+	0x14, 0xc6, 0x23, 0xdb, 0x71, 0xec, 0xe3, 0x2c, 0x33, 0xb8, 0x61, 0xd3, 0xb2, 0x65, 0xf0, 0x9c,
+	0x7f, 0x5e, 0x1b, 0x48, 0xa8, 0x8b, 0xa0, 0x45, 0x81, 0x36, 0x4d, 0x9c, 0x16, 0x48, 0x0b, 0xd4,
+	0x06, 0x9d, 0xab, 0xde, 0x18, 0x8c, 0xc4, 0x28, 0x02, 0x24, 0x52, 0x20, 0xe9, 0xa4, 0x7e, 0x84,
+	0x5e, 0xf4, 0xe5, 0x7a, 0xdb, 0x97, 0x29, 0x28, 0xd1, 0xf2, 0xff, 0xb4, 0x40, 0xd1, 0x3b, 0x4a,
+	0xfc, 0x7e, 0x87, 0xe4, 0xf7, 0x1d, 0x4a, 0xf0, 0xf7, 0x6d, 0x5b, 0x90, 0x91, 0xe3, 0xf1, 0xd8,
+	0xf5, 0xb8, 0xa0, 0xae, 0xc7, 0xd9, 0x75, 0x18, 0x38, 0x89, 0xe0, 0x8a, 0x23, 0x18, 0x4f, 0x0a,
+	0xba, 0x7d, 0x30, 0x27, 0x24, 0x49, 0xe2, 0x0a, 0x3e, 0x54, 0x54, 0xcc, 0x30, 0xdb, 0xbb, 0x4b,
+	0x74, 0x3e, 0x93, 0xb3, 0xa2, 0xc3, 0x85, 0x55, 0xe3, 0x98, 0x33, 0x37, 0xe2, 0xc4, 0xa7, 0xc2,
+	0x55, 0xa3, 0x84, 0x1a, 0xe1, 0xde, 0x72, 0x21, 0xa3, 0xca, 0x4d, 0xb8, 0x50, 0xf7, 0x97, 0xd3,
+	0x2a, 0xe2, 0xfb, 0x82, 0x4a, 0x69, 0x84, 0x07, 0xab, 0xd6, 0x0d, 0x66, 0xf7, 0xe7, 0xcc, 0xe9,
+	0x94, 0x20, 0x4c, 0xea, 0x05, 0xdd, 0x90, 0x29, 0x2a, 0x74, 0xe1, 0x19, 0xfd, 0xfe, 0x4a, 0xfd,
+	0xb4, 0xac, 0x79, 0x0c, 0x3b, 0xa7, 0x51, 0xc4, 0x3d, 0xa2, 0x42, 0xce, 0xfa, 0x4a, 0x10, 0x45,
+	0x83, 0x51, 0x87, 0x33, 0x6f, 0x28, 0x04, 0x65, 0xde, 0x08, 0xfd, 0x0e, 0xeb, 0xb7, 0x24, 0x1a,
+	0x52, 0xdb, 0x6a, 0x58, 0xad, 0x5f, 0x70, 0xf6, 0xd0, 0x7c, 0x04, 0x7f, 0x2d, 0x62, 0x98, 0x5e,
+	0x0b, 0x2a, 0x6f, 0x56, 0x20, 0x1f, 0x0b, 0x80, 0x16, 0x19, 0xf4, 0x04, 0x4a, 0xda, 0xdc, 0x54,
+	0xbb, 0xd5, 0xde, 0x75, 0x26, 0xf9, 0x3a, 0x8b, 0x6a, 0xe7, 0x72, 0x94, 0x50, 0x9c, 0x02, 0xe8,
+	0x2d, 0xd4, 0xbc, 0xc9, 0x3e, 0xed, 0x42, 0xc3, 0x6a, 0xd5, 0xda, 0xff, 0xdf, 0xcf, 0x4f, 0x1d,
+	0x0c, 0x4f, 0xd3, 0xe8, 0x04, 0x36, 0x44, 0xb6, 0x7b, 0xbb, 0x98, 0x16, 0xda, 0xbf, 0xbf, 0x90,
+	0x39, 0x2a, 0x1e, 0x53, 0xcd, 0x23, 0x28, 0xe9, 0xbd, 0x21, 0x80, 0xf2, 0x69, 0x74, 0x47, 0x46,
+	0xb2, 0xbe, 0xa6, 0xc7, 0x98, 0x30, 0x9f, 0xc7, 0x75, 0x0b, 0x6d, 0x42, 0xe5, 0xd5, 0x07, 0x9d,
+	0x13, 0x89, 0xea, 0x85, 0xe6, 0xe7, 0x22, 0xfc, 0x79, 0xc1, 0xae, 0xf8, 0x90, 0xf9, 0x1d, 0xce,
+	0x18, 0xf5, 0x74, 0xed, 0x4e, 0x9a, 0x0b, 0xea, 0x40, 0x45, 0x52, 0xa5, 0x42, 0x16, 0xc8, 0xd4,
+	0x94, 0x5a, 0xfb, 0x70, 0x7a, 0x2f, 0x59, 0x7f, 0x38, 0x59, 0x5f, 0xa6, 0x7e, 0xf8, 0x7d, 0x23,
+	0xc7, 0x39, 0x88, 0x4e, 0x00, 0x74, 0xd6, 0x03, 0x41, 0x58, 0x40, 0x8d, 0x37, 0x8d, 0x25, 0x65,
+	0x18, 0x55, 0x4e, 0x8f, 0x0b, 0x85, 0xb5, 0x0e, 0x57, 0x93, 0xf1, 0x10, 0xbd, 0x80, 0x6a, 0x14,
+	0x4a, 0x45, 0xd9, 0x80, 0x33, 0x63, 0xc9, 0x7f, 0x2b, 0xf8, 0x8b, 0x5e, 0x57, 0x9c, 0xf3, 0x98,
+	0x84, 0x0c, 0x57, 0x32, 0xa6, 0xcb, 0x50, 0x1d, 0x8a, 0x8a, 0x04, 0x76, 0xa9, 0x61, 0xb5, 0xaa,
+	0x58, 0x0f, 0x51, 0x17, 0x7e, 0x23, 0xb9, 0x8f, 0x03, 0x69, 0x8c, 0xb4, 0xd7, 0xd3, 0xda, 0xff,
+	0x7e, 0xc3, 0x6e, 0x44, 0x16, 0x3b, 0xe7, 0x12, 0x7e, 0x95, 0x4a, 0x50, 0x12, 0x0f, 0x72, 0xbf,
+	0xca, 0x69, 0xb1, 0x87, 0xd3, 0xc5, 0xf2, 0xbe, 0x77, 0xc6, 0xf7, 0xc4, 0xe9, 0xa7, 0x54, 0x66,
+	0x37, 0xde, 0xca, 0x6a, 0x8c, 0x3d, 0x44, 0x4f, 0xc1, 0xd6, 0x6b, 0xdd, 0x0d, 0x12, 0x22, 0x65,
+	0x78, 0x4b, 0x07, 0x5e, 0x1e, 0x90, 0xbd, 0xd1, 0xb0, 0x5a, 0x15, 0xfc, 0x47, 0x3a, 0xdf, 0xcb,
+	0xa6, 0x27, 0xf1, 0x35, 0x3f, 0x15, 0xc0, 0xee, 0x0e, 0xd5, 0x4f, 0x4c, 0xf5, 0x1c, 0x36, 0x25,
+	0x65, 0xfe, 0x40, 0xdd, 0x08, 0x3e, 0x0c, 0x6e, 0x4c, 0xae, 0xdf, 0x91, 0x4b, 0x4d, 0x63, 0x97,
+	0x19, 0xb5, 0xcc, 0xb7, 0xe2, 0x8f, 0xfb, 0xb6, 0x10, 0x78, 0xf3, 0x4b, 0x01, 0xca, 0xe6, 0xf4,
+	0xcf, 0x61, 0x23, 0xcc, 0xda, 0xdd, 0xb6, 0x1a, 0xc5, 0x56, 0x6d, 0xf6, 0x9e, 0xaf, 0xb8, 0x09,
+	0x78, 0xcc, 0xa0, 0x97, 0x50, 0xe1, 0xc6, 0x58, 0xbb, 0x90, 0xf2, 0x7b, 0xd3, 0xfc, 0x2a, 0xd3,
+	0x71, 0x4e, 0x21, 0x17, 0x8a, 0x11, 0x0f, 0xcc, 0x39, 0x77, 0x96, 0x3a, 0x1f, 0x38, 0x86, 0xd2,
+	0x4a, 0x74, 0x0c, 0xe5, 0xec, 0x57, 0x92, 0x9e, 0x68, 0x8e, 0x21, 0x49, 0xe2, 0x64, 0xb3, 0x63,
+	0xc6, 0x88, 0xd1, 0x11, 0x14, 0x7d, 0x26, 0x4d, 0x53, 0x6f, 0xcf, 0x33, 0x3e, 0x93, 0xf9, 0x22,
+	0x3e, 0x93, 0xe8, 0x19, 0x54, 0x73, 0x9b, 0x4d, 0xef, 0xfe, 0xb3, 0x3c, 0x03, 0x43, 0x4d, 0xe4,
+	0x0f, 0x0e, 0x60, 0x33, 0x7b, 0xf9, 0x9a, 0x8b, 0x98, 0x28, 0xfd, 0x81, 0xe9, 0xe9, 0x2f, 0xfa,
+	0xd5, 0xf0, 0xba, 0xbe, 0x86, 0x2a, 0x50, 0x7a, 0xd3, 0xef, 0xbe, 0xab, 0x5b, 0x67, 0xbb, 0xb0,
+	0xe5, 0xf1, 0x78, 0xaa, 0xea, 0x59, 0x2d, 0xe3, 0x52, 0xf5, 0xfb, 0x92, 0x7e, 0x75, 0x55, 0x4e,
+	0x7f, 0x06, 0x8f, 0xbf, 0x06, 0x00, 0x00, 0xff, 0xff, 0x4c, 0xd4, 0x2c, 0xd9, 0x7b, 0x07, 0x00,
+	0x00,
 }
 }

+ 4 - 7
config.proto

@@ -7,14 +7,13 @@ option java_outer_classname = "ConfigProto";
 
 
 import "v2ray.com/core/app/router/config.proto";
 import "v2ray.com/core/app/router/config.proto";
 import "v2ray.com/core/app/dns/config.proto";
 import "v2ray.com/core/app/dns/config.proto";
+import "v2ray.com/core/common/loader/type.proto";
 import "v2ray.com/core/common/net/port.proto";
 import "v2ray.com/core/common/net/port.proto";
 import "v2ray.com/core/common/net/address.proto";
 import "v2ray.com/core/common/net/address.proto";
 import "v2ray.com/core/common/log/config.proto";
 import "v2ray.com/core/common/log/config.proto";
 import "v2ray.com/core/transport/internet/config.proto";
 import "v2ray.com/core/transport/internet/config.proto";
 import "v2ray.com/core/transport/config.proto";
 import "v2ray.com/core/transport/config.proto";
 
 
-import "google/protobuf/any.proto";
-
 enum ConfigFormat {
 enum ConfigFormat {
   Protobuf = 0;
   Protobuf = 0;
   JSON = 1;
   JSON = 1;
@@ -51,22 +50,20 @@ message AllocationStrategy {
 
 
 // Config for an inbound connection handler.
 // Config for an inbound connection handler.
 message InboundConnectionConfig {
 message InboundConnectionConfig {
-  string protocol = 1;
+  v2ray.core.common.loader.TypedSettings settings = 1;
   v2ray.core.common.net.PortRange port_range = 2;
   v2ray.core.common.net.PortRange port_range = 2;
   v2ray.core.common.net.IPOrDomain listen_on = 3;
   v2ray.core.common.net.IPOrDomain listen_on = 3;
   string tag = 4;
   string tag = 4;
   AllocationStrategy allocation_strategy = 5;
   AllocationStrategy allocation_strategy = 5;
   v2ray.core.transport.internet.StreamConfig stream_settings = 6;
   v2ray.core.transport.internet.StreamConfig stream_settings = 6;
-  google.protobuf.Any settings = 7;
-  bool allow_passive_connection = 8;
+  bool allow_passive_connection = 7;
 }
 }
 
 
 message OutboundConnectionConfig {
 message OutboundConnectionConfig {
-  string protocol = 1;
+  v2ray.core.common.loader.TypedSettings settings = 1;
   v2ray.core.common.net.IPOrDomain send_through = 2;
   v2ray.core.common.net.IPOrDomain send_through = 2;
   v2ray.core.transport.internet.StreamConfig stream_settings = 3;
   v2ray.core.transport.internet.StreamConfig stream_settings = 3;
   string tag = 4;
   string tag = 4;
-  google.protobuf.Any settings = 5;
 }
 }
 
 
 message Config {
 message Config {

+ 1 - 1
inbound_detour_always.go

@@ -28,7 +28,7 @@ func NewInboundDetourHandlerAlways(space app.Space, config *InboundConnectionCon
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
-		ich, err := proxyregistry.CreateInboundHandler(config.Protocol, space, ichConfig, &proxy.InboundHandlerMeta{
+		ich, err := proxyregistry.CreateInboundHandler(config.Settings.Type, space, ichConfig, &proxy.InboundHandlerMeta{
 			Address:                config.ListenOn.AsAddress(),
 			Address:                config.ListenOn.AsAddress(),
 			Port:                   i,
 			Port:                   i,
 			Tag:                    config.Tag,
 			Tag:                    config.Tag,

+ 2 - 2
inbound_detour_dynamic.go

@@ -36,7 +36,7 @@ func NewInboundDetourHandlerDynamic(space app.Space, config *InboundConnectionCo
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	ich, err := proxyregistry.CreateInboundHandler(config.Protocol, space, ichConfig, &proxy.InboundHandlerMeta{
+	ich, err := proxyregistry.CreateInboundHandler(config.Settings.Type, space, ichConfig, &proxy.InboundHandlerMeta{
 		Address:                config.ListenOn.AsAddress(),
 		Address:                config.ListenOn.AsAddress(),
 		Port:                   0,
 		Port:                   0,
 		Tag:                    config.Tag,
 		Tag:                    config.Tag,
@@ -107,7 +107,7 @@ func (this *InboundDetourHandlerDynamic) refresh() error {
 	for idx := range newIchs {
 	for idx := range newIchs {
 		err := retry.Timed(5, 100).On(func() error {
 		err := retry.Timed(5, 100).On(func() error {
 			port := this.pickUnusedPort()
 			port := this.pickUnusedPort()
-			ich, err := proxyregistry.CreateInboundHandler(config.Protocol, this.space, config.Settings, &proxy.InboundHandlerMeta{
+			ich, err := proxyregistry.CreateInboundHandler(config.Settings.Type, this.space, config.Settings, &proxy.InboundHandlerMeta{
 				Address: config.ListenOn.AsAddress(), Port: port, Tag: config.Tag, StreamSettings: config.StreamSettings})
 				Address: config.ListenOn.AsAddress(), Port: port, Tag: config.Tag, StreamSettings: config.StreamSettings})
 			if err != nil {
 			if err != nil {
 				delete(this.portsInUse, port)
 				delete(this.portsInUse, port)

+ 13 - 1
main/main.go

@@ -7,6 +7,7 @@ import (
 	"os"
 	"os"
 	"os/signal"
 	"os/signal"
 	"path/filepath"
 	"path/filepath"
+	"strings"
 	"syscall"
 	"syscall"
 
 
 	"v2ray.com/core"
 	"v2ray.com/core"
@@ -29,6 +30,17 @@ func init() {
 	flag.StringVar(&configFile, "config", defaultConfigFile, "Config file for this Point server.")
 	flag.StringVar(&configFile, "config", defaultConfigFile, "Config file for this Point server.")
 }
 }
 
 
+func GetConfigFormat() core.ConfigFormat {
+	switch strings.ToLower(*format) {
+	case "json":
+		return core.ConfigFormat_JSON
+	case "pb", "protobuf":
+		return core.ConfigFormat_Protobuf
+	default:
+		return core.ConfigFormat_JSON
+	}
+}
+
 func startV2Ray() *core.Point {
 func startV2Ray() *core.Point {
 	if len(configFile) == 0 {
 	if len(configFile) == 0 {
 		log.Error("Config file is not set.")
 		log.Error("Config file is not set.")
@@ -47,7 +59,7 @@ func startV2Ray() *core.Point {
 		defer file.Close()
 		defer file.Close()
 		configInput = file
 		configInput = file
 	}
 	}
-	config, err := core.LoadConfig(configInput)
+	config, err := core.LoadConfig(GetConfigFormat(), configInput)
 	if err != nil {
 	if err != nil {
 		log.Error("Failed to read config file (", configFile, "): ", configFile, err)
 		log.Error("Failed to read config file (", configFile, "): ", configFile, err)
 		return nil
 		return nil

+ 3 - 2
proxy/blackhole/blackhole.go

@@ -3,6 +3,7 @@ package blackhole
 import (
 import (
 	"v2ray.com/core/app"
 	"v2ray.com/core/app"
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/alloc"
+	"v2ray.com/core/common/loader"
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/proxy"
 	"v2ray.com/core/proxy"
 	"v2ray.com/core/proxy/registry"
 	"v2ray.com/core/proxy/registry"
@@ -16,7 +17,7 @@ type BlackHole struct {
 }
 }
 
 
 func NewBlackHole(space app.Space, config *Config, meta *proxy.OutboundHandlerMeta) (*BlackHole, error) {
 func NewBlackHole(space app.Space, config *Config, meta *proxy.OutboundHandlerMeta) (*BlackHole, error) {
-	response, err := config.Response.GetInternalResponse()
+	response, err := config.GetInternalResponse()
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -50,5 +51,5 @@ func (this *Factory) Create(space app.Space, config interface{}, meta *proxy.Out
 }
 }
 
 
 func init() {
 func init() {
-	registry.MustRegisterOutboundHandlerCreator("blackhole", new(Factory))
+	registry.MustRegisterOutboundHandlerCreator(loader.GetType(new(Config)), new(Factory))
 }
 }

+ 4 - 23
proxy/blackhole/config.go

@@ -4,11 +4,8 @@ import (
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/alloc"
 	v2io "v2ray.com/core/common/io"
 	v2io "v2ray.com/core/common/io"
 
 
-	"github.com/golang/protobuf/proto"
 	"github.com/golang/protobuf/ptypes"
 	"github.com/golang/protobuf/ptypes"
 	"github.com/golang/protobuf/ptypes/any"
 	"github.com/golang/protobuf/ptypes/any"
-	"strings"
-	"v2ray.com/core/common/loader"
 )
 )
 
 
 const (
 const (
@@ -42,30 +39,14 @@ func (this *HTTPResponse) AsAny() *any.Any {
 	return r
 	return r
 }
 }
 
 
-func (this *Response) GetInternalResponse() (ResponseConfig, error) {
-	if this == nil {
+func (this *Config) GetInternalResponse() (ResponseConfig, error) {
+	if this.GetResponse() == nil {
 		return new(NoneResponse), nil
 		return new(NoneResponse), nil
 	}
 	}
 
 
-	var r ResponseConfig
-	switch this.Type {
-	case Response_None:
-		r = new(NoneResponse)
-	case Response_HTTP:
-		r = new(HTTPResponse)
-	}
-	err := ptypes.UnmarshalAny(this.Settings, r.(proto.Message))
+	config, err := this.GetResponse().GetInstance()
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	return r, nil
-}
-
-var (
-	cache = loader.ConfigCreatorCache{}
-)
-
-func init() {
-	cache.RegisterCreator(strings.ToLower(Response_Type_name[int32(Response_None)]), func() interface{} { return new(NoneResponse) })
-	cache.RegisterCreator(strings.ToLower(Response_Type_name[int32(Response_HTTP)]), func() interface{} { return new(HTTPResponse) })
+	return config.(ResponseConfig), nil
 }
 }

+ 10 - 16
proxy/blackhole/config_json.go

@@ -6,9 +6,8 @@ import (
 	"encoding/json"
 	"encoding/json"
 	"errors"
 	"errors"
 
 
-	"strings"
+	"github.com/golang/protobuf/proto"
 	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/loader"
-	"v2ray.com/core/proxy/registry"
 )
 )
 
 
 func (this *Config) UnmarshalJSON(data []byte) error {
 func (this *Config) UnmarshalJSON(data []byte) error {
@@ -21,27 +20,22 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 	}
 	}
 
 
 	if jsonConfig.Response != nil {
 	if jsonConfig.Response != nil {
-		response, rType, err := configLoader.Load(jsonConfig.Response)
+		response, _, err := configLoader.Load(jsonConfig.Response)
 		if err != nil {
 		if err != nil {
 			return errors.New("Blackhole: Failed to parse response config: " + err.Error())
 			return errors.New("Blackhole: Failed to parse response config: " + err.Error())
 		}
 		}
-		this.Response = new(Response)
-		switch rType {
-		case strings.ToLower(Response_Type_name[int32(Response_None)]):
-			this.Response.Type = Response_None
-		case strings.ToLower(Response_Type_name[int32(Response_HTTP)]):
-			this.Response.Type = Response_HTTP
-		}
-		this.Response.Settings = response.(ResponseConfig).AsAny()
+		this.Response = loader.NewTypedSettings(response.(proto.Message))
 	}
 	}
 
 
 	return nil
 	return nil
 }
 }
 
 
 var (
 var (
-	configLoader = loader.NewJSONConfigLoader(cache, "type", "")
+	configLoader = loader.NewJSONConfigLoader(
+		loader.NamedTypeMap{
+			"none": loader.GetType(new(NoneResponse)),
+			"http": loader.GetType(new(HTTPResponse)),
+		},
+		"type",
+		"")
 )
 )
-
-func init() {
-	registry.RegisterOutboundConfig("blackhole", func() interface{} { return new(Config) })
-}

+ 0 - 5
proxy/dokodemo/config_json.go

@@ -7,7 +7,6 @@ import (
 	"errors"
 	"errors"
 
 
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
-	"v2ray.com/core/proxy/registry"
 )
 )
 
 
 func (this *Config) UnmarshalJSON(data []byte) error {
 func (this *Config) UnmarshalJSON(data []byte) error {
@@ -31,7 +30,3 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 	this.FollowRedirect = rawConfig.Redirect
 	this.FollowRedirect = rawConfig.Redirect
 	return nil
 	return nil
 }
 }
-
-func init() {
-	registry.RegisterInboundConfig("dokodemo-door", func() interface{} { return new(Config) })
-}

+ 2 - 1
proxy/dokodemo/dokodemo.go

@@ -7,6 +7,7 @@ import (
 	"v2ray.com/core/app/dispatcher"
 	"v2ray.com/core/app/dispatcher"
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/alloc"
 	v2io "v2ray.com/core/common/io"
 	v2io "v2ray.com/core/common/io"
+	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/proxy"
 	"v2ray.com/core/proxy"
@@ -205,5 +206,5 @@ func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.
 }
 }
 
 
 func init() {
 func init() {
-	registry.MustRegisterInboundHandlerCreator("dokodemo-door", new(Factory))
+	registry.MustRegisterInboundHandlerCreator(loader.GetType(new(Config)), new(Factory))
 }
 }

+ 0 - 6
proxy/freedom/config_json.go

@@ -6,8 +6,6 @@ import (
 	"encoding/json"
 	"encoding/json"
 	"errors"
 	"errors"
 	"strings"
 	"strings"
-
-	"v2ray.com/core/proxy/registry"
 )
 )
 
 
 func (this *Config) UnmarshalJSON(data []byte) error {
 func (this *Config) UnmarshalJSON(data []byte) error {
@@ -27,7 +25,3 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 	this.Timeout = jsonConfig.Timeout
 	this.Timeout = jsonConfig.Timeout
 	return nil
 	return nil
 }
 }
-
-func init() {
-	registry.RegisterOutboundConfig("freedom", func() interface{} { return new(Config) })
-}

+ 2 - 1
proxy/freedom/freedom.go

@@ -8,6 +8,7 @@ import (
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/dice"
 	"v2ray.com/core/common/dice"
 	v2io "v2ray.com/core/common/io"
 	v2io "v2ray.com/core/common/io"
+	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/retry"
 	"v2ray.com/core/common/retry"
@@ -140,5 +141,5 @@ func (this *FreedomFactory) Create(space app.Space, config interface{}, meta *pr
 }
 }
 
 
 func init() {
 func init() {
-	registry.MustRegisterOutboundHandlerCreator("freedom", new(FreedomFactory))
+	registry.MustRegisterOutboundHandlerCreator(loader.GetType(new(Config)), new(FreedomFactory))
 }
 }

+ 0 - 6
proxy/http/config_json.go

@@ -5,8 +5,6 @@ package http
 import (
 import (
 	"encoding/json"
 	"encoding/json"
 	"errors"
 	"errors"
-
-	"v2ray.com/core/proxy/registry"
 )
 )
 
 
 // UnmarshalJSON implements json.Unmarshaler
 // UnmarshalJSON implements json.Unmarshaler
@@ -22,7 +20,3 @@ func (this *ServerConfig) UnmarshalJSON(data []byte) error {
 
 
 	return nil
 	return nil
 }
 }
-
-func init() {
-	registry.RegisterInboundConfig("http", func() interface{} { return new(ServerConfig) })
-}

+ 2 - 1
proxy/http/server.go

@@ -13,6 +13,7 @@ import (
 	"v2ray.com/core/app/dispatcher"
 	"v2ray.com/core/app/dispatcher"
 	"v2ray.com/core/common"
 	"v2ray.com/core/common"
 	v2io "v2ray.com/core/common/io"
 	v2io "v2ray.com/core/common/io"
+	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/proxy"
 	"v2ray.com/core/proxy"
@@ -281,5 +282,5 @@ func (this *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *
 }
 }
 
 
 func init() {
 func init() {
-	registry.MustRegisterInboundHandlerCreator("http", new(ServerFactory))
+	registry.MustRegisterInboundHandlerCreator(loader.GetType(new(ServerConfig)), new(ServerFactory))
 }
 }

+ 0 - 50
proxy/registry/config_cache.go

@@ -1,50 +0,0 @@
-package registry
-
-import (
-	"v2ray.com/core/common/loader"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/ptypes"
-	"github.com/golang/protobuf/ptypes/any"
-)
-
-var (
-	inboundConfigCreatorCache  = loader.ConfigCreatorCache{}
-	outboundConfigCreatorCache = loader.ConfigCreatorCache{}
-)
-
-func RegisterInboundConfig(protocol string, creator loader.ConfigCreator) error {
-	return inboundConfigCreatorCache.RegisterCreator(protocol, creator)
-}
-
-func RegisterOutboundConfig(protocol string, creator loader.ConfigCreator) error {
-	return outboundConfigCreatorCache.RegisterCreator(protocol, creator)
-}
-
-func MarshalInboundConfig(protocol string, settings *any.Any) (interface{}, error) {
-	config, err := inboundConfigCreatorCache.CreateConfig(protocol)
-	if err != nil {
-		return nil, err
-	}
-	if settings == nil {
-		return config, nil
-	}
-	if err := ptypes.UnmarshalAny(settings, config.(proto.Message)); err != nil {
-		return nil, err
-	}
-	return config, nil
-}
-
-func MarshalOutboundConfig(protocol string, settings *any.Any) (interface{}, error) {
-	config, err := outboundConfigCreatorCache.CreateConfig(protocol)
-	if err != nil {
-		return nil, err
-	}
-	if settings == nil {
-		return config, nil
-	}
-	if err := ptypes.UnmarshalAny(settings, config.(proto.Message)); err != nil {
-		return nil, err
-	}
-	return config, nil
-}

+ 0 - 25
proxy/registry/config_cache_json.go

@@ -1,25 +0,0 @@
-// +build json
-
-package registry
-
-import (
-	"v2ray.com/core/common/loader"
-)
-
-var (
-	inboundConfigCache  loader.ConfigLoader
-	outboundConfigCache loader.ConfigLoader
-)
-
-func CreateInboundConfig(protocol string, data []byte) (interface{}, error) {
-	return inboundConfigCache.LoadWithID(data, protocol)
-}
-
-func CreateOutboundConfig(protocol string, data []byte) (interface{}, error) {
-	return outboundConfigCache.LoadWithID(data, protocol)
-}
-
-func init() {
-	inboundConfigCache = loader.NewJSONConfigLoader(inboundConfigCreatorCache, "protocol", "settings")
-	outboundConfigCache = loader.NewJSONConfigLoader(outboundConfigCreatorCache, "protocol", "settings")
-}

+ 2 - 13
proxy/shadowsocks/config_json.go

@@ -8,11 +8,9 @@ import (
 	"strings"
 	"strings"
 
 
 	"v2ray.com/core/common"
 	"v2ray.com/core/common"
+	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/protocol"
-	"v2ray.com/core/proxy/registry"
-
-	"github.com/golang/protobuf/ptypes"
 )
 )
 
 
 func (this *ServerConfig) UnmarshalJSON(data []byte) error {
 func (this *ServerConfig) UnmarshalJSON(data []byte) error {
@@ -52,20 +50,11 @@ func (this *ServerConfig) UnmarshalJSON(data []byte) error {
 		return common.ErrBadConfiguration
 		return common.ErrBadConfiguration
 	}
 	}
 
 
-	anyAccount, err := ptypes.MarshalAny(account)
-	if err != nil {
-		log.Error("Shadowsocks: Failed to create account: ", err)
-		return common.ErrBadConfiguration
-	}
 	this.User = &protocol.User{
 	this.User = &protocol.User{
 		Email:   jsonConfig.Email,
 		Email:   jsonConfig.Email,
 		Level:   uint32(jsonConfig.Level),
 		Level:   uint32(jsonConfig.Level),
-		Account: anyAccount,
+		Account: loader.NewTypedSettings(account),
 	}
 	}
 
 
 	return nil
 	return nil
 }
 }
-
-func init() {
-	registry.RegisterInboundConfig("shadowsocks", func() interface{} { return new(ServerConfig) })
-}

+ 4 - 2
proxy/shadowsocks/config_json_test.go

@@ -21,10 +21,12 @@ func TestConfigParsing(t *testing.T) {
 	err := json.Unmarshal([]byte(rawJson), config)
 	err := json.Unmarshal([]byte(rawJson), config)
 	assert.Error(err).IsNil()
 	assert.Error(err).IsNil()
 
 
-	account := new(Account)
-	_, err = config.User.GetTypedAccount(account)
+	rawAccount, err = config.User.GetTypedAccount()
 	assert.Error(err).IsNil()
 	assert.Error(err).IsNil()
 
 
+	account, ok := rawAccount.(*Account)
+	assert.Bool(ok).IsTrue()
+
 	cipher, err := account.GetCipher()
 	cipher, err := account.GetCipher()
 	assert.Error(err).IsNil()
 	assert.Error(err).IsNil()
 	assert.Int(cipher.KeySize()).Equals(16)
 	assert.Int(cipher.KeySize()).Equals(16)

+ 8 - 3
proxy/shadowsocks/server.go

@@ -12,6 +12,7 @@ import (
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/crypto"
 	"v2ray.com/core/common/crypto"
 	v2io "v2ray.com/core/common/io"
 	v2io "v2ray.com/core/common/io"
+	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/protocol"
@@ -37,10 +38,14 @@ func NewServer(config *ServerConfig, space app.Space, meta *proxy.InboundHandler
 	if config.GetUser() == nil {
 	if config.GetUser() == nil {
 		return nil, protocol.ErrUserMissing
 		return nil, protocol.ErrUserMissing
 	}
 	}
-	account := new(Account)
-	if _, err := config.GetUser().GetTypedAccount(account); err != nil {
+	rawAccount, err := config.GetUser().GetTypedAccount()
+	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
+	account, ok := rawAccount.(*Account)
+	if !ok {
+		return nil, protocol.ErrUnknownAccountType
+	}
 	cipher, err := account.GetCipher()
 	cipher, err := account.GetCipher()
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -292,5 +297,5 @@ func (this *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *
 }
 }
 
 
 func init() {
 func init() {
-	registry.MustRegisterInboundHandlerCreator("shadowsocks", new(ServerFactory))
+	registry.MustRegisterInboundHandlerCreator(loader.GetType(new(ServerConfig)), new(ServerFactory))
 }
 }

+ 4 - 9
proxy/socks/config.go

@@ -8,7 +8,6 @@ import (
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/protocol"
-	"v2ray.com/core/proxy/registry"
 
 
 	"github.com/golang/protobuf/ptypes"
 	"github.com/golang/protobuf/ptypes"
 	google_protobuf "github.com/golang/protobuf/ptypes/any"
 	google_protobuf "github.com/golang/protobuf/ptypes/any"
@@ -58,11 +57,11 @@ const (
 
 
 func (this *ServerConfig) UnmarshalJSON(data []byte) error {
 func (this *ServerConfig) UnmarshalJSON(data []byte) error {
 	type SocksConfig struct {
 	type SocksConfig struct {
-		AuthMethod string           `json:"auth"`
-		Accounts   []*Account       `json:"accounts"`
-		UDP        bool             `json:"udp"`
+		AuthMethod string            `json:"auth"`
+		Accounts   []*Account        `json:"accounts"`
+		UDP        bool              `json:"udp"`
 		Host       *v2net.IPOrDomain `json:"ip"`
 		Host       *v2net.IPOrDomain `json:"ip"`
-		Timeout    uint32           `json:"timeout"`
+		Timeout    uint32            `json:"timeout"`
 	}
 	}
 
 
 	rawConfig := new(SocksConfig)
 	rawConfig := new(SocksConfig)
@@ -95,7 +94,3 @@ func (this *ServerConfig) UnmarshalJSON(data []byte) error {
 	}
 	}
 	return nil
 	return nil
 }
 }
-
-func init() {
-	registry.RegisterInboundConfig("socks", func() interface{} { return new(ServerConfig) })
-}

+ 3 - 11
proxy/socks/config_json.go

@@ -6,9 +6,9 @@ import (
 	"encoding/json"
 	"encoding/json"
 	"errors"
 	"errors"
 
 
+	"v2ray.com/core/common/loader"
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/protocol"
-	"v2ray.com/core/proxy/registry"
 )
 )
 
 
 func (this *Account) UnmarshalJSON(data []byte) error {
 func (this *Account) UnmarshalJSON(data []byte) error {
@@ -27,7 +27,7 @@ func (this *Account) UnmarshalJSON(data []byte) error {
 
 
 func (this *ClientConfig) UnmarshalJSON(data []byte) error {
 func (this *ClientConfig) UnmarshalJSON(data []byte) error {
 	type ServerConfig struct {
 	type ServerConfig struct {
-		Address *v2net.IPOrDomain  `json:"address"`
+		Address *v2net.IPOrDomain `json:"address"`
 		Port    v2net.Port        `json:"port"`
 		Port    v2net.Port        `json:"port"`
 		Users   []json.RawMessage `json:"users"`
 		Users   []json.RawMessage `json:"users"`
 	}
 	}
@@ -53,18 +53,10 @@ func (this *ClientConfig) UnmarshalJSON(data []byte) error {
 			if err := json.Unmarshal(rawUser, account); err != nil {
 			if err := json.Unmarshal(rawUser, account); err != nil {
 				return errors.New("Socks|Client: Failed to parse socks account: " + err.Error())
 				return errors.New("Socks|Client: Failed to parse socks account: " + err.Error())
 			}
 			}
-			anyAccount, err := account.AsAny()
-			if err != nil {
-				return err
-			}
-			user.Account = anyAccount
+			user.Account = loader.NewTypedSettings(account)
 			server.User = append(server.User, user)
 			server.User = append(server.User, user)
 		}
 		}
 		this.Server[idx] = server
 		this.Server[idx] = server
 	}
 	}
 	return nil
 	return nil
 }
 }
-
-func init() {
-	registry.RegisterOutboundConfig("socks", func() interface{} { return new(ClientConfig) })
-}

+ 2 - 1
proxy/socks/server.go

@@ -9,6 +9,7 @@ import (
 	"v2ray.com/core/app"
 	"v2ray.com/core/app"
 	"v2ray.com/core/app/dispatcher"
 	"v2ray.com/core/app/dispatcher"
 	v2io "v2ray.com/core/common/io"
 	v2io "v2ray.com/core/common/io"
+	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/proxy"
 	"v2ray.com/core/proxy"
@@ -326,5 +327,5 @@ func (this *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *
 }
 }
 
 
 func init() {
 func init() {
-	registry.MustRegisterInboundHandlerCreator("socks", new(ServerFactory))
+	registry.MustRegisterInboundHandlerCreator(loader.GetType(new(ServerConfig)), new(ServerFactory))
 }
 }

+ 1 - 1
proxy/vmess/encoding/client.go

@@ -52,7 +52,7 @@ func NewClientSession(idHash protocol.IDHash) *ClientSession {
 
 
 func (this *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, writer io.Writer) {
 func (this *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, writer io.Writer) {
 	timestamp := protocol.NewTimestampGenerator(protocol.NowTime(), 30)()
 	timestamp := protocol.NewTimestampGenerator(protocol.NowTime(), 30)()
-	account, err := header.User.GetTypedAccount(&vmess.Account{})
+	account, err := header.User.GetTypedAccount()
 	if err != nil {
 	if err != nil {
 		log.Error("VMess: Failed to get user account: ", err)
 		log.Error("VMess: Failed to get user account: ", err)
 		return
 		return

+ 2 - 1
proxy/vmess/encoding/server.go

@@ -59,11 +59,12 @@ func (this *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Requ
 	timestampHash := md5.New()
 	timestampHash := md5.New()
 	timestampHash.Write(hashTimestamp(timestamp))
 	timestampHash.Write(hashTimestamp(timestamp))
 	iv := timestampHash.Sum(nil)
 	iv := timestampHash.Sum(nil)
-	account, err := user.GetTypedAccount(&vmess.Account{})
+	account, err := user.GetTypedAccount()
 	if err != nil {
 	if err != nil {
 		log.Error("Vmess: Failed to get user account: ", err)
 		log.Error("Vmess: Failed to get user account: ", err)
 		return nil, err
 		return nil, err
 	}
 	}
+
 	aesStream := crypto.NewAesDecryptionStream(account.(*vmess.InternalAccount).ID.CmdKey(), iv)
 	aesStream := crypto.NewAesDecryptionStream(account.(*vmess.InternalAccount).ID.CmdKey(), iv)
 	decryptor := crypto.NewCryptionReader(aesStream, reader)
 	decryptor := crypto.NewCryptionReader(aesStream, reader)
 
 

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

@@ -22,7 +22,7 @@ func (this *VMessInboundHandler) generateCommand(request *protocol.RequestHeader
 				if user == nil {
 				if user == nil {
 					return nil
 					return nil
 				}
 				}
-				account, _ := user.GetTypedAccount(&vmess.Account{})
+				account, _ := user.GetTypedAccount()
 				return &protocol.CommandSwitchAccount{
 				return &protocol.CommandSwitchAccount{
 					Port:     inboundHandler.Port(),
 					Port:     inboundHandler.Port(),
 					ID:       account.(*vmess.InternalAccount).ID.UUID(),
 					ID:       account.(*vmess.InternalAccount).ID.UUID(),

+ 2 - 15
proxy/vmess/inbound/config_json.go

@@ -6,13 +6,9 @@ import (
 	"encoding/json"
 	"encoding/json"
 	"errors"
 	"errors"
 
 
-	"v2ray.com/core/common"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/protocol"
-	"v2ray.com/core/proxy/registry"
 	"v2ray.com/core/proxy/vmess"
 	"v2ray.com/core/proxy/vmess"
-
-	"github.com/golang/protobuf/ptypes"
 )
 )
 
 
 func (this *DetourConfig) UnmarshalJSON(data []byte) error {
 func (this *DetourConfig) UnmarshalJSON(data []byte) error {
@@ -81,18 +77,9 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 		if err := json.Unmarshal(rawData, account); err != nil {
 		if err := json.Unmarshal(rawData, account); err != nil {
 			return errors.New("VMess|Inbound: Invalid user: " + err.Error())
 			return errors.New("VMess|Inbound: Invalid user: " + err.Error())
 		}
 		}
-		anyAccount, err := ptypes.MarshalAny(account)
-		if err != nil {
-			log.Error("VMess|Inbound: Failed to create account: ", err)
-			return common.ErrBadConfiguration
-		}
-		user.Account = anyAccount
+		user.Account = loader.NewTypedSettings(account)
 		this.User[idx] = user
 		this.User[idx] = user
 	}
 	}
 
 
 	return nil
 	return nil
 }
 }
-
-func init() {
-	registry.RegisterInboundConfig("vmess", func() interface{} { return new(Config) })
-}

+ 3 - 5
proxy/vmess/inbound/inbound.go

@@ -10,6 +10,7 @@ import (
 	"v2ray.com/core/common"
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/alloc"
 	v2io "v2ray.com/core/common/io"
 	v2io "v2ray.com/core/common/io"
+	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/protocol"
@@ -20,8 +21,6 @@ import (
 	"v2ray.com/core/proxy/vmess/encoding"
 	"v2ray.com/core/proxy/vmess/encoding"
 	vmessio "v2ray.com/core/proxy/vmess/io"
 	vmessio "v2ray.com/core/proxy/vmess/io"
 	"v2ray.com/core/transport/internet"
 	"v2ray.com/core/transport/internet"
-
-	"github.com/golang/protobuf/ptypes"
 )
 )
 
 
 type userByEmail struct {
 type userByEmail struct {
@@ -57,11 +56,10 @@ func (this *userByEmail) Get(email string) (*protocol.User, bool) {
 				Id:      uuid.New().String(),
 				Id:      uuid.New().String(),
 				AlterId: uint32(this.defaultAlterIDs),
 				AlterId: uint32(this.defaultAlterIDs),
 			}
 			}
-			anyAccount, _ := ptypes.MarshalAny(account)
 			user = &protocol.User{
 			user = &protocol.User{
 				Level:   this.defaultLevel,
 				Level:   this.defaultLevel,
 				Email:   email,
 				Email:   email,
-				Account: anyAccount,
+				Account: loader.NewTypedSettings(account),
 			}
 			}
 			this.cache[email] = user
 			this.cache[email] = user
 		}
 		}
@@ -282,5 +280,5 @@ func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.
 }
 }
 
 
 func init() {
 func init() {
-	registry.MustRegisterInboundHandlerCreator("vmess", new(Factory))
+	registry.MustRegisterInboundHandlerCreator(loader.GetType(new(Config)), new(Factory))
 }
 }

+ 3 - 4
proxy/vmess/outbound/command.go

@@ -3,11 +3,10 @@ package outbound
 import (
 import (
 	"time"
 	"time"
 
 
+	"v2ray.com/core/common/loader"
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/proxy/vmess"
 	"v2ray.com/core/proxy/vmess"
-
-	"github.com/golang/protobuf/ptypes"
 )
 )
 
 
 func (this *VMessOutboundHandler) handleSwitchAccount(cmd *protocol.CommandSwitchAccount) {
 func (this *VMessOutboundHandler) handleSwitchAccount(cmd *protocol.CommandSwitchAccount) {
@@ -15,11 +14,11 @@ func (this *VMessOutboundHandler) handleSwitchAccount(cmd *protocol.CommandSwitc
 		Id:      cmd.ID.String(),
 		Id:      cmd.ID.String(),
 		AlterId: uint32(cmd.AlterIds),
 		AlterId: uint32(cmd.AlterIds),
 	}
 	}
-	anyAccount, _ := ptypes.MarshalAny(account)
+
 	user := &protocol.User{
 	user := &protocol.User{
 		Email:   "",
 		Email:   "",
 		Level:   cmd.Level,
 		Level:   cmd.Level,
-		Account: anyAccount,
+		Account: loader.NewTypedSettings(account),
 	}
 	}
 	dest := v2net.TCPDestination(cmd.Host, cmd.Port)
 	dest := v2net.TCPDestination(cmd.Host, cmd.Port)
 	until := time.Now().Add(time.Duration(cmd.ValidMin) * time.Minute)
 	until := time.Now().Add(time.Duration(cmd.ValidMin) * time.Minute)

+ 2 - 13
proxy/vmess/outbound/config_json.go

@@ -7,14 +7,12 @@ import (
 	"errors"
 	"errors"
 
 
 	"v2ray.com/core/common"
 	"v2ray.com/core/common"
+	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/serial"
 	"v2ray.com/core/common/serial"
-	"v2ray.com/core/proxy/registry"
 	"v2ray.com/core/proxy/vmess"
 	"v2ray.com/core/proxy/vmess"
-
-	"github.com/golang/protobuf/ptypes"
 )
 )
 
 
 func (this *Config) UnmarshalJSON(data []byte) error {
 func (this *Config) UnmarshalJSON(data []byte) error {
@@ -65,12 +63,7 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 				log.Error("VMess|Outbound: Invalid user: ", err)
 				log.Error("VMess|Outbound: Invalid user: ", err)
 				return err
 				return err
 			}
 			}
-			anyAccount, err := ptypes.MarshalAny(account)
-			if err != nil {
-				log.Error("VMess|Outbound: Failed to create account: ", err)
-				return common.ErrBadConfiguration
-			}
-			user.Account = anyAccount
+			user.Account = loader.NewTypedSettings(account)
 			spec.User = append(spec.User, user)
 			spec.User = append(spec.User, user)
 		}
 		}
 		serverSpecs[idx] = spec
 		serverSpecs[idx] = spec
@@ -78,7 +71,3 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 	this.Receiver = serverSpecs
 	this.Receiver = serverSpecs
 	return nil
 	return nil
 }
 }
-
-func init() {
-	registry.RegisterOutboundConfig("vmess", func() interface{} { return new(Config) })
-}

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

@@ -7,6 +7,7 @@ import (
 	"v2ray.com/core/app"
 	"v2ray.com/core/app"
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/alloc"
 	v2io "v2ray.com/core/common/io"
 	v2io "v2ray.com/core/common/io"
+	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/protocol"
@@ -183,5 +184,5 @@ func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.
 }
 }
 
 
 func init() {
 func init() {
-	registry.MustRegisterOutboundHandlerCreator("vmess", new(Factory))
+	registry.MustRegisterOutboundHandlerCreator(loader.GetType(new(Config)), new(Factory))
 }
 }

+ 1 - 1
proxy/vmess/vmess.go

@@ -118,7 +118,7 @@ L:
 func (this *TimedUserValidator) Add(user *protocol.User) error {
 func (this *TimedUserValidator) Add(user *protocol.User) error {
 	idx := len(this.validUsers)
 	idx := len(this.validUsers)
 	this.validUsers = append(this.validUsers, user)
 	this.validUsers = append(this.validUsers, user)
-	rawAccount, err := user.GetTypedAccount(&Account{})
+	rawAccount, err := user.GetTypedAccount()
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}

+ 76 - 0
tools/conf/common.go

@@ -0,0 +1,76 @@
+package conf
+
+import (
+	"encoding/json"
+	"errors"
+
+	"strings"
+	v2net "v2ray.com/core/common/net"
+)
+
+type Address struct {
+	v2net.Address
+}
+
+func (this *Address) UnmarshalJSON(data []byte) error {
+	var rawStr string
+	if err := json.Unmarshal(data, &rawStr); err != nil {
+		return err
+	}
+	this.Address = v2net.ParseAddress(rawStr)
+
+	return nil
+}
+
+func (this *Address) Build() *v2net.IPOrDomain {
+	if this.Family().IsDomain() {
+		return &v2net.IPOrDomain{
+			Address: &v2net.IPOrDomain_Domain{
+				Domain: this.Domain(),
+			},
+		}
+	}
+
+	return &v2net.IPOrDomain{
+		Address: &v2net.IPOrDomain_Ip{
+			Ip: []byte(this.IP()),
+		},
+	}
+}
+
+type Network string
+
+func (this Network) Build() v2net.Network {
+	return v2net.ParseNetwork(string(this))
+}
+
+type NetworkList []Network
+
+func (this *NetworkList) UnmarshalJSON(data []byte) error {
+	var strarray []Network
+	if err := json.Unmarshal(data, &strarray); err == nil {
+		nl := NetworkList(strarray)
+		*this = nl
+		return nil
+	}
+
+	var rawstr Network
+	if err := json.Unmarshal(data, &rawstr); err == nil {
+		strlist := strings.Split(string(rawstr), ",")
+		nl := make([]Network, len(strlist))
+		for idx, network := range strlist {
+			nl[idx] = Network(network)
+		}
+		*this = nl
+		return nil
+	}
+	return errors.New("Unknown format of a string list: " + string(data))
+}
+
+func (this *NetworkList) Build() *v2net.NetworkList {
+	list := new(v2net.NetworkList)
+	for _, network := range *this {
+		list.Network = append(list.Network, network.Build())
+	}
+	return list
+}

+ 80 - 0
tools/conf/common_test.go

@@ -0,0 +1,80 @@
+package conf_test
+
+import (
+	"encoding/json"
+	"testing"
+
+	v2net "v2ray.com/core/common/net"
+	"v2ray.com/core/testing/assert"
+	. "v2ray.com/core/tools/conf"
+)
+
+func TestIPParsing(t *testing.T) {
+	assert := assert.On(t)
+
+	rawJson := "\"8.8.8.8\""
+	var address Address
+	err := json.Unmarshal([]byte(rawJson), &address)
+	assert.Error(err).IsNil()
+	assert.Bytes([]byte(address.IP())).Equals([]byte{8, 8, 8, 8})
+}
+
+func TestDomainParsing(t *testing.T) {
+	assert := assert.On(t)
+
+	rawJson := "\"v2ray.com\""
+	var address Address
+	err := json.Unmarshal([]byte(rawJson), &address)
+	assert.Error(err).IsNil()
+	assert.String(address.Domain()).Equals("v2ray.com")
+}
+
+func TestInvalidAddressJson(t *testing.T) {
+	assert := assert.On(t)
+
+	rawJson := "1234"
+	var address Address
+	err := json.Unmarshal([]byte(rawJson), &address)
+	assert.Error(err).IsNotNil()
+}
+
+func TestStringNetwork(t *testing.T) {
+	assert := assert.On(t)
+
+	var network Network
+	err := json.Unmarshal([]byte(`"tcp"`), &network)
+	assert.Error(err).IsNil()
+	assert.Bool(network.Build() == v2net.Network_TCP).IsTrue()
+}
+
+func TestArrayNetworkList(t *testing.T) {
+	assert := assert.On(t)
+
+	var list NetworkList
+	err := json.Unmarshal([]byte("[\"Tcp\"]"), &list)
+	assert.Error(err).IsNil()
+
+	nlist := list.Build()
+	assert.Bool(nlist.HasNetwork(v2net.ParseNetwork("tcp"))).IsTrue()
+	assert.Bool(nlist.HasNetwork(v2net.ParseNetwork("udp"))).IsFalse()
+}
+
+func TestStringNetworkList(t *testing.T) {
+	assert := assert.On(t)
+
+	var list NetworkList
+	err := json.Unmarshal([]byte("\"TCP, ip\""), &list)
+	assert.Error(err).IsNil()
+
+	nlist := list.Build()
+	assert.Bool(nlist.HasNetwork(v2net.ParseNetwork("tcp"))).IsTrue()
+	assert.Bool(nlist.HasNetwork(v2net.ParseNetwork("udp"))).IsFalse()
+}
+
+func TestInvalidNetworkJson(t *testing.T) {
+	assert := assert.On(t)
+
+	var list NetworkList
+	err := json.Unmarshal([]byte("0"), &list)
+	assert.Error(err).IsNotNil()
+}

+ 43 - 0
tools/conf/log.go

@@ -0,0 +1,43 @@
+package conf
+
+import (
+	"strings"
+
+	"v2ray.com/core/common/log"
+)
+
+type LogConfig struct {
+	AccessLog string `json:"access"`
+	ErrorLog  string `json:"error"`
+	LogLevel  string `json:"loglevel"`
+}
+
+func (this *LogConfig) Build() *log.Config {
+	if this == nil {
+		return nil
+	}
+	config := new(log.Config)
+	if len(this.AccessLog) > 0 {
+		config.AccessLogPath = this.AccessLog
+		config.AccessLogType = log.LogType_File
+	}
+	if len(this.ErrorLog) > 0 {
+		config.ErrorLogPath = this.ErrorLog
+		config.ErrorLogType = log.LogType_File
+	}
+
+	level := strings.ToLower(this.LogLevel)
+	switch level {
+	case "debug":
+		config.ErrorLogLevel = log.LogLevel_Debug
+	case "info":
+		config.ErrorLogLevel = log.LogLevel_Info
+	case "error":
+		config.ErrorLogLevel = log.LogLevel_Error
+	case "none":
+		config.ErrorLogType = log.LogType_None
+	default:
+		config.ErrorLogLevel = log.LogLevel_Warning
+	}
+	return config
+}

+ 28 - 0
tools/conf/v2ray.go

@@ -0,0 +1,28 @@
+package conf
+
+/*
+import (
+	"encoding/json"
+	"errors"
+	"io"
+
+	"v2ray.com/core/app/dns"
+	"v2ray.com/core/app/router"
+	"v2ray.com/core/common"
+	v2net "v2ray.com/core/common/net"
+	"v2ray.com/core/transport"
+	"v2ray.com/core/transport/internet"
+)
+
+type Config struct {
+	Port            uint16                    `json:"port"` // Port of this Point server.
+	LogConfig       *LogConfig                `json:"log"`
+	RouterConfig    *router.Config            `json:"routing"`
+	DNSConfig       *dns.Config               `json:"dns"`
+	InboundConfig   *InboundConnectionConfig  `json:"inbound"`
+	OutboundConfig  *OutboundConnectionConfig `json:"outbound"`
+	InboundDetours  []*InboundDetourConfig    `json:"inboundDetour"`
+	OutboundDetours []*OutboundDetourConfig   `json:"outboundDetour"`
+	Transport       *transport.Config         `json:"transport"`
+}
+*/

+ 4 - 17
transport/config_json.go

@@ -5,13 +5,12 @@ package transport
 import (
 import (
 	"encoding/json"
 	"encoding/json"
 
 
+	"v2ray.com/core/common/loader"
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"
 	"v2ray.com/core/transport/internet"
 	"v2ray.com/core/transport/internet/kcp"
 	"v2ray.com/core/transport/internet/kcp"
 	"v2ray.com/core/transport/internet/tcp"
 	"v2ray.com/core/transport/internet/tcp"
 	"v2ray.com/core/transport/internet/ws"
 	"v2ray.com/core/transport/internet/ws"
-
-	"github.com/golang/protobuf/ptypes"
 )
 )
 
 
 func (this *Config) UnmarshalJSON(data []byte) error {
 func (this *Config) UnmarshalJSON(data []byte) error {
@@ -26,35 +25,23 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 	}
 	}
 
 
 	if jsonConfig.TCPConfig != nil {
 	if jsonConfig.TCPConfig != nil {
-		any, err := ptypes.MarshalAny(jsonConfig.TCPConfig)
-		if err != nil {
-			return err
-		}
 		this.NetworkSettings = append(this.NetworkSettings, &internet.NetworkSettings{
 		this.NetworkSettings = append(this.NetworkSettings, &internet.NetworkSettings{
 			Network:  v2net.Network_TCP,
 			Network:  v2net.Network_TCP,
-			Settings: any,
+			Settings: loader.NewTypedSettings(jsonConfig.TCPConfig),
 		})
 		})
 	}
 	}
 
 
 	if jsonConfig.KCPConfig != nil {
 	if jsonConfig.KCPConfig != nil {
-		any, err := ptypes.MarshalAny(jsonConfig.KCPConfig)
-		if err != nil {
-			return err
-		}
 		this.NetworkSettings = append(this.NetworkSettings, &internet.NetworkSettings{
 		this.NetworkSettings = append(this.NetworkSettings, &internet.NetworkSettings{
 			Network:  v2net.Network_KCP,
 			Network:  v2net.Network_KCP,
-			Settings: any,
+			Settings: loader.NewTypedSettings(jsonConfig.KCPConfig),
 		})
 		})
 	}
 	}
 
 
 	if jsonConfig.WSConfig != nil {
 	if jsonConfig.WSConfig != nil {
-		any, err := ptypes.MarshalAny(jsonConfig.WSConfig)
-		if err != nil {
-			return err
-		}
 		this.NetworkSettings = append(this.NetworkSettings, &internet.NetworkSettings{
 		this.NetworkSettings = append(this.NetworkSettings, &internet.NetworkSettings{
 			Network:  v2net.Network_WebSocket,
 			Network:  v2net.Network_WebSocket,
-			Settings: any,
+			Settings: loader.NewTypedSettings(jsonConfig.WSConfig),
 		})
 		})
 	}
 	}
 	return nil
 	return nil

+ 0 - 43
transport/internet/authenticator.go

@@ -1,14 +1,9 @@
 package internet
 package internet
 
 
 import (
 import (
-	"errors"
-
 	"v2ray.com/core/common"
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/loader"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/ptypes"
 )
 )
 
 
 type Authenticator interface {
 type Authenticator interface {
@@ -21,40 +16,6 @@ type AuthenticatorFactory interface {
 	Create(interface{}) Authenticator
 	Create(interface{}) Authenticator
 }
 }
 
 
-func (this *AuthenticatorConfig) GetInternalConfig() (interface{}, error) {
-	config, err := configCache.CreateConfig(this.Name)
-	if err != nil {
-		return nil, err
-	}
-	if err := ptypes.UnmarshalAny(this.Settings, config.(proto.Message)); err != nil {
-		return nil, err
-	}
-	return config, nil
-}
-
-func NewAuthenticatorConfig(name string, config interface{}) (*AuthenticatorConfig, error) {
-	pbMsg, ok := config.(proto.Message)
-	if !ok {
-		return nil, errors.New("Internet|Authenticator: Failed to convert config into proto message.")
-	}
-	anyConfig, err := ptypes.MarshalAny(pbMsg)
-	if err != nil {
-		return nil, err
-	}
-	return &AuthenticatorConfig{
-		Name:     name,
-		Settings: anyConfig,
-	}, nil
-}
-
-func (this *AuthenticatorConfig) CreateAuthenticator() (Authenticator, error) {
-	config, err := this.GetInternalConfig()
-	if err != nil {
-		return nil, err
-	}
-	return CreateAuthenticator(this.Name, config)
-}
-
 var (
 var (
 	authenticatorCache = make(map[string]AuthenticatorFactory)
 	authenticatorCache = make(map[string]AuthenticatorFactory)
 	configCache        = loader.ConfigCreatorCache{}
 	configCache        = loader.ConfigCreatorCache{}
@@ -68,10 +29,6 @@ func RegisterAuthenticator(name string, factory AuthenticatorFactory) error {
 	return nil
 	return nil
 }
 }
 
 
-func RegisterAuthenticatorConfig(name string, configCreator loader.ConfigCreator) error {
-	return configCache.RegisterCreator(name, configCreator)
-}
-
 func CreateAuthenticator(name string, config interface{}) (Authenticator, error) {
 func CreateAuthenticator(name string, config interface{}) (Authenticator, error) {
 	factory, found := authenticatorCache[name]
 	factory, found := authenticatorCache[name]
 	if !found {
 	if !found {

+ 18 - 19
transport/internet/authenticator.pb.go

@@ -11,7 +11,6 @@ It is generated from these files:
 
 
 It has these top-level messages:
 It has these top-level messages:
 	AuthenticatorConfig
 	AuthenticatorConfig
-	SecuritySettings
 	NetworkSettings
 	NetworkSettings
 	StreamConfig
 	StreamConfig
 */
 */
@@ -20,7 +19,7 @@ package internet
 import proto "github.com/golang/protobuf/proto"
 import proto "github.com/golang/protobuf/proto"
 import fmt "fmt"
 import fmt "fmt"
 import math "math"
 import math "math"
-import google_protobuf "github.com/golang/protobuf/ptypes/any"
+import v2ray_core_common_loader "v2ray.com/core/common/loader"
 
 
 // Reference imports to suppress errors if they are not otherwise used.
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
 var _ = proto.Marshal
@@ -34,8 +33,8 @@ var _ = math.Inf
 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 
 
 type AuthenticatorConfig struct {
 type AuthenticatorConfig struct {
-	Name     string               `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
-	Settings *google_protobuf.Any `protobuf:"bytes,2,opt,name=settings" json:"settings,omitempty"`
+	Name     string                                  `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	Settings *v2ray_core_common_loader.TypedSettings `protobuf:"bytes,2,opt,name=settings" json:"settings,omitempty"`
 }
 }
 
 
 func (m *AuthenticatorConfig) Reset()                    { *m = AuthenticatorConfig{} }
 func (m *AuthenticatorConfig) Reset()                    { *m = AuthenticatorConfig{} }
@@ -43,7 +42,7 @@ func (m *AuthenticatorConfig) String() string            { return proto.CompactT
 func (*AuthenticatorConfig) ProtoMessage()               {}
 func (*AuthenticatorConfig) ProtoMessage()               {}
 func (*AuthenticatorConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
 func (*AuthenticatorConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
 
 
-func (m *AuthenticatorConfig) GetSettings() *google_protobuf.Any {
+func (m *AuthenticatorConfig) GetSettings() *v2ray_core_common_loader.TypedSettings {
 	if m != nil {
 	if m != nil {
 		return m.Settings
 		return m.Settings
 	}
 	}
@@ -59,18 +58,18 @@ func init() {
 }
 }
 
 
 var fileDescriptor0 = []byte{
 var fileDescriptor0 = []byte{
-	// 197 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x8e, 0xc1, 0x4a, 0xc4, 0x40,
-	0x0c, 0x40, 0xa9, 0x88, 0xac, 0xe3, 0x6d, 0xf4, 0xb0, 0x0a, 0xc2, 0xea, 0x69, 0x4f, 0x19, 0xa9,
-	0xf8, 0x01, 0xad, 0x3f, 0x20, 0x3d, 0xea, 0x69, 0x3a, 0xa4, 0xe3, 0x80, 0x4d, 0x4a, 0x9a, 0x0a,
-	0xfd, 0x7b, 0xb1, 0x65, 0x8a, 0x5e, 0xf6, 0x16, 0xc8, 0x7b, 0x2f, 0x31, 0x2f, 0xdf, 0xa5, 0xf8,
-	0x19, 0x02, 0xf7, 0x2e, 0xb0, 0xa0, 0x53, 0xf1, 0x34, 0x0e, 0x2c, 0xea, 0x12, 0x29, 0x0a, 0xa1,
-	0x3a, 0x3f, 0xe9, 0x27, 0x92, 0xa6, 0xe0, 0x95, 0x05, 0x06, 0x61, 0x65, 0x7b, 0x9f, 0x35, 0x41,
-	0xd8, 0x14, 0xc8, 0xca, 0xdd, 0x6d, 0x64, 0x8e, 0x5f, 0xe8, 0x16, 0xb8, 0x9d, 0x3a, 0xe7, 0x69,
-	0x5e, 0xcd, 0xc7, 0x0f, 0x73, 0x5d, 0xfd, 0x0d, 0xbe, 0x32, 0x75, 0x29, 0x5a, 0x6b, 0xce, 0xc9,
-	0xf7, 0xb8, 0x2f, 0x0e, 0xc5, 0xf1, 0xb2, 0x59, 0x66, 0xfb, 0x64, 0x76, 0x23, 0xaa, 0x26, 0x8a,
-	0xe3, 0xfe, 0xec, 0x50, 0x1c, 0xaf, 0xca, 0x1b, 0x58, 0xc3, 0x90, 0xc3, 0x50, 0xd1, 0xdc, 0x6c,
-	0x54, 0x5d, 0x99, 0x87, 0xc0, 0x3d, 0x9c, 0x7c, 0xae, 0xb6, 0xff, 0xee, 0xbf, 0xfd, 0x96, 0xde,
-	0x77, 0x79, 0xdb, 0x5e, 0x2c, 0xe9, 0xe7, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x59, 0x3f, 0x6f,
-	0x4b, 0x19, 0x01, 0x00, 0x00,
+	// 207 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x8e, 0xc1, 0x4a, 0xc4, 0x30,
+	0x10, 0x86, 0xa9, 0x88, 0xac, 0xf1, 0x16, 0x2f, 0x8b, 0x20, 0xac, 0x5e, 0x76, 0x4f, 0x13, 0x58,
+	0xf1, 0x01, 0xda, 0xbe, 0x80, 0x54, 0x4f, 0xde, 0x62, 0x3a, 0xd6, 0x80, 0x99, 0x09, 0xd3, 0x51,
+	0xe8, 0xdb, 0x8b, 0xad, 0x2d, 0xd5, 0x83, 0xb7, 0x40, 0xe6, 0xfb, 0xfe, 0xcf, 0xdc, 0x7f, 0x1e,
+	0xc5, 0x0f, 0x10, 0x38, 0xb9, 0xc0, 0x82, 0x4e, 0xc5, 0x53, 0x9f, 0x59, 0xd4, 0x45, 0x52, 0x14,
+	0x42, 0x75, 0xfe, 0x43, 0xdf, 0x90, 0x34, 0x06, 0xaf, 0x2c, 0x90, 0x85, 0x95, 0xed, 0xf5, 0x8c,
+	0x09, 0xc2, 0x82, 0xc0, 0x8c, 0x5c, 0xed, 0xff, 0x58, 0x03, 0xa7, 0xc4, 0xe4, 0xde, 0xd9, 0xb7,
+	0x28, 0x4e, 0x87, 0x8c, 0x93, 0xe7, 0x96, 0xcc, 0x65, 0xb9, 0xd6, 0xd7, 0x4c, 0xaf, 0xb1, 0xb3,
+	0xd6, 0x9c, 0x92, 0x4f, 0xb8, 0x2d, 0x76, 0xc5, 0xe1, 0xbc, 0x19, 0xdf, 0xb6, 0x36, 0x9b, 0x1e,
+	0x55, 0x23, 0x75, 0xfd, 0xf6, 0x64, 0x57, 0x1c, 0x2e, 0x8e, 0x7b, 0x58, 0x55, 0x4c, 0x13, 0x30,
+	0x4d, 0xc0, 0xd3, 0x90, 0xb1, 0x7d, 0xfc, 0x39, 0x6f, 0x16, 0xb0, 0x2a, 0xcd, 0x4d, 0xe0, 0x04,
+	0xff, 0xd6, 0x57, 0xf6, 0x57, 0xd2, 0xc3, 0x77, 0xe8, 0xf3, 0x66, 0xfe, 0x7d, 0x39, 0x1b, 0xcb,
+	0xef, 0xbe, 0x02, 0x00, 0x00, 0xff, 0xff, 0x86, 0xf6, 0xf6, 0xdf, 0x3a, 0x01, 0x00, 0x00,
 }
 }

+ 2 - 2
transport/internet/authenticator.proto

@@ -5,9 +5,9 @@ option go_package = "internet";
 option java_package = "com.v2ray.core.transport.internet";
 option java_package = "com.v2ray.core.transport.internet";
 option java_outer_classname = "AuthenticatorProto";
 option java_outer_classname = "AuthenticatorProto";
 
 
-import "google/protobuf/any.proto";
+import "v2ray.com/core/common/loader/type.proto";
 
 
 message AuthenticatorConfig {
 message AuthenticatorConfig {
   string name = 1;
   string name = 1;
-  google.protobuf.Any settings = 2;
+  v2ray.core.common.loader.TypedSettings settings = 2;
 }
 }

+ 0 - 23
transport/internet/authenticator_json.go

@@ -1,23 +0,0 @@
-// +build json
-
-package internet
-
-import (
-	"v2ray.com/core/common/loader"
-)
-
-func CreateAuthenticatorConfig(rawConfig []byte) (string, interface{}, error) {
-	config, name, err := configLoader.Load(rawConfig)
-	if err != nil {
-		return name, nil, err
-	}
-	return name, config, nil
-}
-
-var (
-	configLoader loader.ConfigLoader
-)
-
-func init() {
-	configLoader = loader.NewJSONConfigLoader(configCache, "type", "")
-}

+ 2 - 2
transport/internet/authenticators/noop/noop.go

@@ -2,6 +2,7 @@ package noop
 
 
 import (
 import (
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/alloc"
+	"v2ray.com/core/common/loader"
 	"v2ray.com/core/transport/internet"
 	"v2ray.com/core/transport/internet"
 )
 )
 
 
@@ -22,6 +23,5 @@ func (this NoOpAuthenticatorFactory) Create(config interface{}) internet.Authent
 }
 }
 
 
 func init() {
 func init() {
-	internet.RegisterAuthenticator("none", NoOpAuthenticatorFactory{})
-	internet.RegisterAuthenticatorConfig("none", func() interface{} { return &Config{} })
+	internet.RegisterAuthenticator(loader.GetType(new(Config)), NoOpAuthenticatorFactory{})
 }
 }

+ 2 - 2
transport/internet/authenticators/srtp/srtp.go

@@ -4,6 +4,7 @@ import (
 	"math/rand"
 	"math/rand"
 
 
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/alloc"
+	"v2ray.com/core/common/loader"
 	"v2ray.com/core/transport/internet"
 	"v2ray.com/core/transport/internet"
 )
 )
 
 
@@ -38,6 +39,5 @@ func (this SRTPFactory) Create(rawSettings interface{}) internet.Authenticator {
 }
 }
 
 
 func init() {
 func init() {
-	internet.RegisterAuthenticator("srtp", SRTPFactory{})
-	internet.RegisterAuthenticatorConfig("srtp", func() interface{} { return &Config{} })
+	internet.RegisterAuthenticator(loader.GetType(new(Config)), SRTPFactory{})
 }
 }

+ 2 - 2
transport/internet/authenticators/utp/utp.go

@@ -4,6 +4,7 @@ import (
 	"math/rand"
 	"math/rand"
 
 
 	"v2ray.com/core/common/alloc"
 	"v2ray.com/core/common/alloc"
+	"v2ray.com/core/common/loader"
 	"v2ray.com/core/transport/internet"
 	"v2ray.com/core/transport/internet"
 )
 )
 
 
@@ -38,6 +39,5 @@ func (this UTPFactory) Create(rawSettings interface{}) internet.Authenticator {
 }
 }
 
 
 func init() {
 func init() {
-	internet.RegisterAuthenticator("utp", UTPFactory{})
-	internet.RegisterAuthenticatorConfig("utp", func() interface{} { return &Config{} })
+	internet.RegisterAuthenticator(loader.GetType(new(Config)), UTPFactory{})
 }
 }

+ 11 - 51
transport/internet/config.go

@@ -3,32 +3,26 @@ package internet
 import (
 import (
 	"errors"
 	"errors"
 
 
+	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
-	v2tls "v2ray.com/core/transport/internet/tls"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/ptypes"
 )
 )
 
 
-type NetworkConfigCreator func() proto.Message
-
 var (
 var (
-	globalNetworkConfigCreatorCache  = make(map[v2net.Network]NetworkConfigCreator)
-	globalSecurityConfigCreatorCache = make(map[SecurityType]NetworkConfigCreator)
+	globalNetworkConfigCreatorCache = make(map[v2net.Network]loader.ConfigCreator)
 
 
 	globalNetworkSettings []*NetworkSettings
 	globalNetworkSettings []*NetworkSettings
 
 
 	ErrUnconfiguredNetwork = errors.New("Network config creator not set.")
 	ErrUnconfiguredNetwork = errors.New("Network config creator not set.")
 )
 )
 
 
-func RegisterNetworkConfigCreator(network v2net.Network, creator NetworkConfigCreator) error {
+func RegisterNetworkConfigCreator(network v2net.Network, creator loader.ConfigCreator) error {
 	// TODO: check duplicate
 	// TODO: check duplicate
 	globalNetworkConfigCreatorCache[network] = creator
 	globalNetworkConfigCreatorCache[network] = creator
 	return nil
 	return nil
 }
 }
 
 
-func CreateNetworkConfig(network v2net.Network) (proto.Message, error) {
+func CreateNetworkConfig(network v2net.Network) (interface{}, error) {
 	creator, ok := globalNetworkConfigCreatorCache[network]
 	creator, ok := globalNetworkConfigCreatorCache[network]
 	if !ok {
 	if !ok {
 		log.Warning("Internet: Network config creator not found: ", network)
 		log.Warning("Internet: Network config creator not found: ", network)
@@ -37,40 +31,8 @@ func CreateNetworkConfig(network v2net.Network) (proto.Message, error) {
 	return creator(), nil
 	return creator(), nil
 }
 }
 
 
-func RegisterSecurityConfigCreator(securityType SecurityType, creator NetworkConfigCreator) error {
-	globalSecurityConfigCreatorCache[securityType] = creator
-	return nil
-}
-
-func CreateSecurityConfig(securityType SecurityType) (proto.Message, error) {
-	creator, ok := globalSecurityConfigCreatorCache[securityType]
-	if !ok {
-		log.Warning("Internet: Security config creator not found: ", securityType)
-		return nil, ErrUnconfiguredNetwork
-	}
-	return creator(), nil
-}
-
 func (this *NetworkSettings) GetTypedSettings() (interface{}, error) {
 func (this *NetworkSettings) GetTypedSettings() (interface{}, error) {
-	message, err := CreateNetworkConfig(this.Network)
-	if err != nil {
-		return nil, err
-	}
-	if err := ptypes.UnmarshalAny(this.Settings, message); err != nil {
-		return nil, err
-	}
-	return message, nil
-}
-
-func (this *SecuritySettings) GetTypeSettings() (interface{}, error) {
-	message, err := CreateSecurityConfig(this.Type)
-	if err != nil {
-		return nil, err
-	}
-	if err := ptypes.UnmarshalAny(this.Settings, message); err != nil {
-		return nil, err
-	}
-	return message, nil
+	return this.Settings.GetInstance()
 }
 }
 
 
 func (this *StreamConfig) GetEffectiveNetworkSettings() (interface{}, error) {
 func (this *StreamConfig) GetEffectiveNetworkSettings() (interface{}, error) {
@@ -90,19 +52,17 @@ func (this *StreamConfig) GetEffectiveNetworkSettings() (interface{}, error) {
 func (this *StreamConfig) GetEffectiveSecuritySettings() (interface{}, error) {
 func (this *StreamConfig) GetEffectiveSecuritySettings() (interface{}, error) {
 	for _, settings := range this.SecuritySettings {
 	for _, settings := range this.SecuritySettings {
 		if settings.Type == this.SecurityType {
 		if settings.Type == this.SecurityType {
-			return settings.GetTypeSettings()
+			return settings.GetInstance()
 		}
 		}
 	}
 	}
-	return CreateSecurityConfig(this.SecurityType)
+	return loader.GetInstance(this.SecurityType)
+}
+
+func (this *StreamConfig) HasSecuritySettings() bool {
+	return len(this.SecurityType) > 0
 }
 }
 
 
 func ApplyGlobalNetworkSettings(settings []*NetworkSettings) error {
 func ApplyGlobalNetworkSettings(settings []*NetworkSettings) error {
 	globalNetworkSettings = settings
 	globalNetworkSettings = settings
 	return nil
 	return nil
 }
 }
-
-func init() {
-	RegisterSecurityConfigCreator(SecurityType_TLS, func() proto.Message {
-		return new(v2tls.Config)
-	})
-}

+ 30 - 73
transport/internet/config.pb.go

@@ -8,62 +8,24 @@ import proto "github.com/golang/protobuf/proto"
 import fmt "fmt"
 import fmt "fmt"
 import math "math"
 import math "math"
 import v2ray_core_common_net "v2ray.com/core/common/net"
 import v2ray_core_common_net "v2ray.com/core/common/net"
-import google_protobuf "github.com/golang/protobuf/ptypes/any"
+import v2ray_core_common_loader "v2ray.com/core/common/loader"
 
 
 // Reference imports to suppress errors if they are not otherwise used.
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
 var _ = proto.Marshal
 var _ = fmt.Errorf
 var _ = fmt.Errorf
 var _ = math.Inf
 var _ = math.Inf
 
 
-type SecurityType int32
-
-const (
-	SecurityType_None SecurityType = 0
-	SecurityType_TLS  SecurityType = 1
-)
-
-var SecurityType_name = map[int32]string{
-	0: "None",
-	1: "TLS",
-}
-var SecurityType_value = map[string]int32{
-	"None": 0,
-	"TLS":  1,
-}
-
-func (x SecurityType) String() string {
-	return proto.EnumName(SecurityType_name, int32(x))
-}
-func (SecurityType) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
-
-type SecuritySettings struct {
-	Type     SecurityType         `protobuf:"varint,1,opt,name=type,enum=v2ray.core.transport.internet.SecurityType" json:"type,omitempty"`
-	Settings *google_protobuf.Any `protobuf:"bytes,2,opt,name=settings" json:"settings,omitempty"`
-}
-
-func (m *SecuritySettings) Reset()                    { *m = SecuritySettings{} }
-func (m *SecuritySettings) String() string            { return proto.CompactTextString(m) }
-func (*SecuritySettings) ProtoMessage()               {}
-func (*SecuritySettings) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
-
-func (m *SecuritySettings) GetSettings() *google_protobuf.Any {
-	if m != nil {
-		return m.Settings
-	}
-	return nil
-}
-
 type NetworkSettings struct {
 type NetworkSettings struct {
-	Network  v2ray_core_common_net.Network `protobuf:"varint,1,opt,name=network,enum=v2ray.core.common.net.Network" json:"network,omitempty"`
-	Settings *google_protobuf.Any          `protobuf:"bytes,2,opt,name=settings" json:"settings,omitempty"`
+	Network  v2ray_core_common_net.Network           `protobuf:"varint,1,opt,name=network,enum=v2ray.core.common.net.Network" json:"network,omitempty"`
+	Settings *v2ray_core_common_loader.TypedSettings `protobuf:"bytes,2,opt,name=settings" json:"settings,omitempty"`
 }
 }
 
 
 func (m *NetworkSettings) Reset()                    { *m = NetworkSettings{} }
 func (m *NetworkSettings) Reset()                    { *m = NetworkSettings{} }
 func (m *NetworkSettings) String() string            { return proto.CompactTextString(m) }
 func (m *NetworkSettings) String() string            { return proto.CompactTextString(m) }
 func (*NetworkSettings) ProtoMessage()               {}
 func (*NetworkSettings) ProtoMessage()               {}
-func (*NetworkSettings) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} }
+func (*NetworkSettings) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
 
 
-func (m *NetworkSettings) GetSettings() *google_protobuf.Any {
+func (m *NetworkSettings) GetSettings() *v2ray_core_common_loader.TypedSettings {
 	if m != nil {
 	if m != nil {
 		return m.Settings
 		return m.Settings
 	}
 	}
@@ -71,16 +33,16 @@ func (m *NetworkSettings) GetSettings() *google_protobuf.Any {
 }
 }
 
 
 type StreamConfig struct {
 type StreamConfig struct {
-	Network          v2ray_core_common_net.Network `protobuf:"varint,1,opt,name=network,enum=v2ray.core.common.net.Network" json:"network,omitempty"`
-	NetworkSettings  []*NetworkSettings            `protobuf:"bytes,2,rep,name=network_settings,json=networkSettings" json:"network_settings,omitempty"`
-	SecurityType     SecurityType                  `protobuf:"varint,3,opt,name=security_type,json=securityType,enum=v2ray.core.transport.internet.SecurityType" json:"security_type,omitempty"`
-	SecuritySettings []*SecuritySettings           `protobuf:"bytes,4,rep,name=security_settings,json=securitySettings" json:"security_settings,omitempty"`
+	Network          v2ray_core_common_net.Network             `protobuf:"varint,1,opt,name=network,enum=v2ray.core.common.net.Network" json:"network,omitempty"`
+	NetworkSettings  []*NetworkSettings                        `protobuf:"bytes,2,rep,name=network_settings,json=networkSettings" json:"network_settings,omitempty"`
+	SecurityType     string                                    `protobuf:"bytes,3,opt,name=security_type,json=securityType" json:"security_type,omitempty"`
+	SecuritySettings []*v2ray_core_common_loader.TypedSettings `protobuf:"bytes,4,rep,name=security_settings,json=securitySettings" json:"security_settings,omitempty"`
 }
 }
 
 
 func (m *StreamConfig) Reset()                    { *m = StreamConfig{} }
 func (m *StreamConfig) Reset()                    { *m = StreamConfig{} }
 func (m *StreamConfig) String() string            { return proto.CompactTextString(m) }
 func (m *StreamConfig) String() string            { return proto.CompactTextString(m) }
 func (*StreamConfig) ProtoMessage()               {}
 func (*StreamConfig) ProtoMessage()               {}
-func (*StreamConfig) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2} }
+func (*StreamConfig) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} }
 
 
 func (m *StreamConfig) GetNetworkSettings() []*NetworkSettings {
 func (m *StreamConfig) GetNetworkSettings() []*NetworkSettings {
 	if m != nil {
 	if m != nil {
@@ -89,7 +51,7 @@ func (m *StreamConfig) GetNetworkSettings() []*NetworkSettings {
 	return nil
 	return nil
 }
 }
 
 
-func (m *StreamConfig) GetSecuritySettings() []*SecuritySettings {
+func (m *StreamConfig) GetSecuritySettings() []*v2ray_core_common_loader.TypedSettings {
 	if m != nil {
 	if m != nil {
 		return m.SecuritySettings
 		return m.SecuritySettings
 	}
 	}
@@ -97,36 +59,31 @@ func (m *StreamConfig) GetSecuritySettings() []*SecuritySettings {
 }
 }
 
 
 func init() {
 func init() {
-	proto.RegisterType((*SecuritySettings)(nil), "v2ray.core.transport.internet.SecuritySettings")
 	proto.RegisterType((*NetworkSettings)(nil), "v2ray.core.transport.internet.NetworkSettings")
 	proto.RegisterType((*NetworkSettings)(nil), "v2ray.core.transport.internet.NetworkSettings")
 	proto.RegisterType((*StreamConfig)(nil), "v2ray.core.transport.internet.StreamConfig")
 	proto.RegisterType((*StreamConfig)(nil), "v2ray.core.transport.internet.StreamConfig")
-	proto.RegisterEnum("v2ray.core.transport.internet.SecurityType", SecurityType_name, SecurityType_value)
 }
 }
 
 
 func init() { proto.RegisterFile("v2ray.com/core/transport/internet/config.proto", fileDescriptor1) }
 func init() { proto.RegisterFile("v2ray.com/core/transport/internet/config.proto", fileDescriptor1) }
 
 
 var fileDescriptor1 = []byte{
 var fileDescriptor1 = []byte{
-	// 347 bytes of a gzipped FileDescriptorProto
+	// 296 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x91, 0x4f, 0x4b, 0xc3, 0x40,
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x91, 0x4f, 0x4b, 0xc3, 0x40,
-	0x10, 0xc5, 0x4d, 0x5b, 0x6c, 0x99, 0x56, 0x1b, 0x83, 0x87, 0x5a, 0x50, 0xda, 0x5e, 0x0c, 0x8a,
-	0xbb, 0x12, 0x2f, 0xde, 0x44, 0xbd, 0x4a, 0x91, 0xa4, 0x17, 0x45, 0x28, 0x69, 0x98, 0x86, 0xa0,
-	0xd9, 0x09, 0x9b, 0xad, 0x92, 0x83, 0x47, 0x3f, 0xa1, 0x5f, 0x48, 0x9a, 0x7f, 0x84, 0x1c, 0xea,
-	0xbf, 0xdb, 0x6e, 0xf2, 0xe6, 0xcd, 0x6f, 0xdf, 0x03, 0xf6, 0x6a, 0x49, 0x37, 0x61, 0x1e, 0x85,
-	0xdc, 0x23, 0x89, 0x5c, 0x49, 0x57, 0xc4, 0x11, 0x49, 0xc5, 0x03, 0xa1, 0x50, 0x0a, 0x54, 0xdc,
-	0x23, 0xb1, 0x0c, 0x7c, 0x16, 0x49, 0x52, 0x64, 0x1c, 0x16, 0x7a, 0x89, 0xac, 0xd4, 0xb2, 0x42,
-	0x3b, 0x3c, 0xae, 0xd9, 0x79, 0x14, 0x86, 0x24, 0xf8, 0xda, 0x46, 0xa0, 0x7a, 0x23, 0xf9, 0x9c,
-	0xf9, 0x0c, 0x0f, 0x7c, 0x22, 0xff, 0x05, 0x79, 0x7a, 0x5b, 0xac, 0x96, 0xdc, 0x15, 0x49, 0xf6,
-	0x6b, 0xf2, 0xa1, 0x81, 0xee, 0xa0, 0xb7, 0x92, 0x81, 0x4a, 0x1c, 0x54, 0x2a, 0x10, 0x7e, 0x6c,
-	0x5c, 0x41, 0x4b, 0x25, 0x11, 0x0e, 0xb4, 0x91, 0x66, 0xee, 0x5a, 0xa7, 0x6c, 0x23, 0x06, 0x2b,
-	0xc6, 0x67, 0x49, 0x84, 0x76, 0x3a, 0x68, 0x9c, 0x43, 0x27, 0xce, 0xcd, 0x06, 0x8d, 0x91, 0x66,
-	0x76, 0xad, 0x7d, 0x96, 0x31, 0xb0, 0x82, 0x81, 0x5d, 0x8b, 0xc4, 0x2e, 0x55, 0x93, 0x77, 0xe8,
-	0x4f, 0x33, 0xe6, 0x92, 0xe2, 0x12, 0xda, 0xf9, 0x33, 0x72, 0x90, 0xa3, 0x2a, 0x48, 0xf6, 0x58,
-	0xb6, 0x06, 0xc8, 0x07, 0xed, 0x42, 0xfe, 0x87, 0xf5, 0x9f, 0x0d, 0xe8, 0x39, 0x4a, 0xa2, 0x1b,
-	0xde, 0xa6, 0x05, 0xfc, 0x63, 0xf9, 0x03, 0xe8, 0xf9, 0x71, 0x5e, 0x81, 0x68, 0x9a, 0x5d, 0x8b,
-	0x7d, 0x13, 0x64, 0x2d, 0x00, 0xbb, 0x2f, 0x6a, 0x89, 0xdc, 0xc3, 0x4e, 0x9c, 0x87, 0x3d, 0x4f,
-	0x0b, 0x6a, 0xfe, 0xbe, 0xa0, 0x5e, 0x5c, 0xb9, 0x19, 0x4f, 0xb0, 0x57, 0x3a, 0x96, 0xb4, 0xad,
-	0x94, 0x96, 0xff, 0xd0, 0xb5, 0xc4, 0xd5, 0xe3, 0xda, 0x97, 0x93, 0x31, 0xf4, 0xaa, 0xbb, 0x8d,
-	0x0e, 0xb4, 0xa6, 0x24, 0x50, 0xdf, 0x32, 0xda, 0xd0, 0x9c, 0xdd, 0x39, 0xba, 0x76, 0x73, 0x06,
-	0x63, 0x8f, 0xc2, 0xcd, 0xab, 0x1e, 0x3b, 0xc5, 0x69, 0xb1, 0x9d, 0xf6, 0x77, 0xf1, 0x15, 0x00,
-	0x00, 0xff, 0xff, 0xb2, 0x2e, 0x36, 0x52, 0x4a, 0x03, 0x00, 0x00,
+	0x10, 0xc5, 0x49, 0x2b, 0x5a, 0xb7, 0xd5, 0xd6, 0x9c, 0x82, 0xa0, 0xc4, 0x7a, 0x68, 0x2e, 0xce,
+	0x42, 0xbc, 0x78, 0xb6, 0x77, 0x0f, 0x69, 0x2f, 0x7a, 0x29, 0x71, 0x3b, 0x96, 0xa0, 0xd9, 0x0d,
+	0x93, 0x51, 0xc9, 0xb7, 0xf0, 0x13, 0xf8, 0x59, 0x25, 0x7f, 0x36, 0x94, 0xa0, 0x45, 0xe8, 0x6d,
+	0x18, 0xde, 0xfb, 0xed, 0x9b, 0xb7, 0x02, 0x3e, 0x42, 0x8a, 0x0b, 0x50, 0x26, 0x95, 0xca, 0x10,
+	0x4a, 0xa6, 0x58, 0xe7, 0x99, 0x21, 0x96, 0x89, 0x66, 0x24, 0x8d, 0x2c, 0x95, 0xd1, 0x2f, 0xc9,
+	0x06, 0x32, 0x32, 0x6c, 0xdc, 0x0b, 0xab, 0x27, 0x84, 0x56, 0x0b, 0x56, 0x7b, 0x3e, 0xeb, 0xe0,
+	0x94, 0x49, 0x53, 0xa3, 0x65, 0x89, 0xd1, 0xc8, 0x9f, 0x86, 0x5e, 0x6b, 0xce, 0x5f, 0xc2, 0x37,
+	0x13, 0xaf, 0x91, 0x24, 0x17, 0x19, 0xd6, 0xc2, 0xe9, 0x97, 0x23, 0xc6, 0x0f, 0xb5, 0x75, 0x81,
+	0xcc, 0x89, 0xde, 0xe4, 0xee, 0x9d, 0x38, 0x6a, 0x68, 0x9e, 0xe3, 0x3b, 0xc1, 0x69, 0x78, 0x09,
+	0x5b, 0xb1, 0x6a, 0x14, 0x68, 0x64, 0x68, 0x8c, 0x91, 0x95, 0xbb, 0x73, 0x31, 0xc8, 0x1b, 0x8a,
+	0xd7, 0xf3, 0x9d, 0x60, 0x18, 0xce, 0x7e, 0xb1, 0xd6, 0x29, 0x60, 0x59, 0x64, 0xb8, 0xb6, 0x8f,
+	0x46, 0xad, 0x71, 0xfa, 0xdd, 0x13, 0xa3, 0x05, 0x13, 0xc6, 0xe9, 0xbc, 0xaa, 0x66, 0x8f, 0x3c,
+	0x8f, 0x62, 0xd2, 0x8c, 0xab, 0xad, 0x5c, 0xfd, 0x60, 0x18, 0x02, 0xec, 0x6c, 0x1a, 0x3a, 0x9d,
+	0x44, 0x63, 0xdd, 0x29, 0xe9, 0x5a, 0x9c, 0xe4, 0xa8, 0xde, 0x29, 0xe1, 0x62, 0x55, 0xf6, 0xe9,
+	0xf5, 0x7d, 0x27, 0x38, 0x8e, 0x46, 0x76, 0x59, 0x5e, 0xe7, 0x2e, 0xc5, 0x59, 0x2b, 0x6a, 0x03,
+	0x1c, 0x54, 0x01, 0xfe, 0x5d, 0xcc, 0xc4, 0x12, 0xec, 0xe6, 0xfe, 0x46, 0x5c, 0x29, 0x93, 0xee,
+	0x3e, 0xe0, 0x69, 0x60, 0xa7, 0xe7, 0xc3, 0xea, 0xa7, 0x6f, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff,
+	0xf6, 0x3d, 0x07, 0x73, 0x8c, 0x02, 0x00, 0x00,
 }
 }

+ 4 - 15
transport/internet/config.proto

@@ -5,27 +5,16 @@ option go_package = "internet";
 option java_package = "com.v2ray.core.transport.internet";
 option java_package = "com.v2ray.core.transport.internet";
 
 
 import "v2ray.com/core/common/net/network.proto";
 import "v2ray.com/core/common/net/network.proto";
-
-import "google/protobuf/any.proto";
-
-enum SecurityType {
-  None = 0;
-  TLS = 1;
-}
-
-message SecuritySettings {
-  SecurityType type = 1;
-  google.protobuf.Any settings = 2;
-}
+import "v2ray.com/core/common/loader/type.proto";
 
 
 message NetworkSettings {
 message NetworkSettings {
   v2ray.core.common.net.Network network = 1;
   v2ray.core.common.net.Network network = 1;
-  google.protobuf.Any settings = 2;
+  v2ray.core.common.loader.TypedSettings settings = 2;
 }
 }
 
 
 message StreamConfig {
 message StreamConfig {
   v2ray.core.common.net.Network network = 1;
   v2ray.core.common.net.Network network = 1;
   repeated NetworkSettings network_settings = 2;
   repeated NetworkSettings network_settings = 2;
-  SecurityType security_type = 3;
-  repeated SecuritySettings security_settings = 4;
+  string security_type = 3;
+  repeated v2ray.core.common.loader.TypedSettings security_settings = 4;
 }
 }

+ 5 - 13
transport/internet/connection_json.go

@@ -6,8 +6,7 @@ import (
 	"encoding/json"
 	"encoding/json"
 	"strings"
 	"strings"
 
 
-	"errors"
-	"github.com/golang/protobuf/ptypes"
+	"v2ray.com/core/common/loader"
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	v2tls "v2ray.com/core/transport/internet/tls"
 	v2tls "v2ray.com/core/transport/internet/tls"
 )
 )
@@ -26,19 +25,12 @@ func (this *StreamConfig) UnmarshalJSON(data []byte) error {
 	if jsonConfig.Network != nil {
 	if jsonConfig.Network != nil {
 		this.Network = *jsonConfig.Network
 		this.Network = *jsonConfig.Network
 	}
 	}
-	this.SecurityType = SecurityType_None
 	if strings.ToLower(jsonConfig.Security) == "tls" {
 	if strings.ToLower(jsonConfig.Security) == "tls" {
-		this.SecurityType = SecurityType_TLS
-	}
-	if jsonConfig.TLSSettings != nil {
-		anyTLSSettings, err := ptypes.MarshalAny(jsonConfig.TLSSettings)
-		if err != nil {
-			return errors.New("Internet: Failed to parse TLS settings: " + err.Error())
+		tlsSettings := jsonConfig.TLSSettings
+		if tlsSettings == nil {
+			tlsSettings = &v2tls.Config{}
 		}
 		}
-		this.SecuritySettings = append(this.SecuritySettings, &SecuritySettings{
-			Type:     SecurityType_TLS,
-			Settings: anyTLSSettings,
-		})
+		this.SecuritySettings = append(this.SecuritySettings, loader.NewTypedSettings(tlsSettings))
 	}
 	}
 	return nil
 	return nil
 }
 }

+ 7 - 4
transport/internet/kcp/config.go

@@ -3,8 +3,6 @@ package kcp
 import (
 import (
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"
 	"v2ray.com/core/transport/internet"
-
-	"github.com/golang/protobuf/proto"
 )
 )
 
 
 func (this *MTU) GetValue() uint32 {
 func (this *MTU) GetValue() uint32 {
@@ -52,7 +50,12 @@ func (this *ReadBuffer) GetSize() uint32 {
 func (this *Config) GetAuthenticator() (internet.Authenticator, error) {
 func (this *Config) GetAuthenticator() (internet.Authenticator, error) {
 	auth := NewSimpleAuthenticator()
 	auth := NewSimpleAuthenticator()
 	if this.HeaderConfig != nil {
 	if this.HeaderConfig != nil {
-		header, err := this.HeaderConfig.CreateAuthenticator()
+		rawConfig, err := this.HeaderConfig.GetInstance()
+		if err != nil {
+			return nil, err
+		}
+
+		header, err := internet.CreateAuthenticator(this.HeaderConfig.Type, rawConfig)
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
@@ -86,7 +89,7 @@ func (this *Config) GetReceivingBufferSize() uint32 {
 }
 }
 
 
 func init() {
 func init() {
-	internet.RegisterNetworkConfigCreator(v2net.Network_KCP, func() proto.Message {
+	internet.RegisterNetworkConfigCreator(v2net.Network_KCP, func() interface{} {
 		return new(Config)
 		return new(Config)
 	})
 	})
 }
 }

+ 38 - 37
transport/internet/kcp/config.pb.go

@@ -22,7 +22,7 @@ package kcp
 import proto "github.com/golang/protobuf/proto"
 import proto "github.com/golang/protobuf/proto"
 import fmt "fmt"
 import fmt "fmt"
 import math "math"
 import math "math"
-import v2ray_core_transport_internet "v2ray.com/core/transport/internet"
+import v2ray_core_common_loader "v2ray.com/core/common/loader"
 
 
 // Reference imports to suppress errors if they are not otherwise used.
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
 var _ = proto.Marshal
@@ -96,14 +96,14 @@ func (*ReadBuffer) ProtoMessage()               {}
 func (*ReadBuffer) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
 func (*ReadBuffer) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
 
 
 type Config struct {
 type Config struct {
-	Mtu              *MTU                                               `protobuf:"bytes,1,opt,name=mtu" json:"mtu,omitempty"`
-	Tti              *TTI                                               `protobuf:"bytes,2,opt,name=tti" json:"tti,omitempty"`
-	UplinkCapacity   *UplinkCapacity                                    `protobuf:"bytes,3,opt,name=uplink_capacity,json=uplinkCapacity" json:"uplink_capacity,omitempty"`
-	DownlinkCapacity *DownlinkCapacity                                  `protobuf:"bytes,4,opt,name=downlink_capacity,json=downlinkCapacity" json:"downlink_capacity,omitempty"`
-	Congestion       bool                                               `protobuf:"varint,5,opt,name=congestion" json:"congestion,omitempty"`
-	WriteBuffer      *WriteBuffer                                       `protobuf:"bytes,6,opt,name=write_buffer,json=writeBuffer" json:"write_buffer,omitempty"`
-	ReadBuffer       *ReadBuffer                                        `protobuf:"bytes,7,opt,name=read_buffer,json=readBuffer" json:"read_buffer,omitempty"`
-	HeaderConfig     *v2ray_core_transport_internet.AuthenticatorConfig `protobuf:"bytes,8,opt,name=header_config,json=headerConfig" json:"header_config,omitempty"`
+	Mtu              *MTU                                    `protobuf:"bytes,1,opt,name=mtu" json:"mtu,omitempty"`
+	Tti              *TTI                                    `protobuf:"bytes,2,opt,name=tti" json:"tti,omitempty"`
+	UplinkCapacity   *UplinkCapacity                         `protobuf:"bytes,3,opt,name=uplink_capacity,json=uplinkCapacity" json:"uplink_capacity,omitempty"`
+	DownlinkCapacity *DownlinkCapacity                       `protobuf:"bytes,4,opt,name=downlink_capacity,json=downlinkCapacity" json:"downlink_capacity,omitempty"`
+	Congestion       bool                                    `protobuf:"varint,5,opt,name=congestion" json:"congestion,omitempty"`
+	WriteBuffer      *WriteBuffer                            `protobuf:"bytes,6,opt,name=write_buffer,json=writeBuffer" json:"write_buffer,omitempty"`
+	ReadBuffer       *ReadBuffer                             `protobuf:"bytes,7,opt,name=read_buffer,json=readBuffer" json:"read_buffer,omitempty"`
+	HeaderConfig     *v2ray_core_common_loader.TypedSettings `protobuf:"bytes,8,opt,name=header_config,json=headerConfig" json:"header_config,omitempty"`
 }
 }
 
 
 func (m *Config) Reset()                    { *m = Config{} }
 func (m *Config) Reset()                    { *m = Config{} }
@@ -153,7 +153,7 @@ func (m *Config) GetReadBuffer() *ReadBuffer {
 	return nil
 	return nil
 }
 }
 
 
-func (m *Config) GetHeaderConfig() *v2ray_core_transport_internet.AuthenticatorConfig {
+func (m *Config) GetHeaderConfig() *v2ray_core_common_loader.TypedSettings {
 	if m != nil {
 	if m != nil {
 		return m.HeaderConfig
 		return m.HeaderConfig
 	}
 	}
@@ -173,31 +173,32 @@ func init() {
 func init() { proto.RegisterFile("v2ray.com/core/transport/internet/kcp/config.proto", fileDescriptor0) }
 func init() { proto.RegisterFile("v2ray.com/core/transport/internet/kcp/config.proto", fileDescriptor0) }
 
 
 var fileDescriptor0 = []byte{
 var fileDescriptor0 = []byte{
-	// 411 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x93, 0x51, 0xab, 0xda, 0x30,
-	0x1c, 0xc5, 0x71, 0xf5, 0xba, 0xcb, 0xbf, 0xf7, 0xde, 0xb9, 0xb2, 0x87, 0xb2, 0xc1, 0x50, 0x61,
-	0xe2, 0xcb, 0x52, 0x56, 0x19, 0x6c, 0x8f, 0xd3, 0xbd, 0xf8, 0xe0, 0xd8, 0x42, 0x45, 0xf0, 0xc5,
-	0xc5, 0x34, 0x6a, 0xa8, 0x26, 0x25, 0xa6, 0x8a, 0xfb, 0xa0, 0xfb, 0x3c, 0xa3, 0xa9, 0x9d, 0x55,
-	0xf0, 0xb6, 0x6f, 0x4d, 0x73, 0xce, 0x2f, 0xed, 0x39, 0xf9, 0x83, 0xbf, 0xf7, 0x15, 0x39, 0x22,
-	0x2a, 0xb7, 0x1e, 0x95, 0x8a, 0x79, 0x5a, 0x11, 0xb1, 0x8b, 0xa5, 0xd2, 0x1e, 0x17, 0x9a, 0x29,
-	0xc1, 0xb4, 0x17, 0xd1, 0xd8, 0xa3, 0x52, 0x2c, 0xf9, 0x0a, 0xc5, 0x4a, 0x6a, 0xe9, 0xb4, 0x73,
-	0x8f, 0x62, 0xe8, 0xbf, 0x1e, 0xe5, 0x7a, 0x14, 0xd1, 0xf8, 0xed, 0xe7, 0x72, 0x2c, 0x49, 0xf4,
-	0x9a, 0x09, 0xcd, 0x29, 0xd1, 0x52, 0x65, 0xe4, 0xce, 0x3b, 0xb0, 0xc6, 0xc1, 0xc4, 0x79, 0x03,
-	0x77, 0x7b, 0xb2, 0x49, 0x98, 0x5b, 0x6b, 0xd5, 0x7a, 0x8f, 0x38, 0x5b, 0xa4, 0x9b, 0x41, 0x30,
-	0xba, 0xb1, 0xd9, 0x85, 0xa7, 0x49, 0xbc, 0xe1, 0x22, 0x1a, 0x92, 0x98, 0x50, 0xae, 0x8f, 0x37,
-	0x74, 0x3d, 0x68, 0x7e, 0x97, 0x07, 0x51, 0x41, 0xd9, 0x06, 0x7b, 0xaa, 0xb8, 0x66, 0x83, 0x64,
-	0xb9, 0x64, 0xca, 0x71, 0xa0, 0xbe, 0xe3, 0x7f, 0x72, 0x8d, 0x79, 0xee, 0xb4, 0x00, 0x30, 0x23,
-	0xe1, 0x33, 0x8a, 0xbf, 0x75, 0x68, 0x0c, 0x4d, 0x76, 0xce, 0x17, 0xb0, 0xb6, 0x3a, 0x31, 0xbb,
-	0xb6, 0xdf, 0x45, 0xa5, 0x19, 0xa2, 0x71, 0x30, 0xc1, 0xa9, 0x25, 0x75, 0x6a, 0xcd, 0xdd, 0x17,
-	0x95, 0x9d, 0x41, 0x30, 0xc2, 0xa9, 0xc5, 0x99, 0xc1, 0xab, 0xc4, 0xa4, 0x32, 0xa7, 0xa7, 0x9f,
-	0x75, 0x2d, 0x43, 0xf9, 0x54, 0x81, 0x72, 0x99, 0x27, 0x7e, 0x4a, 0x2e, 0xf3, 0xfd, 0x0d, 0xaf,
-	0xc3, 0x53, 0x92, 0x67, 0x7a, 0xdd, 0xd0, 0xfb, 0x15, 0xe8, 0xd7, 0x2d, 0xe0, 0x66, 0x78, 0xdd,
-	0xcb, 0x7b, 0x00, 0x2a, 0xc5, 0x8a, 0xed, 0x34, 0x97, 0xc2, 0xbd, 0x6b, 0xd5, 0x7a, 0xf7, 0xb8,
-	0xf0, 0xc6, 0xf9, 0x05, 0x0f, 0x87, 0xb4, 0xa1, 0xf9, 0xc2, 0x14, 0xe0, 0x36, 0xcc, 0xe1, 0xa8,
-	0xc2, 0xe1, 0x85, 0x62, 0xb1, 0x7d, 0x28, 0xb4, 0xfc, 0x03, 0x6c, 0xc5, 0x48, 0x98, 0x13, 0x5f,
-	0x1a, 0xe2, 0xc7, 0x0a, 0xc4, 0xf3, 0x3d, 0xc0, 0xa0, 0xce, 0x77, 0x62, 0x0a, 0x8f, 0x6b, 0x46,
-	0x42, 0xa6, 0xe6, 0xd9, 0x04, 0xb9, 0xf7, 0x86, 0xe8, 0x97, 0x10, 0xbf, 0x15, 0x67, 0x23, 0xbb,
-	0x3f, 0xf8, 0x21, 0x03, 0x65, 0xab, 0xc1, 0x57, 0xf8, 0x40, 0xe5, 0xb6, 0xfc, 0xc3, 0x06, 0x76,
-	0x66, 0xf8, 0x99, 0xce, 0xd7, 0xcc, 0x8a, 0x68, 0xbc, 0x68, 0x98, 0x59, 0xeb, 0xff, 0x0b, 0x00,
-	0x00, 0xff, 0xff, 0xe8, 0xba, 0x79, 0x48, 0xfb, 0x03, 0x00, 0x00,
+	// 426 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x93, 0xc1, 0x6f, 0xd3, 0x30,
+	0x18, 0xc5, 0x55, 0xd2, 0x95, 0xe9, 0xcb, 0x36, 0x46, 0xc4, 0x21, 0x02, 0x09, 0x75, 0x93, 0xd8,
+	0x7a, 0xc1, 0x11, 0xdd, 0x05, 0xae, 0x1d, 0x97, 0x49, 0x0c, 0x81, 0x49, 0x85, 0xd4, 0x4b, 0x71,
+	0x1d, 0xb7, 0x58, 0x69, 0x6c, 0xcb, 0x71, 0x5a, 0x85, 0x7f, 0x91, 0x7f, 0x0a, 0xc5, 0x6e, 0x68,
+	0x5a, 0xa9, 0x6b, 0x6e, 0x6d, 0xfc, 0xde, 0xcf, 0xc9, 0x7b, 0xdf, 0x07, 0xc3, 0xd5, 0x50, 0x93,
+	0x12, 0x51, 0x99, 0x45, 0x54, 0x6a, 0x16, 0x19, 0x4d, 0x44, 0xae, 0xa4, 0x36, 0x11, 0x17, 0x86,
+	0x69, 0xc1, 0x4c, 0x94, 0x52, 0x15, 0x51, 0x29, 0xe6, 0x7c, 0x81, 0x94, 0x96, 0x46, 0x06, 0x57,
+	0xb5, 0x47, 0x33, 0xf4, 0x5f, 0x8f, 0x6a, 0x3d, 0x4a, 0xa9, 0x7a, 0x7d, 0xbb, 0x87, 0xa5, 0x32,
+	0xcb, 0xa4, 0x88, 0x96, 0x92, 0x24, 0x4c, 0x47, 0xa6, 0x54, 0xcc, 0xb1, 0xae, 0xdf, 0x80, 0xf7,
+	0x18, 0x8f, 0x83, 0x57, 0x70, 0xb2, 0x22, 0xcb, 0x82, 0x85, 0x9d, 0x7e, 0x67, 0x70, 0x8e, 0xdd,
+	0x9f, 0xea, 0x30, 0x8e, 0x1f, 0x0e, 0x1c, 0xde, 0xc0, 0xc5, 0x58, 0x2d, 0xb9, 0x48, 0xef, 0x89,
+	0x22, 0x94, 0x9b, 0xf2, 0x80, 0x6e, 0x00, 0x97, 0x9f, 0xe5, 0x5a, 0xb4, 0x50, 0x5e, 0x81, 0xff,
+	0x53, 0x73, 0xc3, 0x46, 0xc5, 0x7c, 0xce, 0x74, 0x10, 0x40, 0x37, 0xe7, 0x7f, 0x6a, 0x8d, 0xfd,
+	0x7d, 0xdd, 0x07, 0xc0, 0x8c, 0x24, 0x4f, 0x28, 0xfe, 0x76, 0xa1, 0x77, 0x6f, 0xd3, 0x0a, 0x3e,
+	0x82, 0x97, 0x99, 0xc2, 0x9e, 0xfa, 0xc3, 0x1b, 0x74, 0x34, 0x35, 0xf4, 0x18, 0x8f, 0x71, 0x65,
+	0xa9, 0x9c, 0xc6, 0xf0, 0xf0, 0x59, 0x6b, 0x67, 0x1c, 0x3f, 0xe0, 0xca, 0x12, 0x4c, 0xe0, 0x45,
+	0x61, 0x53, 0x99, 0xd2, 0xcd, 0xc7, 0x86, 0x9e, 0xa5, 0x7c, 0x68, 0x41, 0xd9, 0xcd, 0x13, 0x5f,
+	0x14, 0xbb, 0xf9, 0xfe, 0x82, 0x97, 0xc9, 0x26, 0xc9, 0x2d, 0xbd, 0x6b, 0xe9, 0x77, 0x2d, 0xe8,
+	0xfb, 0x2d, 0xe0, 0xcb, 0x64, 0xbf, 0x97, 0xb7, 0x00, 0x54, 0x8a, 0x05, 0xcb, 0x0d, 0x97, 0x22,
+	0x3c, 0xe9, 0x77, 0x06, 0xa7, 0xb8, 0xf1, 0x24, 0xf8, 0x0e, 0x67, 0xeb, 0xaa, 0xa1, 0xe9, 0xcc,
+	0x16, 0x10, 0xf6, 0xec, 0xe5, 0xa8, 0xc5, 0xe5, 0x8d, 0x62, 0xb1, 0xbf, 0x6e, 0xb4, 0xfc, 0x15,
+	0x7c, 0xcd, 0x48, 0x52, 0x13, 0x9f, 0x5b, 0xe2, 0xfb, 0x16, 0xc4, 0xed, 0x1c, 0x60, 0xd0, 0xdb,
+	0x99, 0xf8, 0x02, 0xe7, 0xbf, 0x59, 0x35, 0xe5, 0x53, 0xb7, 0x33, 0xe1, 0xa9, 0x25, 0xde, 0x36,
+	0x89, 0x6e, 0x1b, 0x90, 0xdb, 0x06, 0x14, 0x97, 0x8a, 0x25, 0x3f, 0x98, 0x31, 0x5c, 0x2c, 0x72,
+	0x7c, 0xe6, 0xdc, 0x6e, 0x84, 0x46, 0x9f, 0xe0, 0x1d, 0x95, 0xd9, 0xf1, 0xb7, 0x19, 0xf9, 0xce,
+	0xf0, 0xad, 0x5a, 0xaa, 0x89, 0x97, 0x52, 0x35, 0xeb, 0xd9, 0x05, 0xbb, 0xfb, 0x17, 0x00, 0x00,
+	0xff, 0xff, 0x02, 0xb7, 0x81, 0x10, 0xe2, 0x03, 0x00, 0x00,
 }
 }

+ 2 - 2
transport/internet/kcp/config.proto

@@ -5,7 +5,7 @@ option go_package = "kcp";
 option java_package = "com.v2ray.core.transport.internet.kcp";
 option java_package = "com.v2ray.core.transport.internet.kcp";
 option java_outer_classname = "ConfigProto";
 option java_outer_classname = "ConfigProto";
 
 
-import "v2ray.com/core/transport/internet/authenticator.proto";
+import "v2ray.com/core/common/loader/type.proto";
 
 
 // Maximum Transmission Unit, in bytes.
 // Maximum Transmission Unit, in bytes.
 message MTU {
 message MTU {
@@ -45,5 +45,5 @@ message Config {
   bool congestion = 5;
   bool congestion = 5;
   WriteBuffer write_buffer = 6;
   WriteBuffer write_buffer = 6;
   ReadBuffer read_buffer = 7;
   ReadBuffer read_buffer = 7;
-  v2ray.core.transport.internet.AuthenticatorConfig header_config = 8;
+  v2ray.core.common.loader.TypedSettings header_config = 8;
 }
 }

+ 15 - 8
transport/internet/kcp/config_json.go

@@ -5,9 +5,13 @@ package kcp
 import (
 import (
 	"encoding/json"
 	"encoding/json"
 
 
+	"github.com/golang/protobuf/proto"
 	"v2ray.com/core/common"
 	"v2ray.com/core/common"
+	"v2ray.com/core/common/loader"
 	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/log"
-	"v2ray.com/core/transport/internet"
+	"v2ray.com/core/transport/internet/authenticators/noop"
+	"v2ray.com/core/transport/internet/authenticators/srtp"
+	"v2ray.com/core/transport/internet/authenticators/utp"
 )
 )
 
 
 func (this *Config) UnmarshalJSON(data []byte) error {
 func (this *Config) UnmarshalJSON(data []byte) error {
@@ -67,18 +71,21 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 		}
 		}
 	}
 	}
 	if len(jsonConfig.HeaderConfig) > 0 {
 	if len(jsonConfig.HeaderConfig) > 0 {
-		name, config, err := internet.CreateAuthenticatorConfig(jsonConfig.HeaderConfig)
+		config, _, err := headerLoader.Load(jsonConfig.HeaderConfig)
 		if err != nil {
 		if err != nil {
 			log.Error("KCP|Config: Failed to parse header config: ", err)
 			log.Error("KCP|Config: Failed to parse header config: ", err)
 			return err
 			return err
 		}
 		}
-		authConfig, err := internet.NewAuthenticatorConfig(name, config)
-		if err != nil {
-			log.Error("KCP:Config: Failed to create header config: ", err)
-			return err
-		}
-		this.HeaderConfig = authConfig
+		this.HeaderConfig = loader.NewTypedSettings(config.(proto.Message))
 	}
 	}
 
 
 	return nil
 	return nil
 }
 }
+
+var (
+	headerLoader = loader.NewJSONConfigLoader(loader.NamedTypeMap{
+		"none": loader.GetType(new(noop.Config)),
+		"srtp": loader.GetType(new(srtp.Config)),
+		"utp":  loader.GetType(new(utp.Config)),
+	}, "type", "")
+)

+ 10 - 7
transport/internet/kcp/dialer.go

@@ -44,18 +44,21 @@ func DialKCP(src v2net.Address, dest v2net.Destination, options internet.DialerO
 	var iConn internet.Connection
 	var iConn internet.Connection
 	iConn = session
 	iConn = session
 
 
-	if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
+	if options.Stream != nil && options.Stream.HasSecuritySettings() {
 		securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
 		securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
 		if err != nil {
 		if err != nil {
-			log.Error("KCP|Dialer: Failed to apply TLS config: ", err)
+			log.Error("KCP|Dialer: Failed to get security settings: ", err)
 			return nil, err
 			return nil, err
 		}
 		}
-		config := securitySettings.(*v2tls.Config).GetTLSConfig()
-		if dest.Address.Family().IsDomain() {
-			config.ServerName = dest.Address.Domain()
+		switch securitySettings := securitySettings.(type) {
+		case *v2tls.Config:
+			config := securitySettings.GetTLSConfig()
+			if dest.Address.Family().IsDomain() {
+				config.ServerName = dest.Address.Domain()
+			}
+			tlsConn := tls.Client(conn, config)
+			iConn = v2tls.NewConnection(tlsConn)
 		}
 		}
-		tlsConn := tls.Client(conn, config)
-		iConn = v2tls.NewConnection(tlsConn)
 	}
 	}
 
 
 	return iConn, nil
 	return iConn, nil

+ 6 - 3
transport/internet/kcp/listener.go

@@ -47,13 +47,16 @@ func NewListener(address v2net.Address, port v2net.Port, options internet.Listen
 		running:       true,
 		running:       true,
 		config:        kcpSettings,
 		config:        kcpSettings,
 	}
 	}
-	if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
+	if options.Stream != nil && options.Stream.HasSecuritySettings() {
 		securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
 		securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
 		if err != nil {
 		if err != nil {
-			log.Error("KCP|Listener: Failed to apply TLS config: ", err)
+			log.Error("KCP|Listener: Failed to get security settings: ", err)
 			return nil, err
 			return nil, err
 		}
 		}
-		l.tlsConfig = securitySettings.(*v2tls.Config).GetTLSConfig()
+		switch securitySettings := securitySettings.(type) {
+		case *v2tls.Config:
+			l.tlsConfig = securitySettings.GetTLSConfig()
+		}
 	}
 	}
 	hub, err := udp.ListenUDP(address, port, udp.ListenOption{Callback: l.OnReceive})
 	hub, err := udp.ListenUDP(address, port, udp.ListenOption{Callback: l.OnReceive})
 	if err != nil {
 	if err != nil {

+ 1 - 3
transport/internet/tcp/config.go

@@ -3,12 +3,10 @@ package tcp
 import (
 import (
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"
 	"v2ray.com/core/transport/internet"
-
-	"github.com/golang/protobuf/proto"
 )
 )
 
 
 func init() {
 func init() {
-	internet.RegisterNetworkConfigCreator(v2net.Network_TCP, func() proto.Message {
+	internet.RegisterNetworkConfigCreator(v2net.Network_TCP, func() interface{} {
 		return new(Config)
 		return new(Config)
 	})
 	})
 }
 }

+ 9 - 6
transport/internet/tcp/dialer.go

@@ -37,17 +37,20 @@ func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOpti
 			return nil, err
 			return nil, err
 		}
 		}
 	}
 	}
-	if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
+	if options.Stream != nil && options.Stream.HasSecuritySettings() {
 		securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
 		securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
 		if err != nil {
 		if err != nil {
-			log.Error("TCP: Failed to apply TLS config: ", err)
+			log.Error("TCP: Failed to get security settings: ", err)
 			return nil, err
 			return nil, err
 		}
 		}
-		config := securitySettings.(*v2tls.Config).GetTLSConfig()
-		if dest.Address.Family().IsDomain() {
-			config.ServerName = dest.Address.Domain()
+		tlsConfig, ok := securitySettings.(*v2tls.Config)
+		if ok {
+			config := tlsConfig.GetTLSConfig()
+			if dest.Address.Family().IsDomain() {
+				config.ServerName = dest.Address.Domain()
+			}
+			conn = tls.Client(conn, config)
 		}
 		}
-		conn = tls.Client(conn, config)
 	}
 	}
 	return NewConnection(id, conn, globalCache, tcpSettings), nil
 	return NewConnection(id, conn, globalCache, tcpSettings), nil
 }
 }

+ 6 - 3
transport/internet/tcp/hub.go

@@ -51,13 +51,16 @@ func ListenTCP(address v2net.Address, port v2net.Port, options internet.ListenOp
 		awaitingConns: make(chan *ConnectionWithError, 32),
 		awaitingConns: make(chan *ConnectionWithError, 32),
 		config:        tcpSettings,
 		config:        tcpSettings,
 	}
 	}
-	if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
+	if options.Stream != nil && options.Stream.HasSecuritySettings() {
 		securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
 		securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
 		if err != nil {
 		if err != nil {
-			log.Error("TCP: Failed to apply TLS config: ", err)
+			log.Error("TCP: Failed to get security config: ", err)
 			return nil, err
 			return nil, err
 		}
 		}
-		l.tlsConfig = securitySettings.(*v2tls.Config).GetTLSConfig()
+		tlsConfig, ok := securitySettings.(*v2tls.Config)
+		if ok {
+			l.tlsConfig = tlsConfig.GetTLSConfig()
+		}
 	}
 	}
 	go l.KeepAccepting()
 	go l.KeepAccepting()
 	return l, nil
 	return l, nil

+ 1 - 3
transport/internet/ws/config.go

@@ -3,12 +3,10 @@ package ws
 import (
 import (
 	v2net "v2ray.com/core/common/net"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"
 	"v2ray.com/core/transport/internet"
-
-	"github.com/golang/protobuf/proto"
 )
 )
 
 
 func init() {
 func init() {
-	internet.RegisterNetworkConfigCreator(v2net.Network_WebSocket, func() proto.Message {
+	internet.RegisterNetworkConfigCreator(v2net.Network_WebSocket, func() interface{} {
 		return new(Config)
 		return new(Config)
 	})
 	})
 }
 }

+ 8 - 5
transport/internet/ws/dialer.go

@@ -69,16 +69,19 @@ func wsDial(src v2net.Address, dest v2net.Destination, options internet.DialerOp
 
 
 	protocol := "ws"
 	protocol := "ws"
 
 
-	if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
+	if options.Stream != nil && options.Stream.HasSecuritySettings() {
 		protocol = "wss"
 		protocol = "wss"
 		securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
 		securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
 		if err != nil {
 		if err != nil {
-			log.Error("WebSocket: Failed to create apply TLS config: ", err)
+			log.Error("WebSocket: Failed to create security settings: ", err)
 			return nil, err
 			return nil, err
 		}
 		}
-		dialer.TLSClientConfig = securitySettings.(*v2tls.Config).GetTLSConfig()
-		if dest.Address.Family().IsDomain() {
-			dialer.TLSClientConfig.ServerName = dest.Address.Domain()
+		tlsConfig, ok := securitySettings.(*v2tls.Config)
+		if ok {
+			dialer.TLSClientConfig = tlsConfig.GetTLSConfig()
+			if dest.Address.Family().IsDomain() {
+				dialer.TLSClientConfig.ServerName = dest.Address.Domain()
+			}
 		}
 		}
 	}
 	}
 
 

+ 5 - 2
transport/internet/ws/hub.go

@@ -46,13 +46,16 @@ func ListenWS(address v2net.Address, port v2net.Port, options internet.ListenOpt
 		awaitingConns: make(chan *ConnectionWithError, 32),
 		awaitingConns: make(chan *ConnectionWithError, 32),
 		config:        wsSettings,
 		config:        wsSettings,
 	}
 	}
-	if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
+	if options.Stream != nil && options.Stream.HasSecuritySettings() {
 		securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
 		securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
 		if err != nil {
 		if err != nil {
 			log.Error("WebSocket: Failed to create apply TLS config: ", err)
 			log.Error("WebSocket: Failed to create apply TLS config: ", err)
 			return nil, err
 			return nil, err
 		}
 		}
-		l.tlsConfig = securitySettings.(*v2tls.Config).GetTLSConfig()
+		tlsConfig, ok := securitySettings.(*v2tls.Config)
+		if ok {
+			l.tlsConfig = tlsConfig.GetTLSConfig()
+		}
 	}
 	}
 
 
 	err = l.listenws(address, port)
 	err = l.listenws(address, port)

+ 1 - 1
v2ray.go

@@ -97,7 +97,7 @@ func NewPoint(pConfig *Config) (*Point, error) {
 			return nil, err
 			return nil, err
 		}
 		}
 		outboundHandler, err := proxyregistry.CreateOutboundHandler(
 		outboundHandler, err := proxyregistry.CreateOutboundHandler(
-			outbound.Protocol, vpoint.space, outboundSettings, &proxy.OutboundHandlerMeta{
+			outbound.Settings.Type, vpoint.space, outboundSettings, &proxy.OutboundHandlerMeta{
 				Tag:            outbound.Tag,
 				Tag:            outbound.Tag,
 				Address:        outbound.SendThrough.AsAddress(),
 				Address:        outbound.SendThrough.AsAddress(),
 				StreamSettings: outbound.StreamSettings,
 				StreamSettings: outbound.StreamSettings,