diff --git a/config.go b/config.go index 5f15a1b3d..8f86d8ca5 100644 --- a/config.go +++ b/config.go @@ -3,72 +3,33 @@ package core import ( "io" - "v2ray.com/core/app/dns" - "v2ray.com/core/app/router" "v2ray.com/core/common" - "v2ray.com/core/common/log" - v2net "v2ray.com/core/common/net" - "v2ray.com/core/transport" - "v2ray.com/core/transport/internet" + "v2ray.com/core/proxy/registry" ) -type InboundConnectionConfig struct { - Port v2net.Port - ListenOn v2net.Address - StreamSettings *internet.StreamConfig - Protocol string - Settings []byte - AllowPassiveConnection bool +func (this *AllocationStrategyConcurrency) GetValue() uint32 { + if this == nil { + return 3 + } + return this.Value } -type OutboundConnectionConfig struct { - Protocol string - SendThrough v2net.Address - StreamSettings *internet.StreamConfig - Settings []byte +func (this *AllocationStrategyRefresh) GetValue() uint32 { + if this == nil { + return 5 + } + return this.Value } -const ( - AllocationStrategyAlways = "always" - AllocationStrategyRandom = "random" - AllocationStrategyExternal = "external" -) - -type InboundDetourAllocationConfig struct { - Strategy string // Allocation strategy of this inbound detour. - Concurrency int // Number of handlers (ports) running in parallel. - Refresh int // Number of minutes before a handler is regenerated. +func (this *InboundConnectionConfig) GetAllocationStrategyValue() *AllocationStrategy { + if this.AllocationStrategy == nil { + return &AllocationStrategy{} + } + return this.AllocationStrategy } -type InboundDetourConfig struct { - Protocol string - PortRange v2net.PortRange - ListenOn v2net.Address - Tag string - Allocation *InboundDetourAllocationConfig - StreamSettings *internet.StreamConfig - Settings []byte - AllowPassiveConnection bool -} - -type OutboundDetourConfig struct { - Protocol string - SendThrough v2net.Address - StreamSettings *internet.StreamConfig - Tag string - Settings []byte -} - -type Config struct { - Port v2net.Port - LogConfig *log.Config - RouterConfig *router.Config - DNSConfig *dns.Config - InboundConfig *InboundConnectionConfig - OutboundConfig *OutboundConnectionConfig - InboundDetours []*InboundDetourConfig - OutboundDetours []*OutboundDetourConfig - TransportConfig *transport.Config +func (this *InboundConnectionConfig) GetTypedSettings() (interface{}, error) { + return registry.MarshalInboundConfig(this.Protocol, this.Settings) } type ConfigLoader func(input io.Reader) (*Config, error) diff --git a/config.pb.go b/config.pb.go new file mode 100644 index 000000000..90f513069 --- /dev/null +++ b/config.pb.go @@ -0,0 +1,318 @@ +// Code generated by protoc-gen-go. +// source: v2ray.com/core/config.proto +// DO NOT EDIT! + +/* +Package core is a generated protocol buffer package. + +It is generated from these files: + v2ray.com/core/config.proto + +It has these top-level messages: + AllocationStrategyConcurrency + AllocationStrategyRefresh + AllocationStrategy + InboundConnectionConfig + OutboundConnectionConfig + Config +*/ +package core + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import v2ray_core_app_router "v2ray.com/core/app/router" +import v2ray_core_app_dns "v2ray.com/core/app/dns" +import v2ray_core_common_net "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_transport_internet "v2ray.com/core/transport/internet" +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. +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 AllocationStrategy_Type int32 + +const ( + // Always allocate all connection handlers. + AllocationStrategy_Always AllocationStrategy_Type = 0 + // Randomly allocate specific range of handlers. + AllocationStrategy_Random AllocationStrategy_Type = 1 + // External. Not supported yet. + AllocationStrategy_External AllocationStrategy_Type = 2 +) + +var AllocationStrategy_Type_name = map[int32]string{ + 0: "Always", + 1: "Random", + 2: "External", +} +var AllocationStrategy_Type_value = map[string]int32{ + "Always": 0, + "Random": 1, + "External": 2, +} + +func (x AllocationStrategy_Type) String() string { + return proto.EnumName(AllocationStrategy_Type_name, int32(x)) +} +func (AllocationStrategy_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 0} } + +type AllocationStrategyConcurrency struct { + Value uint32 `protobuf:"varint,1,opt,name=value" json:"value,omitempty"` +} + +func (m *AllocationStrategyConcurrency) Reset() { *m = AllocationStrategyConcurrency{} } +func (m *AllocationStrategyConcurrency) String() string { return proto.CompactTextString(m) } +func (*AllocationStrategyConcurrency) ProtoMessage() {} +func (*AllocationStrategyConcurrency) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +type AllocationStrategyRefresh struct { + Value uint32 `protobuf:"varint,1,opt,name=value" json:"value,omitempty"` +} + +func (m *AllocationStrategyRefresh) Reset() { *m = AllocationStrategyRefresh{} } +func (m *AllocationStrategyRefresh) String() string { return proto.CompactTextString(m) } +func (*AllocationStrategyRefresh) ProtoMessage() {} +func (*AllocationStrategyRefresh) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +type AllocationStrategy struct { + Type AllocationStrategy_Type `protobuf:"varint,1,opt,name=type,enum=v2ray.core.AllocationStrategy_Type" json:"type,omitempty"` + // Number of handlers (ports) running in parallel. + Concurrency *AllocationStrategyConcurrency `protobuf:"bytes,2,opt,name=concurrency" json:"concurrency,omitempty"` + // Number of minutes before a handler is regenerated. + Refresh *AllocationStrategyRefresh `protobuf:"bytes,3,opt,name=refresh" json:"refresh,omitempty"` +} + +func (m *AllocationStrategy) Reset() { *m = AllocationStrategy{} } +func (m *AllocationStrategy) String() string { return proto.CompactTextString(m) } +func (*AllocationStrategy) ProtoMessage() {} +func (*AllocationStrategy) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *AllocationStrategy) GetConcurrency() *AllocationStrategyConcurrency { + if m != nil { + return m.Concurrency + } + return nil +} + +func (m *AllocationStrategy) GetRefresh() *AllocationStrategyRefresh { + if m != nil { + return m.Refresh + } + return nil +} + +// Config for an inbound connection handler. +type InboundConnectionConfig struct { + Protocol string `protobuf:"bytes,1,opt,name=protocol" json:"protocol,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"` + 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"` + 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"` +} + +func (m *InboundConnectionConfig) Reset() { *m = InboundConnectionConfig{} } +func (m *InboundConnectionConfig) String() string { return proto.CompactTextString(m) } +func (*InboundConnectionConfig) ProtoMessage() {} +func (*InboundConnectionConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + +func (m *InboundConnectionConfig) GetPortRange() *v2ray_core_common_net.PortRange { + if m != nil { + return m.PortRange + } + return nil +} + +func (m *InboundConnectionConfig) GetListenOn() *v2ray_core_common_net2.IPOrDomain { + if m != nil { + return m.ListenOn + } + return nil +} + +func (m *InboundConnectionConfig) GetAllocationStrategy() *AllocationStrategy { + if m != nil { + return m.AllocationStrategy + } + return nil +} + +func (m *InboundConnectionConfig) GetStreamSettings() *v2ray_core_transport_internet.StreamConfig { + if m != nil { + return m.StreamSettings + } + return nil +} + +func (m *InboundConnectionConfig) GetSettings() *google_protobuf.Any { + if m != nil { + return m.Settings + } + return nil +} + +type OutboundConnectionConfig struct { + Protocol string `protobuf:"bytes,1,opt,name=protocol" json:"protocol,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"` + 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) String() string { return proto.CompactTextString(m) } +func (*OutboundConnectionConfig) ProtoMessage() {} +func (*OutboundConnectionConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } + +func (m *OutboundConnectionConfig) GetSendThrough() *v2ray_core_common_net2.IPOrDomain { + if m != nil { + return m.SendThrough + } + return nil +} + +func (m *OutboundConnectionConfig) GetStreamSettings() *v2ray_core_transport_internet.StreamConfig { + if m != nil { + return m.StreamSettings + } + return nil +} + +func (m *OutboundConnectionConfig) GetSettings() *google_protobuf.Any { + if m != nil { + return m.Settings + } + return nil +} + +type Config struct { + Inbound []*InboundConnectionConfig `protobuf:"bytes,1,rep,name=inbound" json:"inbound,omitempty"` + Outbound []*OutboundConnectionConfig `protobuf:"bytes,2,rep,name=outbound" json:"outbound,omitempty"` + Log *v2ray_core_common_log.Config `protobuf:"bytes,3,opt,name=log" json:"log,omitempty"` + Router *v2ray_core_app_router.Config `protobuf:"bytes,4,opt,name=router" json:"router,omitempty"` + Dns *v2ray_core_app_dns.Config `protobuf:"bytes,5,opt,name=dns" json:"dns,omitempty"` + Transport *v2ray_core_transport.Config `protobuf:"bytes,6,opt,name=transport" json:"transport,omitempty"` +} + +func (m *Config) Reset() { *m = Config{} } +func (m *Config) String() string { return proto.CompactTextString(m) } +func (*Config) ProtoMessage() {} +func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } + +func (m *Config) GetInbound() []*InboundConnectionConfig { + if m != nil { + return m.Inbound + } + return nil +} + +func (m *Config) GetOutbound() []*OutboundConnectionConfig { + if m != nil { + return m.Outbound + } + return nil +} + +func (m *Config) GetLog() *v2ray_core_common_log.Config { + if m != nil { + return m.Log + } + return nil +} + +func (m *Config) GetRouter() *v2ray_core_app_router.Config { + if m != nil { + return m.Router + } + return nil +} + +func (m *Config) GetDns() *v2ray_core_app_dns.Config { + if m != nil { + return m.Dns + } + return nil +} + +func (m *Config) GetTransport() *v2ray_core_transport.Config { + if m != nil { + return m.Transport + } + return nil +} + +func init() { + proto.RegisterType((*AllocationStrategyConcurrency)(nil), "v2ray.core.AllocationStrategyConcurrency") + proto.RegisterType((*AllocationStrategyRefresh)(nil), "v2ray.core.AllocationStrategyRefresh") + proto.RegisterType((*AllocationStrategy)(nil), "v2ray.core.AllocationStrategy") + proto.RegisterType((*InboundConnectionConfig)(nil), "v2ray.core.InboundConnectionConfig") + proto.RegisterType((*OutboundConnectionConfig)(nil), "v2ray.core.OutboundConnectionConfig") + proto.RegisterType((*Config)(nil), "v2ray.core.Config") + proto.RegisterEnum("v2ray.core.AllocationStrategy_Type", AllocationStrategy_Type_name, AllocationStrategy_Type_value) +} + +func init() { proto.RegisterFile("v2ray.com/core/config.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 723 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x95, 0xdb, 0x6e, 0xd3, 0x30, + 0x18, 0xc7, 0xe9, 0x61, 0x5d, 0xfb, 0x75, 0x8c, 0xca, 0x4c, 0x90, 0x15, 0x86, 0x4a, 0x77, 0xa0, + 0x88, 0x29, 0x81, 0xa1, 0x09, 0x84, 0x04, 0x63, 0x07, 0x2e, 0x26, 0x2e, 0x5a, 0x65, 0xbb, 0xe2, + 0xa6, 0xf2, 0x12, 0x2f, 0x8b, 0x94, 0xda, 0x91, 0xed, 0x6e, 0xe4, 0x11, 0x78, 0x01, 0x5e, 0x6e, + 0x2f, 0x83, 0x62, 0x3b, 0xe9, 0x79, 0x0c, 0x71, 0x17, 0xd7, 0xff, 0xdf, 0xe7, 0xcf, 0xff, 0xbf, + 0x3f, 0x15, 0x9e, 0x5d, 0xef, 0x71, 0x9c, 0xd8, 0x1e, 0x1b, 0x38, 0x1e, 0xe3, 0xc4, 0xf1, 0x18, + 0xbd, 0x0c, 0x03, 0x3b, 0xe6, 0x4c, 0x32, 0x04, 0xd9, 0x26, 0x27, 0xcd, 0x9d, 0x29, 0x21, 0x8e, + 0x63, 0x87, 0xb3, 0xa1, 0x24, 0x7c, 0x82, 0x69, 0x6e, 0xce, 0xd1, 0xf9, 0x54, 0x4c, 0x8a, 0xb6, + 0x66, 0x4e, 0x1d, 0x0c, 0x18, 0x75, 0x28, 0x91, 0x4e, 0xcc, 0xb8, 0x34, 0xaa, 0x57, 0x8b, 0x55, + 0xd8, 0xf7, 0x39, 0x11, 0xc2, 0x08, 0x77, 0xe6, 0x0b, 0x23, 0x16, 0x4c, 0x1e, 0x6b, 0x4f, 0xe9, + 0x24, 0xc7, 0x54, 0xa4, 0x07, 0x3a, 0x21, 0x95, 0x84, 0xa7, 0x85, 0x27, 0xf4, 0xdb, 0x0b, 0xf5, + 0x13, 0xb2, 0xf5, 0x80, 0xb1, 0x20, 0x22, 0x8e, 0x5a, 0x5d, 0x0c, 0x2f, 0x1d, 0x4c, 0x13, 0xbd, + 0xd5, 0xde, 0x87, 0x8d, 0xc3, 0x28, 0x62, 0x1e, 0x96, 0x21, 0xa3, 0x67, 0x92, 0x63, 0x49, 0x82, + 0xe4, 0x98, 0x51, 0x6f, 0xc8, 0x39, 0xa1, 0x5e, 0x82, 0xd6, 0x60, 0xe9, 0x1a, 0x47, 0x43, 0x62, + 0x15, 0x5a, 0x85, 0xce, 0x43, 0x57, 0x2f, 0xda, 0xef, 0x60, 0x7d, 0x16, 0x73, 0xc9, 0x25, 0x27, + 0xe2, 0x6a, 0x01, 0xf2, 0xab, 0x08, 0x68, 0x96, 0x41, 0x1f, 0xa0, 0x2c, 0x93, 0x58, 0x6b, 0x57, + 0xf7, 0x36, 0xed, 0x51, 0xa2, 0xf6, 0xac, 0xda, 0x3e, 0x4f, 0x62, 0xe2, 0x2a, 0x00, 0x7d, 0x87, + 0xba, 0x37, 0xea, 0xd3, 0x2a, 0xb6, 0x0a, 0x9d, 0xfa, 0xde, 0xeb, 0xbb, 0xf9, 0xb1, 0x8b, 0xb9, + 0xe3, 0x34, 0x3a, 0x80, 0x65, 0xae, 0xbb, 0xb7, 0x4a, 0xaa, 0xd0, 0xf6, 0xdd, 0x85, 0xcc, 0x55, + 0xdd, 0x8c, 0x6a, 0xef, 0x42, 0x39, 0xed, 0x0d, 0x01, 0x54, 0x0e, 0xa3, 0x1b, 0x9c, 0x88, 0xc6, + 0x83, 0xf4, 0xdb, 0xc5, 0xd4, 0x67, 0x83, 0x46, 0x01, 0xad, 0x40, 0xf5, 0xdb, 0xcf, 0x34, 0x42, + 0x1c, 0x35, 0x8a, 0xed, 0xdb, 0x12, 0x3c, 0x3d, 0xa5, 0x17, 0x6c, 0x48, 0xfd, 0x63, 0x46, 0x29, + 0xf1, 0xd2, 0xda, 0xc7, 0x2a, 0x32, 0xd4, 0x84, 0xaa, 0x8a, 0xc6, 0x63, 0x91, 0x32, 0xa5, 0xe6, + 0xe6, 0x6b, 0x74, 0x00, 0x90, 0xa6, 0xdb, 0xe7, 0x98, 0x06, 0xc4, 0x5c, 0xb9, 0x35, 0xde, 0xa9, + 0x7e, 0x58, 0x36, 0x25, 0xd2, 0xee, 0x31, 0x2e, 0xdd, 0x54, 0xe7, 0xd6, 0xe2, 0xec, 0x13, 0x7d, + 0x81, 0x5a, 0x14, 0x0a, 0x49, 0x68, 0x9f, 0x51, 0x73, 0xd3, 0x97, 0x0b, 0xf8, 0xd3, 0x5e, 0x97, + 0x9f, 0xb0, 0x01, 0x0e, 0xa9, 0x5b, 0xd5, 0x4c, 0x97, 0xa2, 0x06, 0x94, 0x24, 0x0e, 0xac, 0xb2, + 0xea, 0x2b, 0xfd, 0x44, 0x5d, 0x78, 0x8c, 0x73, 0x7b, 0xfa, 0xc2, 0xf8, 0x63, 0x2d, 0xa9, 0xda, + 0x2f, 0xfe, 0xe2, 0x22, 0xc2, 0xb3, 0x0f, 0xe2, 0x1c, 0x1e, 0x09, 0xc9, 0x09, 0x1e, 0xf4, 0x05, + 0x91, 0x32, 0xa4, 0x81, 0xb0, 0x2a, 0xaa, 0xd8, 0x9b, 0xf1, 0x62, 0xf9, 0x4b, 0xb7, 0xb3, 0xc9, + 0xb0, 0xcf, 0x14, 0xa5, 0x5d, 0x74, 0x57, 0x75, 0x8d, 0x33, 0x53, 0x02, 0xbd, 0x85, 0x6a, 0x5e, + 0x6e, 0x59, 0x95, 0x5b, 0xb3, 0xf5, 0x54, 0xd8, 0xd9, 0x54, 0xd8, 0x87, 0x34, 0x71, 0x73, 0x15, + 0xfa, 0x08, 0x56, 0xda, 0xdd, 0x4d, 0x3f, 0xc6, 0x42, 0x84, 0xd7, 0xa4, 0xef, 0xe5, 0x49, 0x59, + 0xd5, 0x56, 0xa1, 0x53, 0x75, 0x9f, 0xa8, 0xfd, 0x9e, 0xde, 0x1e, 0xe5, 0xd8, 0xfe, 0x5d, 0x04, + 0xab, 0x3b, 0x94, 0xff, 0x1e, 0xef, 0x09, 0xac, 0x08, 0x42, 0xfd, 0xbe, 0xbc, 0xe2, 0x6c, 0x18, + 0x5c, 0x99, 0x80, 0xef, 0x11, 0x50, 0x3d, 0xc5, 0xce, 0x35, 0x35, 0xcf, 0xc0, 0xd2, 0xff, 0x1b, + 0x38, 0x9b, 0xfc, 0xb8, 0xa5, 0x4b, 0xf7, 0xb1, 0xb4, 0x7d, 0x5b, 0x84, 0x8a, 0xb1, 0xe1, 0x33, + 0x2c, 0x87, 0x7a, 0x00, 0xac, 0x42, 0xab, 0xd4, 0xa9, 0x4f, 0x4e, 0xfe, 0x82, 0xd9, 0x70, 0x33, + 0x06, 0x7d, 0x85, 0x2a, 0x33, 0x0e, 0x5b, 0x45, 0xc5, 0x6f, 0x8d, 0xf3, 0x8b, 0xdc, 0x77, 0x73, + 0x0a, 0x39, 0x50, 0x8a, 0x58, 0x60, 0x9c, 0xd9, 0x98, 0x63, 0x71, 0xc4, 0x02, 0xdb, 0x50, 0xa9, + 0x12, 0xed, 0x43, 0x45, 0xff, 0x9d, 0x28, 0x0f, 0xa6, 0x18, 0x1c, 0xc7, 0xb6, 0xde, 0xcd, 0x18, + 0x23, 0x46, 0xbb, 0x50, 0xf2, 0x69, 0x66, 0x50, 0x73, 0x9a, 0xf1, 0xa9, 0xc8, 0x0f, 0xf1, 0xa9, + 0x40, 0x9f, 0xa0, 0x96, 0x07, 0x63, 0x9e, 0xfd, 0xf3, 0xf9, 0xa9, 0x19, 0x6a, 0x24, 0x3f, 0xda, + 0x84, 0x55, 0x8f, 0x0d, 0xc6, 0xd4, 0x47, 0x75, 0x2d, 0xea, 0xa5, 0x69, 0xfc, 0x28, 0xa7, 0x3f, + 0x5d, 0x54, 0x54, 0x34, 0xef, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x05, 0x33, 0xc3, 0x7f, 0x57, + 0x07, 0x00, 0x00, +} diff --git a/config.proto b/config.proto index c6f35ad78..e5de44a04 100644 --- a/config.proto +++ b/config.proto @@ -5,9 +5,70 @@ option go_package = "core"; option java_package = "com.v2ray.core"; option java_outer_classname = "ConfigProto"; +import "v2ray.com/core/app/router/config.proto"; +import "v2ray.com/core/app/dns/config.proto"; +import "v2ray.com/core/common/net/port.proto"; +import "v2ray.com/core/common/net/address.proto"; +import "v2ray.com/core/common/log/config.proto"; +import "v2ray.com/core/transport/internet/config.proto"; +import "v2ray.com/core/transport/config.proto"; +import "google/protobuf/any.proto"; +message AllocationStrategyConcurrency { + uint32 value = 1; +} + +message AllocationStrategyRefresh { + uint32 value = 1; +} + +message AllocationStrategy { + enum Type { + // Always allocate all connection handlers. + Always = 0; + + // Randomly allocate specific range of handlers. + Random = 1; + + // External. Not supported yet. + External = 2; + } + + Type type = 1; + + // Number of handlers (ports) running in parallel. + AllocationStrategyConcurrency concurrency = 2; + + // Number of minutes before a handler is regenerated. + AllocationStrategyRefresh refresh = 3; +} + +// Config for an inbound connection handler. message InboundConnectionConfig { string protocol = 1; + v2ray.core.common.net.PortRange port_range = 2; + v2ray.core.common.net.IPOrDomain listen_on = 3; + string tag = 4; + AllocationStrategy allocation_strategy = 5; + v2ray.core.transport.internet.StreamConfig stream_settings = 6; + google.protobuf.Any settings = 7; + bool allow_passive_connection = 8; +} +message OutboundConnectionConfig { + string protocol = 1; + v2ray.core.common.net.IPOrDomain send_through = 2; + v2ray.core.transport.internet.StreamConfig stream_settings = 3; + string tag = 4; + google.protobuf.Any settings = 5; +} + +message Config { + repeated InboundConnectionConfig inbound = 1; + repeated OutboundConnectionConfig outbound = 2; + v2ray.core.common.log.Config log = 3; + v2ray.core.app.router.Config router = 4; + v2ray.core.app.dns.Config dns = 5; + v2ray.core.transport.Config transport = 6; } \ No newline at end of file diff --git a/config_json.go b/config_json.go deleted file mode 100644 index 634a6c48c..000000000 --- a/config_json.go +++ /dev/null @@ -1,246 +0,0 @@ -// +build json - -package core - -import ( - "encoding/json" - "errors" - "io" - - "v2ray.com/core/app/dns" - "v2ray.com/core/app/router" - "v2ray.com/core/common" - "v2ray.com/core/common/log" - v2net "v2ray.com/core/common/net" - "v2ray.com/core/transport" - "v2ray.com/core/transport/internet" -) - -const ( - DefaultRefreshMinute = int(9999) -) - -func (this *Config) UnmarshalJSON(data []byte) error { - type JsonConfig struct { - Port v2net.Port `json:"port"` // Port of this Point server. - LogConfig *log.Config `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"` - } - jsonConfig := new(JsonConfig) - if err := json.Unmarshal(data, jsonConfig); err != nil { - return errors.New("Point: Failed to parse config: " + err.Error()) - } - this.Port = jsonConfig.Port - this.LogConfig = jsonConfig.LogConfig - this.RouterConfig = jsonConfig.RouterConfig - - if jsonConfig.InboundConfig == nil { - return errors.New("Point: Inbound config is not specified.") - } - this.InboundConfig = jsonConfig.InboundConfig - - if jsonConfig.OutboundConfig == nil { - return errors.New("Point: Outbound config is not specified.") - } - this.OutboundConfig = jsonConfig.OutboundConfig - this.InboundDetours = jsonConfig.InboundDetours - this.OutboundDetours = jsonConfig.OutboundDetours - if jsonConfig.DNSConfig == nil { - jsonConfig.DNSConfig = &dns.Config{ - NameServers: []*v2net.Endpoint{{ - Network: v2net.Network_UDP, - Address: &v2net.IPOrDomain{ - Address: &v2net.IPOrDomain_Domain{ - Domain: "localhost", - }, - }, - Port: 53, - }}, - } - } - this.DNSConfig = jsonConfig.DNSConfig - this.TransportConfig = jsonConfig.Transport - return nil -} - -func (this *InboundConnectionConfig) UnmarshalJSON(data []byte) error { - type JsonConfig struct { - Port uint16 `json:"port"` - Listen *v2net.IPOrDomain `json:"listen"` - Protocol string `json:"protocol"` - StreamSetting *internet.StreamConfig `json:"streamSettings"` - Settings json.RawMessage `json:"settings"` - AllowPassive bool `json:"allowPassive"` - } - - jsonConfig := new(JsonConfig) - if err := json.Unmarshal(data, jsonConfig); err != nil { - return errors.New("Point: Failed to parse inbound config: " + err.Error()) - } - this.Port = v2net.Port(jsonConfig.Port) - this.ListenOn = v2net.AnyIP - if jsonConfig.Listen != nil { - if jsonConfig.Listen.AsAddress().Family().IsDomain() { - return errors.New("Point: Unable to listen on domain address: " + jsonConfig.Listen.AsAddress().Domain()) - } - this.ListenOn = jsonConfig.Listen.AsAddress() - } - if jsonConfig.StreamSetting != nil { - this.StreamSettings = jsonConfig.StreamSetting - } - - this.Protocol = jsonConfig.Protocol - this.Settings = jsonConfig.Settings - this.AllowPassiveConnection = jsonConfig.AllowPassive - return nil -} - -func (this *OutboundConnectionConfig) UnmarshalJSON(data []byte) error { - type JsonConnectionConfig struct { - Protocol string `json:"protocol"` - SendThrough *v2net.IPOrDomain `json:"sendThrough"` - StreamSetting *internet.StreamConfig `json:"streamSettings"` - Settings json.RawMessage `json:"settings"` - } - jsonConfig := new(JsonConnectionConfig) - if err := json.Unmarshal(data, jsonConfig); err != nil { - return errors.New("Point: Failed to parse outbound config: " + err.Error()) - } - this.Protocol = jsonConfig.Protocol - this.Settings = jsonConfig.Settings - - if jsonConfig.SendThrough != nil { - address := jsonConfig.SendThrough.AsAddress() - if address.Family().IsDomain() { - return errors.New("Point: Unable to send through: " + address.String()) - } - this.SendThrough = address - } - if jsonConfig.StreamSetting != nil { - this.StreamSettings = jsonConfig.StreamSetting - } - return nil -} - -func (this *InboundDetourAllocationConfig) UnmarshalJSON(data []byte) error { - type JsonInboundDetourAllocationConfig struct { - Strategy string `json:"strategy"` - Concurrency int `json:"concurrency"` - RefreshMin int `json:"refresh"` - } - jsonConfig := new(JsonInboundDetourAllocationConfig) - if err := json.Unmarshal(data, jsonConfig); err != nil { - return errors.New("Point: Failed to parse inbound detour allocation config: " + err.Error()) - } - this.Strategy = jsonConfig.Strategy - this.Concurrency = jsonConfig.Concurrency - this.Refresh = jsonConfig.RefreshMin - if this.Strategy == AllocationStrategyRandom { - if this.Refresh == 0 { - this.Refresh = 5 - } - if this.Concurrency == 0 { - this.Concurrency = 3 - } - } - if this.Refresh == 0 { - this.Refresh = DefaultRefreshMinute - } - return nil -} - -func (this *InboundDetourConfig) UnmarshalJSON(data []byte) error { - type JsonInboundDetourConfig struct { - Protocol string `json:"protocol"` - PortRange *v2net.PortRange `json:"port"` - ListenOn *v2net.IPOrDomain `json:"listen"` - Settings json.RawMessage `json:"settings"` - Tag string `json:"tag"` - Allocation *InboundDetourAllocationConfig `json:"allocate"` - StreamSetting *internet.StreamConfig `json:"streamSettings"` - AllowPassive bool `json:"allowPassive"` - } - jsonConfig := new(JsonInboundDetourConfig) - if err := json.Unmarshal(data, jsonConfig); err != nil { - return errors.New("Point: Failed to parse inbound detour config: " + err.Error()) - } - if jsonConfig.PortRange == nil { - log.Error("Point: Port range not specified in InboundDetour.") - return common.ErrBadConfiguration - } - this.ListenOn = v2net.AnyIP - if jsonConfig.ListenOn != nil { - if jsonConfig.ListenOn.AsAddress().Family().IsDomain() { - return errors.New("Point: Unable to listen on domain address: " + jsonConfig.ListenOn.AsAddress().Domain()) - } - this.ListenOn = jsonConfig.ListenOn.AsAddress() - } - this.Protocol = jsonConfig.Protocol - this.PortRange = *jsonConfig.PortRange - this.Settings = jsonConfig.Settings - this.Tag = jsonConfig.Tag - this.Allocation = jsonConfig.Allocation - if this.Allocation == nil { - this.Allocation = &InboundDetourAllocationConfig{ - Strategy: AllocationStrategyAlways, - Refresh: DefaultRefreshMinute, - } - } - if jsonConfig.StreamSetting != nil { - this.StreamSettings = jsonConfig.StreamSetting - } - this.AllowPassiveConnection = jsonConfig.AllowPassive - return nil -} - -func (this *OutboundDetourConfig) UnmarshalJSON(data []byte) error { - type JsonOutboundDetourConfig struct { - Protocol string `json:"protocol"` - SendThrough *v2net.IPOrDomain `json:"sendThrough"` - Tag string `json:"tag"` - Settings json.RawMessage `json:"settings"` - StreamSetting *internet.StreamConfig `json:"streamSettings"` - } - jsonConfig := new(JsonOutboundDetourConfig) - if err := json.Unmarshal(data, jsonConfig); err != nil { - return errors.New("Point: Failed to parse outbound detour config: " + err.Error()) - } - this.Protocol = jsonConfig.Protocol - this.Tag = jsonConfig.Tag - this.Settings = jsonConfig.Settings - - if jsonConfig.SendThrough != nil { - address := jsonConfig.SendThrough.AsAddress() - if address.Family().IsDomain() { - return errors.New("Point: Unable to send through: " + address.String()) - } - this.SendThrough = address - } - - if jsonConfig.StreamSetting != nil { - this.StreamSettings = jsonConfig.StreamSetting - } - return nil -} - -func JsonLoadConfig(input io.Reader) (*Config, error) { - jsonConfig := &Config{} - decoder := json.NewDecoder(input) - err := decoder.Decode(jsonConfig) - if err != nil { - log.Error("Point: Failed to load server config: ", err) - return nil, err - } - - return jsonConfig, err -} - -func init() { - configLoader = JsonLoadConfig -} diff --git a/config_json_test.go b/config_json_test.go deleted file mode 100644 index bd4518c9f..000000000 --- a/config_json_test.go +++ /dev/null @@ -1,81 +0,0 @@ -// +build json - -package core_test - -import ( - "encoding/json" - "io" - "os" - "path/filepath" - "testing" - - . "v2ray.com/core" - - "v2ray.com/core/testing/assert" -) - -func OpenFile(file string, assert *assert.Assert) io.Reader { - input, err := os.Open(file) - assert.Error(err).IsNil() - return input -} - -func TestClientSampleConfig(t *testing.T) { - assert := assert.On(t) - - GOPATH := os.Getenv("GOPATH") - baseDir := filepath.Join(GOPATH, "src", "v2ray.com", "core", "tools", "release", "config") - - pointConfig, err := LoadConfig(OpenFile(filepath.Join(baseDir, "vpoint_socks_vmess.json"), assert)) - assert.Error(err).IsNil() - - assert.Pointer(pointConfig.InboundConfig).IsNotNil() - assert.Port(pointConfig.InboundConfig.Port).IsValid() - assert.Pointer(pointConfig.OutboundConfig).IsNotNil() - - assert.String(pointConfig.InboundConfig.Protocol).Equals("socks") - assert.Pointer(pointConfig.InboundConfig.Settings).IsNotNil() - - assert.String(pointConfig.OutboundConfig.Protocol).Equals("vmess") - assert.Pointer(pointConfig.OutboundConfig.Settings).IsNotNil() -} - -func TestServerSampleConfig(t *testing.T) { - assert := assert.On(t) - - GOPATH := os.Getenv("GOPATH") - baseDir := filepath.Join(GOPATH, "src", "v2ray.com", "core", "tools", "release", "config") - - pointConfig, err := LoadConfig(OpenFile(filepath.Join(baseDir, "vpoint_vmess_freedom.json"), assert)) - assert.Error(err).IsNil() - - assert.Pointer(pointConfig.InboundConfig).IsNotNil() - assert.Port(pointConfig.InboundConfig.Port).IsValid() - assert.Pointer(pointConfig.OutboundConfig).IsNotNil() - - assert.String(pointConfig.InboundConfig.Protocol).Equals("vmess") - assert.Pointer(pointConfig.InboundConfig.Settings).IsNotNil() - - assert.String(pointConfig.OutboundConfig.Protocol).Equals("freedom") - assert.Pointer(pointConfig.OutboundConfig.Settings).IsNotNil() -} - -func TestDefaultValueOfRandomAllocation(t *testing.T) { - assert := assert.On(t) - - rawJson := `{ - "protocol": "vmess", - "port": 1, - "settings": {}, - "allocate": { - "strategy": "random" - } - }` - - inboundDetourConfig := new(InboundDetourConfig) - err := json.Unmarshal([]byte(rawJson), inboundDetourConfig) - assert.Error(err).IsNil() - assert.String(inboundDetourConfig.Allocation.Strategy).Equals(AllocationStrategyRandom) - assert.Int(inboundDetourConfig.Allocation.Concurrency).Equals(3) - assert.Int(inboundDetourConfig.Allocation.Refresh).Equals(5) -} diff --git a/inbound_detour_always.go b/inbound_detour_always.go index 90866fc81..76eb481fa 100644 --- a/inbound_detour_always.go +++ b/inbound_detour_always.go @@ -12,11 +12,11 @@ import ( // Handler for inbound detour connections. type InboundDetourHandlerAlways struct { space app.Space - config *InboundDetourConfig + config *InboundConnectionConfig ich []proxy.InboundHandler } -func NewInboundDetourHandlerAlways(space app.Space, config *InboundDetourConfig) (*InboundDetourHandlerAlways, error) { +func NewInboundDetourHandlerAlways(space app.Space, config *InboundConnectionConfig) (*InboundDetourHandlerAlways, error) { handler := &InboundDetourHandlerAlways{ space: space, config: config, @@ -24,9 +24,12 @@ func NewInboundDetourHandlerAlways(space app.Space, config *InboundDetourConfig) ports := config.PortRange handler.ich = make([]proxy.InboundHandler, 0, ports.To-ports.From+1) for i := ports.FromPort(); i <= ports.ToPort(); i++ { - ichConfig := config.Settings + ichConfig, err := config.GetTypedSettings() + if err != nil { + return nil, err + } ich, err := proxyregistry.CreateInboundHandler(config.Protocol, space, ichConfig, &proxy.InboundHandlerMeta{ - Address: config.ListenOn, + Address: config.ListenOn.AsAddress(), Port: i, Tag: config.Tag, StreamSettings: config.StreamSettings, @@ -43,7 +46,7 @@ func NewInboundDetourHandlerAlways(space app.Space, config *InboundDetourConfig) func (this *InboundDetourHandlerAlways) GetConnectionHandler() (proxy.InboundHandler, int) { ich := this.ich[dice.Roll(len(this.ich))] - return ich, this.config.Allocation.Refresh + return ich, int(this.config.GetAllocationStrategyValue().Refresh.GetValue()) } func (this *InboundDetourHandlerAlways) Close() { diff --git a/inbound_detour_dynamic.go b/inbound_detour_dynamic.go index 0a64559df..3dd289e41 100644 --- a/inbound_detour_dynamic.go +++ b/inbound_detour_dynamic.go @@ -16,24 +16,24 @@ import ( type InboundDetourHandlerDynamic struct { sync.RWMutex space app.Space - config *InboundDetourConfig + config *InboundConnectionConfig portsInUse map[v2net.Port]bool ichs []proxy.InboundHandler ich2Recyle []proxy.InboundHandler lastRefresh time.Time } -func NewInboundDetourHandlerDynamic(space app.Space, config *InboundDetourConfig) (*InboundDetourHandlerDynamic, error) { +func NewInboundDetourHandlerDynamic(space app.Space, config *InboundConnectionConfig) (*InboundDetourHandlerDynamic, error) { handler := &InboundDetourHandlerDynamic{ space: space, config: config, portsInUse: make(map[v2net.Port]bool), } - handler.ichs = make([]proxy.InboundHandler, config.Allocation.Concurrency) + handler.ichs = make([]proxy.InboundHandler, config.GetAllocationStrategyValue().Concurrency.GetValue()) // To test configuration ich, err := proxyregistry.CreateInboundHandler(config.Protocol, space, config.Settings, &proxy.InboundHandlerMeta{ - Address: config.ListenOn, + Address: config.ListenOn.AsAddress(), Port: 0, Tag: config.Tag, StreamSettings: config.StreamSettings, @@ -64,7 +64,7 @@ func (this *InboundDetourHandlerDynamic) GetConnectionHandler() (proxy.InboundHa this.RLock() defer this.RUnlock() ich := this.ichs[dice.Roll(len(this.ichs))] - until := this.config.Allocation.Refresh - int((time.Now().Unix()-this.lastRefresh.Unix())/60/1000) + until := int(this.config.GetAllocationStrategyValue().Refresh.GetValue()) - int((time.Now().Unix()-this.lastRefresh.Unix())/60/1000) if until < 0 { until = 0 } @@ -98,13 +98,13 @@ func (this *InboundDetourHandlerDynamic) refresh() error { config := this.config this.ich2Recyle = this.ichs - newIchs := make([]proxy.InboundHandler, config.Allocation.Concurrency) + newIchs := make([]proxy.InboundHandler, config.GetAllocationStrategyValue().Concurrency.GetValue()) for idx := range newIchs { err := retry.Timed(5, 100).On(func() error { port := this.pickUnusedPort() ich, err := proxyregistry.CreateInboundHandler(config.Protocol, this.space, config.Settings, &proxy.InboundHandlerMeta{ - Address: config.ListenOn, Port: port, Tag: config.Tag, StreamSettings: config.StreamSettings}) + Address: config.ListenOn.AsAddress(), Port: port, Tag: config.Tag, StreamSettings: config.StreamSettings}) if err != nil { delete(this.portsInUse, port) return err @@ -140,7 +140,7 @@ func (this *InboundDetourHandlerDynamic) Start() error { go func() { for { - time.Sleep(time.Duration(this.config.Allocation.Refresh)*time.Minute - 1) + time.Sleep(time.Duration(this.config.GetAllocationStrategyValue().Refresh.GetValue())*time.Minute - 1) this.RecyleHandles() err := this.refresh() if err != nil { diff --git a/proxy/registry/handler_cache.go b/proxy/registry/handler_cache.go index f042bf52b..85ecd8ea5 100644 --- a/proxy/registry/handler_cache.go +++ b/proxy/registry/handler_cache.go @@ -42,7 +42,7 @@ func MustRegisterOutboundHandlerCreator(name string, creator OutboundHandlerFact } } -func CreateInboundHandler(name string, space app.Space, rawConfig []byte, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) { +func CreateInboundHandler(name string, space app.Space, config interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) { creator, found := inboundFactories[name] if !found { return nil, common.ErrObjectNotFound @@ -57,17 +57,10 @@ func CreateInboundHandler(name string, space app.Space, rawConfig []byte, meta * } } - if len(rawConfig) > 0 { - proxyConfig, err := CreateInboundConfig(name, rawConfig) - if err != nil { - return nil, err - } - return creator.Create(space, proxyConfig, meta) - } - return creator.Create(space, nil, meta) + return creator.Create(space, config, meta) } -func CreateOutboundHandler(name string, space app.Space, rawConfig []byte, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) { +func CreateOutboundHandler(name string, space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) { creator, found := outboundFactories[name] if !found { return nil, common.ErrObjectNotFound @@ -82,13 +75,5 @@ func CreateOutboundHandler(name string, space app.Space, rawConfig []byte, meta } } - if len(rawConfig) > 0 { - proxyConfig, err := CreateOutboundConfig(name, rawConfig) - if err != nil { - return nil, err - } - return creator.Create(space, proxyConfig, meta) - } - - return creator.Create(space, nil, meta) + return creator.Create(space, config, meta) } diff --git a/v2ray.go b/v2ray.go index 47528acc8..7c846e0de 100644 --- a/v2ray.go +++ b/v2ray.go @@ -9,44 +9,33 @@ import ( "v2ray.com/core/app/router" "v2ray.com/core/common" "v2ray.com/core/common/log" - v2net "v2ray.com/core/common/net" - "v2ray.com/core/common/retry" "v2ray.com/core/proxy" proxyregistry "v2ray.com/core/proxy/registry" ) // Point shell of V2Ray. type Point struct { - port v2net.Port - listen v2net.Address - ich proxy.InboundHandler - och proxy.OutboundHandler - idh []InboundDetourHandler - taggedIdh map[string]InboundDetourHandler - odh map[string]proxy.OutboundHandler - router *router.Router - space app.Space + inboundHandlers []InboundDetourHandler + taggedInboundHandlers map[string]InboundDetourHandler + + outboundHandlers []proxy.OutboundHandler + taggedOutboundHandlers map[string]proxy.OutboundHandler + + router *router.Router + space app.Space } // NewPoint returns a new Point server based on given configuration. // The server is not started at this point. func NewPoint(pConfig *Config) (*Point, error) { var vpoint = new(Point) - vpoint.port = pConfig.InboundConfig.Port - if vpoint.port == 0 { - vpoint.port = pConfig.Port // Backward compatibility + + if err := pConfig.Transport.Apply(); err != nil { + return nil, err } - vpoint.listen = pConfig.InboundConfig.ListenOn - - if pConfig.TransportConfig != nil { - pConfig.TransportConfig.Apply() - } - - if pConfig.LogConfig != nil { - if err := pConfig.LogConfig.Apply(); err != nil { - return nil, err - } + if err := pConfig.Log.Apply(); err != nil { + return nil, err } vpoint.space = app.NewSpace() @@ -55,13 +44,13 @@ func NewPoint(pConfig *Config) (*Point, error) { outboundHandlerManager := proxyman.NewDefaultOutboundHandlerManager() vpoint.space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, outboundHandlerManager) - dnsConfig := pConfig.DNSConfig + dnsConfig := pConfig.Dns if dnsConfig != nil { dnsServer := dns.NewCacheServer(vpoint.space, dnsConfig) vpoint.space.BindApp(dns.APP_ID, dnsServer) } - routerConfig := pConfig.RouterConfig + routerConfig := pConfig.Router if routerConfig != nil { r := router.NewRouter(routerConfig, vpoint.space) vpoint.space.BindApp(router.APP_ID, r) @@ -70,84 +59,54 @@ func NewPoint(pConfig *Config) (*Point, error) { vpoint.space.BindApp(dispatcher.APP_ID, dispatchers.NewDefaultDispatcher(vpoint.space)) - ichConfig := pConfig.InboundConfig.Settings - ich, err := proxyregistry.CreateInboundHandler( - pConfig.InboundConfig.Protocol, vpoint.space, ichConfig, &proxy.InboundHandlerMeta{ - Tag: "system.inbound", - Address: pConfig.InboundConfig.ListenOn, - Port: vpoint.port, - StreamSettings: pConfig.InboundConfig.StreamSettings, - AllowPassiveConnection: pConfig.InboundConfig.AllowPassiveConnection, - }) - if err != nil { - log.Error("Failed to create inbound connection handler: ", err) - return nil, err - } - vpoint.ich = ich - - ochConfig := pConfig.OutboundConfig.Settings - och, err := proxyregistry.CreateOutboundHandler( - pConfig.OutboundConfig.Protocol, vpoint.space, ochConfig, &proxy.OutboundHandlerMeta{ - Tag: "system.outbound", - Address: pConfig.OutboundConfig.SendThrough, - StreamSettings: pConfig.OutboundConfig.StreamSettings, - }) - if err != nil { - log.Error("Failed to create outbound connection handler: ", err) - return nil, err - } - vpoint.och = och - outboundHandlerManager.SetDefaultHandler(och) - - vpoint.taggedIdh = make(map[string]InboundDetourHandler) - detours := pConfig.InboundDetours - if len(detours) > 0 { - vpoint.idh = make([]InboundDetourHandler, len(detours)) - for idx, detourConfig := range detours { - allocConfig := detourConfig.Allocation - var detourHandler InboundDetourHandler - switch allocConfig.Strategy { - case AllocationStrategyAlways: - dh, err := NewInboundDetourHandlerAlways(vpoint.space, detourConfig) - if err != nil { - log.Error("Point: Failed to create detour handler: ", err) - return nil, common.ErrBadConfiguration - } - detourHandler = dh - case AllocationStrategyRandom: - dh, err := NewInboundDetourHandlerDynamic(vpoint.space, detourConfig) - if err != nil { - log.Error("Point: Failed to create detour handler: ", err) - return nil, common.ErrBadConfiguration - } - detourHandler = dh - default: - log.Error("Point: Unknown allocation strategy: ", allocConfig.Strategy) + vpoint.inboundHandlers = make([]InboundDetourHandler, 8) + vpoint.taggedInboundHandlers = make(map[string]InboundDetourHandler) + for _, inbound := range pConfig.Inbound { + allocConfig := inbound.GetAllocationStrategyValue() + var inboundHandler InboundDetourHandler + switch allocConfig.Type { + case AllocationStrategy_Always: + dh, err := NewInboundDetourHandlerAlways(vpoint.space, inbound) + if err != nil { + log.Error("Point: Failed to create detour handler: ", err) return nil, common.ErrBadConfiguration } - vpoint.idh[idx] = detourHandler - if len(detourConfig.Tag) > 0 { - vpoint.taggedIdh[detourConfig.Tag] = detourHandler + inboundHandler = dh + case AllocationStrategy_Random: + dh, err := NewInboundDetourHandlerDynamic(vpoint.space, inbound) + if err != nil { + log.Error("Point: Failed to create detour handler: ", err) + return nil, common.ErrBadConfiguration } + inboundHandler = dh + default: + log.Error("Point: Unknown allocation strategy: ", allocConfig.Type) + return nil, common.ErrBadConfiguration + } + vpoint.inboundHandlers = append(vpoint.inboundHandlers, inboundHandler) + if len(inbound.Tag) > 0 { + vpoint.taggedInboundHandlers[inbound.Tag] = inboundHandler } } - outboundDetours := pConfig.OutboundDetours - if len(outboundDetours) > 0 { - vpoint.odh = make(map[string]proxy.OutboundHandler) - for _, detourConfig := range outboundDetours { - detourHandler, err := proxyregistry.CreateOutboundHandler( - detourConfig.Protocol, vpoint.space, detourConfig.Settings, &proxy.OutboundHandlerMeta{ - Tag: detourConfig.Tag, - Address: detourConfig.SendThrough, - StreamSettings: detourConfig.StreamSettings, - }) - if err != nil { - log.Error("Point: Failed to create detour outbound connection handler: ", err) - return nil, err - } - vpoint.odh[detourConfig.Tag] = detourHandler - outboundHandlerManager.SetHandler(detourConfig.Tag, detourHandler) + vpoint.outboundHandlers = make([]proxy.OutboundHandler, 8) + vpoint.taggedOutboundHandlers = make(map[string]proxy.OutboundHandler) + for idx, outbound := range pConfig.Outbound { + outboundHandler, err := proxyregistry.CreateOutboundHandler( + outbound.Protocol, vpoint.space, outbound.Settings, &proxy.OutboundHandlerMeta{ + Tag: outbound.Tag, + Address: outbound.SendThrough.AsAddress(), + StreamSettings: outbound.StreamSettings, + }) + if err != nil { + log.Error("Point: Failed to create detour outbound connection handler: ", err) + return nil, err + } + if idx == 0 { + outboundHandlerManager.SetDefaultHandler(outboundHandler) + } + if len(outbound.Tag) > 0 { + outboundHandlerManager.SetHandler(outbound.Tag, outboundHandler) } } @@ -159,44 +118,27 @@ func NewPoint(pConfig *Config) (*Point, error) { } func (this *Point) Close() { - this.ich.Close() - for _, idh := range this.idh { - idh.Close() + for _, inbound := range this.inboundHandlers { + inbound.Close() } } // Start starts the Point server, and return any error during the process. // In the case of any errors, the state of the server is unpredicatable. func (this *Point) Start() error { - if this.port <= 0 { - log.Error("Point: Invalid port ", this.port) - return common.ErrBadConfiguration - } - - err := retry.Timed(100 /* times */, 100 /* ms */).On(func() error { - err := this.ich.Start() - if err != nil { - return err - } - log.Warning("Point: started on port ", this.port) - return nil - }) - if err != nil { - return err - } - - for _, detourHandler := range this.idh { - err := detourHandler.Start() + for _, inbound := range this.inboundHandlers { + err := inbound.Start() if err != nil { return err } } + log.Warning("V2Ray started.") return nil } func (this *Point) GetHandler(tag string) (proxy.InboundHandler, int) { - handler, found := this.taggedIdh[tag] + handler, found := this.taggedInboundHandlers[tag] if !found { log.Warning("Point: Unable to find an inbound handler with tag: ", tag) return nil, 0