Browse Source

use custom loading rules for router

Shelikhoo 4 years ago
parent
commit
89d9eba1a9
4 changed files with 424 additions and 74 deletions
  1. 319 68
      app/router/config.pb.go
  2. 44 1
      app/router/config.proto
  3. 50 2
      app/router/router.go
  4. 11 3
      infra/conf/cfgcommon/common.go

+ 319 - 68
app/router/config.pb.go

@@ -701,20 +701,209 @@ func (x *Config) GetBalancingRule() []*BalancingRule {
 	return nil
 	return nil
 }
 }
 
 
+type SimplifiedRoutingRule struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Types that are assignable to TargetTag:
+	//	*SimplifiedRoutingRule_Tag
+	//	*SimplifiedRoutingRule_BalancingTag
+	TargetTag isSimplifiedRoutingRule_TargetTag `protobuf_oneof:"target_tag"`
+	// List of domains for target domain matching.
+	Domain []*routercommon.Domain `protobuf:"bytes,2,rep,name=domain,proto3" json:"domain,omitempty"`
+	// List of GeoIPs for target IP address matching. If this entry exists, the
+	// cidr above will have no effect. GeoIP fields with the same country code are
+	// supposed to contain exactly same content. They will be merged during
+	// runtime. For customized GeoIPs, please leave country code empty.
+	Geoip []*routercommon.GeoIP `protobuf:"bytes,10,rep,name=geoip,proto3" json:"geoip,omitempty"`
+	// List of ports.
+	PortList string `protobuf:"bytes,14,opt,name=port_list,json=portList,proto3" json:"port_list,omitempty"`
+	// List of networks for matching.
+	Networks string `protobuf:"bytes,13,opt,name=networks,proto3" json:"networks,omitempty"`
+	// List of GeoIPs for source IP address matching. If this entry exists, the
+	// source_cidr above will have no effect.
+	SourceGeoip []*routercommon.GeoIP `protobuf:"bytes,11,rep,name=source_geoip,json=sourceGeoip,proto3" json:"source_geoip,omitempty"`
+	// List of ports for source port matching.
+	SourcePortList string   `protobuf:"bytes,16,opt,name=source_port_list,json=sourcePortList,proto3" json:"source_port_list,omitempty"`
+	UserEmail      []string `protobuf:"bytes,7,rep,name=user_email,json=userEmail,proto3" json:"user_email,omitempty"`
+	InboundTag     []string `protobuf:"bytes,8,rep,name=inbound_tag,json=inboundTag,proto3" json:"inbound_tag,omitempty"`
+	Protocol       []string `protobuf:"bytes,9,rep,name=protocol,proto3" json:"protocol,omitempty"`
+	Attributes     string   `protobuf:"bytes,15,opt,name=attributes,proto3" json:"attributes,omitempty"`
+	DomainMatcher  string   `protobuf:"bytes,17,opt,name=domain_matcher,json=domainMatcher,proto3" json:"domain_matcher,omitempty"`
+	// geo_domain instruct simplified config loader to load geo domain rule and fill in domain field.
+	GeoDomain []*routercommon.GeoSite `protobuf:"bytes,68001,rep,name=geo_domain,json=geoDomain,proto3" json:"geo_domain,omitempty"`
+}
+
+func (x *SimplifiedRoutingRule) Reset() {
+	*x = SimplifiedRoutingRule{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_app_router_config_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SimplifiedRoutingRule) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SimplifiedRoutingRule) ProtoMessage() {}
+
+func (x *SimplifiedRoutingRule) ProtoReflect() protoreflect.Message {
+	mi := &file_app_router_config_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SimplifiedRoutingRule.ProtoReflect.Descriptor instead.
+func (*SimplifiedRoutingRule) Descriptor() ([]byte, []int) {
+	return file_app_router_config_proto_rawDescGZIP(), []int{7}
+}
+
+func (m *SimplifiedRoutingRule) GetTargetTag() isSimplifiedRoutingRule_TargetTag {
+	if m != nil {
+		return m.TargetTag
+	}
+	return nil
+}
+
+func (x *SimplifiedRoutingRule) GetTag() string {
+	if x, ok := x.GetTargetTag().(*SimplifiedRoutingRule_Tag); ok {
+		return x.Tag
+	}
+	return ""
+}
+
+func (x *SimplifiedRoutingRule) GetBalancingTag() string {
+	if x, ok := x.GetTargetTag().(*SimplifiedRoutingRule_BalancingTag); ok {
+		return x.BalancingTag
+	}
+	return ""
+}
+
+func (x *SimplifiedRoutingRule) GetDomain() []*routercommon.Domain {
+	if x != nil {
+		return x.Domain
+	}
+	return nil
+}
+
+func (x *SimplifiedRoutingRule) GetGeoip() []*routercommon.GeoIP {
+	if x != nil {
+		return x.Geoip
+	}
+	return nil
+}
+
+func (x *SimplifiedRoutingRule) GetPortList() string {
+	if x != nil {
+		return x.PortList
+	}
+	return ""
+}
+
+func (x *SimplifiedRoutingRule) GetNetworks() string {
+	if x != nil {
+		return x.Networks
+	}
+	return ""
+}
+
+func (x *SimplifiedRoutingRule) GetSourceGeoip() []*routercommon.GeoIP {
+	if x != nil {
+		return x.SourceGeoip
+	}
+	return nil
+}
+
+func (x *SimplifiedRoutingRule) GetSourcePortList() string {
+	if x != nil {
+		return x.SourcePortList
+	}
+	return ""
+}
+
+func (x *SimplifiedRoutingRule) GetUserEmail() []string {
+	if x != nil {
+		return x.UserEmail
+	}
+	return nil
+}
+
+func (x *SimplifiedRoutingRule) GetInboundTag() []string {
+	if x != nil {
+		return x.InboundTag
+	}
+	return nil
+}
+
+func (x *SimplifiedRoutingRule) GetProtocol() []string {
+	if x != nil {
+		return x.Protocol
+	}
+	return nil
+}
+
+func (x *SimplifiedRoutingRule) GetAttributes() string {
+	if x != nil {
+		return x.Attributes
+	}
+	return ""
+}
+
+func (x *SimplifiedRoutingRule) GetDomainMatcher() string {
+	if x != nil {
+		return x.DomainMatcher
+	}
+	return ""
+}
+
+func (x *SimplifiedRoutingRule) GetGeoDomain() []*routercommon.GeoSite {
+	if x != nil {
+		return x.GeoDomain
+	}
+	return nil
+}
+
+type isSimplifiedRoutingRule_TargetTag interface {
+	isSimplifiedRoutingRule_TargetTag()
+}
+
+type SimplifiedRoutingRule_Tag struct {
+	// Tag of outbound that this rule is pointing to.
+	Tag string `protobuf:"bytes,1,opt,name=tag,proto3,oneof"`
+}
+
+type SimplifiedRoutingRule_BalancingTag struct {
+	// Tag of routing balancer.
+	BalancingTag string `protobuf:"bytes,12,opt,name=balancing_tag,json=balancingTag,proto3,oneof"`
+}
+
+func (*SimplifiedRoutingRule_Tag) isSimplifiedRoutingRule_TargetTag() {}
+
+func (*SimplifiedRoutingRule_BalancingTag) isSimplifiedRoutingRule_TargetTag() {}
+
 type SimplifiedConfig struct {
 type SimplifiedConfig struct {
 	state         protoimpl.MessageState
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 	unknownFields protoimpl.UnknownFields
 
 
-	DomainStrategy DomainStrategy   `protobuf:"varint,1,opt,name=domain_strategy,json=domainStrategy,proto3,enum=v2ray.core.app.router.DomainStrategy" json:"domain_strategy,omitempty"`
-	Rule           []*RoutingRule   `protobuf:"bytes,2,rep,name=rule,proto3" json:"rule,omitempty"`
-	BalancingRule  []*BalancingRule `protobuf:"bytes,3,rep,name=balancing_rule,json=balancingRule,proto3" json:"balancing_rule,omitempty"`
+	DomainStrategy DomainStrategy           `protobuf:"varint,1,opt,name=domain_strategy,json=domainStrategy,proto3,enum=v2ray.core.app.router.DomainStrategy" json:"domain_strategy,omitempty"`
+	Rule           []*SimplifiedRoutingRule `protobuf:"bytes,2,rep,name=rule,proto3" json:"rule,omitempty"`
+	BalancingRule  []*BalancingRule         `protobuf:"bytes,3,rep,name=balancing_rule,json=balancingRule,proto3" json:"balancing_rule,omitempty"`
 }
 }
 
 
 func (x *SimplifiedConfig) Reset() {
 func (x *SimplifiedConfig) Reset() {
 	*x = SimplifiedConfig{}
 	*x = SimplifiedConfig{}
 	if protoimpl.UnsafeEnabled {
 	if protoimpl.UnsafeEnabled {
-		mi := &file_app_router_config_proto_msgTypes[7]
+		mi := &file_app_router_config_proto_msgTypes[8]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 		ms.StoreMessageInfo(mi)
 	}
 	}
@@ -727,7 +916,7 @@ func (x *SimplifiedConfig) String() string {
 func (*SimplifiedConfig) ProtoMessage() {}
 func (*SimplifiedConfig) ProtoMessage() {}
 
 
 func (x *SimplifiedConfig) ProtoReflect() protoreflect.Message {
 func (x *SimplifiedConfig) ProtoReflect() protoreflect.Message {
-	mi := &file_app_router_config_proto_msgTypes[7]
+	mi := &file_app_router_config_proto_msgTypes[8]
 	if protoimpl.UnsafeEnabled && x != nil {
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 		if ms.LoadMessageInfo() == nil {
@@ -740,7 +929,7 @@ func (x *SimplifiedConfig) ProtoReflect() protoreflect.Message {
 
 
 // Deprecated: Use SimplifiedConfig.ProtoReflect.Descriptor instead.
 // Deprecated: Use SimplifiedConfig.ProtoReflect.Descriptor instead.
 func (*SimplifiedConfig) Descriptor() ([]byte, []int) {
 func (*SimplifiedConfig) Descriptor() ([]byte, []int) {
-	return file_app_router_config_proto_rawDescGZIP(), []int{7}
+	return file_app_router_config_proto_rawDescGZIP(), []int{8}
 }
 }
 
 
 func (x *SimplifiedConfig) GetDomainStrategy() DomainStrategy {
 func (x *SimplifiedConfig) GetDomainStrategy() DomainStrategy {
@@ -750,7 +939,7 @@ func (x *SimplifiedConfig) GetDomainStrategy() DomainStrategy {
 	return DomainStrategy_AsIs
 	return DomainStrategy_AsIs
 }
 }
 
 
-func (x *SimplifiedConfig) GetRule() []*RoutingRule {
+func (x *SimplifiedConfig) GetRule() []*SimplifiedRoutingRule {
 	if x != nil {
 	if x != nil {
 		return x.Rule
 		return x.Rule
 	}
 	}
@@ -901,35 +1090,76 @@ var file_app_router_config_proto_rawDesc = []byte{
 	0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e,
 	0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e,
 	0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e,
 	0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e,
 	0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62,
 	0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62,
-	0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x82, 0x02, 0x0a,
-	0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x12, 0x4e, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61,
-	0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72,
-	0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74,
-	0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
-	0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
-	0x79, 0x12, 0x36, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32,
-	0x22, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70,
-	0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52,
-	0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x62, 0x61, 0x6c,
-	0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28,
-	0x0b, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61,
-	0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63,
-	0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69,
-	0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, 0x08, 0x12, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65,
-	0x72, 0x2a, 0x47, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74,
-	0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x73, 0x49, 0x73, 0x10, 0x00, 0x12, 0x09, 0x0a,
-	0x05, 0x55, 0x73, 0x65, 0x49, 0x70, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x70, 0x49, 0x66,
-	0x4e, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x70,
-	0x4f, 0x6e, 0x44, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x10, 0x03, 0x42, 0x60, 0x0a, 0x19, 0x63, 0x6f,
-	0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70,
-	0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75,
-	0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61,
-	0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f,
-	0x75, 0x74, 0x65, 0x72, 0xaa, 0x02, 0x15, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72,
-	0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x33,
+	0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x87, 0x05, 0x0a,
+	0x15, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69,
+	0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x25, 0x0a, 0x0d, 0x62, 0x61,
+	0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28,
+	0x09, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x54, 0x61,
+	0x67, 0x12, 0x42, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61,
+	0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72,
+	0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x64,
+	0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0a,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72,
+	0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75,
+	0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52,
+	0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c,
+	0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x72, 0x74, 0x4c,
+	0x69, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x18,
+	0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x12,
+	0x4c, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18,
+	0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f,
+	0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f,
+	0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50,
+	0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x28, 0x0a,
+	0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73,
+	0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50,
+	0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f,
+	0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65,
+	0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e,
+	0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x62,
+	0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x63, 0x6f, 0x6c, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x63, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
+	0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
+	0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x6d, 0x61,
+	0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x6f, 0x6d,
+	0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x4c, 0x0a, 0x0a, 0x67, 0x65,
+	0x6f, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0xa1, 0x93, 0x04, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x2b, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70,
+	0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63,
+	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x52, 0x09, 0x67,
+	0x65, 0x6f, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x42, 0x0c, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67,
+	0x65, 0x74, 0x5f, 0x74, 0x61, 0x67, 0x22, 0x8c, 0x02, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c,
+	0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4e, 0x0a, 0x0f, 0x64,
+	0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72,
+	0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d,
+	0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d,
+	0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x40, 0x0a, 0x04, 0x72,
+	0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x32, 0x72, 0x61,
+	0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65,
+	0x72, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74,
+	0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x4b, 0x0a,
+	0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18,
+	0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f,
+	0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61,
+	0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c,
+	0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x09,
+	0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, 0x08, 0x12, 0x06, 0x72,
+	0x6f, 0x75, 0x74, 0x65, 0x72, 0x2a, 0x47, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53,
+	0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x73, 0x49, 0x73, 0x10,
+	0x00, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x49, 0x70, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c,
+	0x49, 0x70, 0x49, 0x66, 0x4e, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x02, 0x12, 0x0e,
+	0x0a, 0x0a, 0x49, 0x70, 0x4f, 0x6e, 0x44, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x10, 0x03, 0x42, 0x60,
+	0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65,
+	0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x29, 0x67,
+	0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f,
+	0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70,
+	0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0xaa, 0x02, 0x15, 0x56, 0x32, 0x52, 0x61, 0x79,
+	0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72,
+	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 }
 
 
 var (
 var (
@@ -945,7 +1175,7 @@ func file_app_router_config_proto_rawDescGZIP() []byte {
 }
 }
 
 
 var file_app_router_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
 var file_app_router_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_app_router_config_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
+var file_app_router_config_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
 var file_app_router_config_proto_goTypes = []interface{}{
 var file_app_router_config_proto_goTypes = []interface{}{
 	(DomainStrategy)(0),             // 0: v2ray.core.app.router.DomainStrategy
 	(DomainStrategy)(0),             // 0: v2ray.core.app.router.DomainStrategy
 	(*RoutingRule)(nil),             // 1: v2ray.core.app.router.RoutingRule
 	(*RoutingRule)(nil),             // 1: v2ray.core.app.router.RoutingRule
@@ -955,42 +1185,47 @@ var file_app_router_config_proto_goTypes = []interface{}{
 	(*StrategyLeastPingConfig)(nil), // 5: v2ray.core.app.router.StrategyLeastPingConfig
 	(*StrategyLeastPingConfig)(nil), // 5: v2ray.core.app.router.StrategyLeastPingConfig
 	(*StrategyLeastLoadConfig)(nil), // 6: v2ray.core.app.router.StrategyLeastLoadConfig
 	(*StrategyLeastLoadConfig)(nil), // 6: v2ray.core.app.router.StrategyLeastLoadConfig
 	(*Config)(nil),                  // 7: v2ray.core.app.router.Config
 	(*Config)(nil),                  // 7: v2ray.core.app.router.Config
-	(*SimplifiedConfig)(nil),        // 8: v2ray.core.app.router.SimplifiedConfig
-	(*routercommon.Domain)(nil),     // 9: v2ray.core.app.router.routercommon.Domain
-	(*routercommon.CIDR)(nil),       // 10: v2ray.core.app.router.routercommon.CIDR
-	(*routercommon.GeoIP)(nil),      // 11: v2ray.core.app.router.routercommon.GeoIP
-	(*net.PortRange)(nil),           // 12: v2ray.core.common.net.PortRange
-	(*net.PortList)(nil),            // 13: v2ray.core.common.net.PortList
-	(*net.NetworkList)(nil),         // 14: v2ray.core.common.net.NetworkList
-	(net.Network)(0),                // 15: v2ray.core.common.net.Network
-	(*routercommon.GeoSite)(nil),    // 16: v2ray.core.app.router.routercommon.GeoSite
-	(*anypb.Any)(nil),               // 17: google.protobuf.Any
+	(*SimplifiedRoutingRule)(nil),   // 8: v2ray.core.app.router.SimplifiedRoutingRule
+	(*SimplifiedConfig)(nil),        // 9: v2ray.core.app.router.SimplifiedConfig
+	(*routercommon.Domain)(nil),     // 10: v2ray.core.app.router.routercommon.Domain
+	(*routercommon.CIDR)(nil),       // 11: v2ray.core.app.router.routercommon.CIDR
+	(*routercommon.GeoIP)(nil),      // 12: v2ray.core.app.router.routercommon.GeoIP
+	(*net.PortRange)(nil),           // 13: v2ray.core.common.net.PortRange
+	(*net.PortList)(nil),            // 14: v2ray.core.common.net.PortList
+	(*net.NetworkList)(nil),         // 15: v2ray.core.common.net.NetworkList
+	(net.Network)(0),                // 16: v2ray.core.common.net.Network
+	(*routercommon.GeoSite)(nil),    // 17: v2ray.core.app.router.routercommon.GeoSite
+	(*anypb.Any)(nil),               // 18: google.protobuf.Any
 }
 }
 var file_app_router_config_proto_depIdxs = []int32{
 var file_app_router_config_proto_depIdxs = []int32{
-	9,  // 0: v2ray.core.app.router.RoutingRule.domain:type_name -> v2ray.core.app.router.routercommon.Domain
-	10, // 1: v2ray.core.app.router.RoutingRule.cidr:type_name -> v2ray.core.app.router.routercommon.CIDR
-	11, // 2: v2ray.core.app.router.RoutingRule.geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP
-	12, // 3: v2ray.core.app.router.RoutingRule.port_range:type_name -> v2ray.core.common.net.PortRange
-	13, // 4: v2ray.core.app.router.RoutingRule.port_list:type_name -> v2ray.core.common.net.PortList
-	14, // 5: v2ray.core.app.router.RoutingRule.network_list:type_name -> v2ray.core.common.net.NetworkList
-	15, // 6: v2ray.core.app.router.RoutingRule.networks:type_name -> v2ray.core.common.net.Network
-	10, // 7: v2ray.core.app.router.RoutingRule.source_cidr:type_name -> v2ray.core.app.router.routercommon.CIDR
-	11, // 8: v2ray.core.app.router.RoutingRule.source_geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP
-	13, // 9: v2ray.core.app.router.RoutingRule.source_port_list:type_name -> v2ray.core.common.net.PortList
-	16, // 10: v2ray.core.app.router.RoutingRule.geo_domain:type_name -> v2ray.core.app.router.routercommon.GeoSite
-	17, // 11: v2ray.core.app.router.BalancingRule.strategy_settings:type_name -> google.protobuf.Any
+	10, // 0: v2ray.core.app.router.RoutingRule.domain:type_name -> v2ray.core.app.router.routercommon.Domain
+	11, // 1: v2ray.core.app.router.RoutingRule.cidr:type_name -> v2ray.core.app.router.routercommon.CIDR
+	12, // 2: v2ray.core.app.router.RoutingRule.geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP
+	13, // 3: v2ray.core.app.router.RoutingRule.port_range:type_name -> v2ray.core.common.net.PortRange
+	14, // 4: v2ray.core.app.router.RoutingRule.port_list:type_name -> v2ray.core.common.net.PortList
+	15, // 5: v2ray.core.app.router.RoutingRule.network_list:type_name -> v2ray.core.common.net.NetworkList
+	16, // 6: v2ray.core.app.router.RoutingRule.networks:type_name -> v2ray.core.common.net.Network
+	11, // 7: v2ray.core.app.router.RoutingRule.source_cidr:type_name -> v2ray.core.app.router.routercommon.CIDR
+	12, // 8: v2ray.core.app.router.RoutingRule.source_geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP
+	14, // 9: v2ray.core.app.router.RoutingRule.source_port_list:type_name -> v2ray.core.common.net.PortList
+	17, // 10: v2ray.core.app.router.RoutingRule.geo_domain:type_name -> v2ray.core.app.router.routercommon.GeoSite
+	18, // 11: v2ray.core.app.router.BalancingRule.strategy_settings:type_name -> google.protobuf.Any
 	3,  // 12: v2ray.core.app.router.StrategyLeastLoadConfig.costs:type_name -> v2ray.core.app.router.StrategyWeight
 	3,  // 12: v2ray.core.app.router.StrategyLeastLoadConfig.costs:type_name -> v2ray.core.app.router.StrategyWeight
 	0,  // 13: v2ray.core.app.router.Config.domain_strategy:type_name -> v2ray.core.app.router.DomainStrategy
 	0,  // 13: v2ray.core.app.router.Config.domain_strategy:type_name -> v2ray.core.app.router.DomainStrategy
 	1,  // 14: v2ray.core.app.router.Config.rule:type_name -> v2ray.core.app.router.RoutingRule
 	1,  // 14: v2ray.core.app.router.Config.rule:type_name -> v2ray.core.app.router.RoutingRule
 	2,  // 15: v2ray.core.app.router.Config.balancing_rule:type_name -> v2ray.core.app.router.BalancingRule
 	2,  // 15: v2ray.core.app.router.Config.balancing_rule:type_name -> v2ray.core.app.router.BalancingRule
-	0,  // 16: v2ray.core.app.router.SimplifiedConfig.domain_strategy:type_name -> v2ray.core.app.router.DomainStrategy
-	1,  // 17: v2ray.core.app.router.SimplifiedConfig.rule:type_name -> v2ray.core.app.router.RoutingRule
-	2,  // 18: v2ray.core.app.router.SimplifiedConfig.balancing_rule:type_name -> v2ray.core.app.router.BalancingRule
-	19, // [19:19] is the sub-list for method output_type
-	19, // [19:19] is the sub-list for method input_type
-	19, // [19:19] is the sub-list for extension type_name
-	19, // [19:19] is the sub-list for extension extendee
-	0,  // [0:19] is the sub-list for field type_name
+	10, // 16: v2ray.core.app.router.SimplifiedRoutingRule.domain:type_name -> v2ray.core.app.router.routercommon.Domain
+	12, // 17: v2ray.core.app.router.SimplifiedRoutingRule.geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP
+	12, // 18: v2ray.core.app.router.SimplifiedRoutingRule.source_geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP
+	17, // 19: v2ray.core.app.router.SimplifiedRoutingRule.geo_domain:type_name -> v2ray.core.app.router.routercommon.GeoSite
+	0,  // 20: v2ray.core.app.router.SimplifiedConfig.domain_strategy:type_name -> v2ray.core.app.router.DomainStrategy
+	8,  // 21: v2ray.core.app.router.SimplifiedConfig.rule:type_name -> v2ray.core.app.router.SimplifiedRoutingRule
+	2,  // 22: v2ray.core.app.router.SimplifiedConfig.balancing_rule:type_name -> v2ray.core.app.router.BalancingRule
+	23, // [23:23] is the sub-list for method output_type
+	23, // [23:23] is the sub-list for method input_type
+	23, // [23:23] is the sub-list for extension type_name
+	23, // [23:23] is the sub-list for extension extendee
+	0,  // [0:23] is the sub-list for field type_name
 }
 }
 
 
 func init() { file_app_router_config_proto_init() }
 func init() { file_app_router_config_proto_init() }
@@ -1084,6 +1319,18 @@ func file_app_router_config_proto_init() {
 			}
 			}
 		}
 		}
 		file_app_router_config_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
 		file_app_router_config_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SimplifiedRoutingRule); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_app_router_config_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*SimplifiedConfig); i {
 			switch v := v.(*SimplifiedConfig); i {
 			case 0:
 			case 0:
 				return &v.state
 				return &v.state
@@ -1100,13 +1347,17 @@ func file_app_router_config_proto_init() {
 		(*RoutingRule_Tag)(nil),
 		(*RoutingRule_Tag)(nil),
 		(*RoutingRule_BalancingTag)(nil),
 		(*RoutingRule_BalancingTag)(nil),
 	}
 	}
+	file_app_router_config_proto_msgTypes[7].OneofWrappers = []interface{}{
+		(*SimplifiedRoutingRule_Tag)(nil),
+		(*SimplifiedRoutingRule_BalancingTag)(nil),
+	}
 	type x struct{}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_app_router_config_proto_rawDesc,
 			RawDescriptor: file_app_router_config_proto_rawDesc,
 			NumEnums:      1,
 			NumEnums:      1,
-			NumMessages:   8,
+			NumMessages:   9,
 			NumExtensions: 0,
 			NumExtensions: 0,
 			NumServices:   0,
 			NumServices:   0,
 		},
 		},

+ 44 - 1
app/router/config.proto

@@ -134,11 +134,54 @@ message Config {
   repeated BalancingRule balancing_rule = 3;
   repeated BalancingRule balancing_rule = 3;
 }
 }
 
 
+message SimplifiedRoutingRule {
+  oneof target_tag {
+    // Tag of outbound that this rule is pointing to.
+    string tag = 1;
+
+    // Tag of routing balancer.
+    string balancing_tag = 12;
+  }
+
+  // List of domains for target domain matching.
+  repeated v2ray.core.app.router.routercommon.Domain domain = 2;
+
+  // List of GeoIPs for target IP address matching. If this entry exists, the
+  // cidr above will have no effect. GeoIP fields with the same country code are
+  // supposed to contain exactly same content. They will be merged during
+  // runtime. For customized GeoIPs, please leave country code empty.
+  repeated v2ray.core.app.router.routercommon.GeoIP geoip = 10;
+
+  // List of ports.
+  string port_list = 14;
+
+  // List of networks for matching.
+  string networks = 13;
+
+  // List of GeoIPs for source IP address matching. If this entry exists, the
+  // source_cidr above will have no effect.
+  repeated v2ray.core.app.router.routercommon.GeoIP source_geoip = 11;
+
+  // List of ports for source port matching.
+  string source_port_list = 16;
+
+  repeated string user_email = 7;
+  repeated string inbound_tag = 8;
+  repeated string protocol = 9;
+
+  string attributes = 15;
+
+  string domain_matcher = 17;
+
+  // geo_domain instruct simplified config loader to load geo domain rule and fill in domain field.
+  repeated v2ray.core.app.router.routercommon.GeoSite geo_domain = 68001;
+}
+
 message SimplifiedConfig {
 message SimplifiedConfig {
   option (v2ray.core.common.protoext.message_opt).type = "service";
   option (v2ray.core.common.protoext.message_opt).type = "service";
   option (v2ray.core.common.protoext.message_opt).short_name = "router";
   option (v2ray.core.common.protoext.message_opt).short_name = "router";
 
 
   DomainStrategy domain_strategy = 1;
   DomainStrategy domain_strategy = 1;
-  repeated RoutingRule rule = 2;
+  repeated SimplifiedRoutingRule rule = 2;
   repeated BalancingRule balancing_rule = 3;
   repeated BalancingRule balancing_rule = 3;
 }
 }

+ 50 - 2
app/router/router.go

@@ -6,6 +6,7 @@ import (
 	"context"
 	"context"
 	core "github.com/v2fly/v2ray-core/v4"
 	core "github.com/v2fly/v2ray-core/v4"
 	"github.com/v2fly/v2ray-core/v4/common"
 	"github.com/v2fly/v2ray-core/v4/common"
+	"github.com/v2fly/v2ray-core/v4/common/net"
 	"github.com/v2fly/v2ray-core/v4/common/platform"
 	"github.com/v2fly/v2ray-core/v4/common/platform"
 	"github.com/v2fly/v2ray-core/v4/features/dns"
 	"github.com/v2fly/v2ray-core/v4/features/dns"
 	"github.com/v2fly/v2ray-core/v4/features/outbound"
 	"github.com/v2fly/v2ray-core/v4/features/outbound"
@@ -168,7 +169,12 @@ func init() {
 
 
 		simplifiedConfig := config.(*SimplifiedConfig)
 		simplifiedConfig := config.(*SimplifiedConfig)
 
 
+		var routingRules []*RoutingRule
+
 		for _, v := range simplifiedConfig.Rule {
 		for _, v := range simplifiedConfig.Rule {
+
+			rule := new(RoutingRule)
+
 			for _, geo := range v.Geoip {
 			for _, geo := range v.Geoip {
 				if geo.Code != "" {
 				if geo.Code != "" {
 					filepath := "geoip.dat"
 					filepath := "geoip.dat"
@@ -184,6 +190,25 @@ func init() {
 					}
 					}
 				}
 				}
 			}
 			}
+			rule.Geoip = v.Geoip
+
+			for _, geo := range v.SourceGeoip {
+				if geo.Code != "" {
+					filepath := "geoip.dat"
+					if geo.FilePath != "" {
+						filepath = geo.FilePath
+					} else {
+						geo.CountryCode = geo.Code
+					}
+					var err error
+					geo.Cidr, err = geoLoader.LoadIP(filepath, geo.Code)
+					if err != nil {
+						return nil, newError("unable to load geoip").Base(err)
+					}
+				}
+			}
+			rule.SourceGeoip = v.SourceGeoip
+
 			for _, geo := range v.GeoDomain {
 			for _, geo := range v.GeoDomain {
 				if geo.Code != "" {
 				if geo.Code != "" {
 					filepath := "geosite.dat"
 					filepath := "geosite.dat"
@@ -195,14 +220,37 @@ func init() {
 					if err != nil {
 					if err != nil {
 						return nil, newError("unable to load geodomain").Base(err)
 						return nil, newError("unable to load geodomain").Base(err)
 					}
 					}
-					v.Domain = append(v.Domain, geo.Domain...)
+					rule.Domain = append(rule.Domain, geo.Domain...)
+				}
+			}
+			{
+				portList := &cfgcommon.PortList{}
+				err := portList.UnmarshalText(v.PortList)
+				if err != nil {
+					return nil, err
+				}
+				rule.PortList = portList.Build()
+			}
+			{
+				portList := &cfgcommon.PortList{}
+				err := portList.UnmarshalText(v.SourcePortList)
+				if err != nil {
+					return nil, err
 				}
 				}
+				rule.SourcePortList = portList.Build()
 			}
 			}
+			rule.Domain = v.Domain
+			rule.Networks = net.ParseNetworks(v.Networks)
+			rule.Protocol = v.Protocol
+			rule.Attributes = v.Attributes
+			rule.UserEmail = v.UserEmail
+			rule.InboundTag = v.InboundTag
+			rule.DomainMatcher = v.DomainMatcher
 		}
 		}
 
 
 		fullConfig := &Config{
 		fullConfig := &Config{
 			DomainStrategy: simplifiedConfig.DomainStrategy,
 			DomainStrategy: simplifiedConfig.DomainStrategy,
-			Rule:           simplifiedConfig.Rule,
+			Rule:           routingRules,
 			BalancingRule:  simplifiedConfig.BalancingRule,
 			BalancingRule:  simplifiedConfig.BalancingRule,
 		}
 		}
 		return common.CreateObject(ctx, fullConfig)
 		return common.CreateObject(ctx, fullConfig)

+ 11 - 3
infra/conf/cfgcommon/common.go

@@ -196,6 +196,17 @@ func (list *PortList) UnmarshalJSON(data []byte) error {
 			return newError("invalid port: ", string(data)).Base(err2)
 			return newError("invalid port: ", string(data)).Base(err2)
 		}
 		}
 	}
 	}
+	err := list.UnmarshalText(listStr)
+	if err != nil {
+		return err
+	}
+	if number != 0 {
+		list.Range = append(list.Range, PortRange{From: number, To: number})
+	}
+	return nil
+}
+
+func (list *PortList) UnmarshalText(listStr string) error {
 	rangelist := strings.Split(listStr, ",")
 	rangelist := strings.Split(listStr, ",")
 	for _, rangeStr := range rangelist {
 	for _, rangeStr := range rangelist {
 		trimmed := strings.TrimSpace(rangeStr)
 		trimmed := strings.TrimSpace(rangeStr)
@@ -215,9 +226,6 @@ func (list *PortList) UnmarshalJSON(data []byte) error {
 			}
 			}
 		}
 		}
 	}
 	}
-	if number != 0 {
-		list.Range = append(list.Range, PortRange{From: number, To: number})
-	}
 	return nil
 	return nil
 }
 }