From b11429eaeef798e3a99cb738c48603fe5b576b93 Mon Sep 17 00:00:00 2001 From: JimhHan <50871214+JimhHan@users.noreply.github.com> Date: Wed, 24 Mar 2021 23:01:20 +0800 Subject: [PATCH 01/20] Refactor: GeoSite & GeoIP --- app/dns/config.go | 35 +- app/dns/config.pb.go | 389 +++----- app/dns/config.proto | 21 +- app/dns/dns.go | 12 +- app/dns/dns_test.go | 81 +- app/dns/hosts.go | 8 +- app/dns/hosts_test.go | 7 +- app/dns/nameserver.go | 12 +- app/router/command/command_test.go | 6 +- app/router/condition.go | 62 +- app/router/condition_test.go | 60 +- app/router/config.go | 48 +- app/router/config.pb.go | 891 +++--------------- app/router/config.proto | 72 +- app/router/router_test.go | 7 +- app/stats/command/command.go | 4 +- common/matcher/conf/conf.go | 3 + common/matcher/conf/domain.go | 78 ++ common/matcher/conf/errors.generated.go | 9 + common/matcher/domain/domain.go | 3 + common/matcher/domain/domain.pb.go | 229 +++++ common/matcher/domain/domain.proto | 39 + common/matcher/domain/errors.generated.go | 9 + common/matcher/geoip/conf.go | 90 ++ common/matcher/geoip/crid.go | 40 + common/matcher/geoip/errors.generated.go | 9 + .../matcher/geoip/geoip.go | 6 +- common/matcher/geoip/geoip.pb.go | 307 ++++++ common/matcher/geoip/geoip.proto | 25 + .../matcher/geoip/geoip_test.go | 32 +- common/matcher/geoip/matcher.go | 47 + common/matcher/geosite/attribute.go | 33 + common/matcher/geosite/conf.go | 42 + common/matcher/geosite/errors.generated.go | 9 + common/matcher/geosite/file.go | 86 ++ common/matcher/geosite/geosite.go | 19 + common/matcher/geosite/geosite.pb.go | 443 +++++++++ common/matcher/geosite/geosite.proto | 38 + .../str}/benchmark_test.go | 4 +- .../str}/domain_matcher.go | 2 +- .../str}/domain_matcher_test.go | 4 +- .../str}/full_matcher.go | 2 +- .../str}/full_matcher_test.go | 4 +- .../{strmatcher => matcher/str}/matchers.go | 2 +- .../str}/matchers_test.go | 4 +- .../{strmatcher => matcher/str}/strmatcher.go | 2 +- .../str}/strmatcher_test.go | 4 +- infra/conf/dns.go | 56 +- infra/conf/dns_test.go | 27 +- infra/conf/router.go | 264 +----- infra/conf/router_test.go | 32 +- infra/conf/xray_test.go | 5 +- testing/scenarios/dns_test.go | 3 +- testing/scenarios/reverse_test.go | 17 +- 54 files changed, 2110 insertions(+), 1633 deletions(-) create mode 100644 common/matcher/conf/conf.go create mode 100644 common/matcher/conf/domain.go create mode 100644 common/matcher/conf/errors.generated.go create mode 100644 common/matcher/domain/domain.go create mode 100644 common/matcher/domain/domain.pb.go create mode 100644 common/matcher/domain/domain.proto create mode 100644 common/matcher/domain/errors.generated.go create mode 100644 common/matcher/geoip/conf.go create mode 100644 common/matcher/geoip/crid.go create mode 100644 common/matcher/geoip/errors.generated.go rename app/router/condition_geoip.go => common/matcher/geoip/geoip.go (96%) create mode 100644 common/matcher/geoip/geoip.pb.go create mode 100644 common/matcher/geoip/geoip.proto rename app/router/condition_geoip_test.go => common/matcher/geoip/geoip_test.go (85%) create mode 100644 common/matcher/geoip/matcher.go create mode 100644 common/matcher/geosite/attribute.go create mode 100644 common/matcher/geosite/conf.go create mode 100644 common/matcher/geosite/errors.generated.go create mode 100644 common/matcher/geosite/file.go create mode 100644 common/matcher/geosite/geosite.go create mode 100644 common/matcher/geosite/geosite.pb.go create mode 100644 common/matcher/geosite/geosite.proto rename common/{strmatcher => matcher/str}/benchmark_test.go (91%) rename common/{strmatcher => matcher/str}/domain_matcher.go (98%) rename common/{strmatcher => matcher/str}/domain_matcher_test.go (94%) rename common/{strmatcher => matcher/str}/full_matcher.go (96%) rename common/{strmatcher => matcher/str}/full_matcher_test.go (91%) rename common/{strmatcher => matcher/str}/matchers.go (97%) rename common/{strmatcher => matcher/str}/matchers_test.go (94%) rename common/{strmatcher => matcher/str}/strmatcher.go (99%) rename common/{strmatcher => matcher/str}/strmatcher_test.go (95%) diff --git a/app/dns/config.go b/app/dns/config.go index 6236f7b5336e..caa7304cdd08 100644 --- a/app/dns/config.go +++ b/app/dns/config.go @@ -1,31 +1,32 @@ package dns import ( + dm "github.com/xtls/xray-core/common/matcher/domain" + "github.com/xtls/xray-core/common/matcher/str" "github.com/xtls/xray-core/common/net" - "github.com/xtls/xray-core/common/strmatcher" "github.com/xtls/xray-core/common/uuid" ) -var typeMap = map[DomainMatchingType]strmatcher.Type{ - DomainMatchingType_Full: strmatcher.Full, - DomainMatchingType_Subdomain: strmatcher.Domain, - DomainMatchingType_Keyword: strmatcher.Substr, - DomainMatchingType_Regex: strmatcher.Regex, +var typeMap = map[dm.MatchingType]str.Type{ + dm.MatchingType_Keyword: str.Substr, + dm.MatchingType_Regex: str.Regex, + dm.MatchingType_Subdomain: str.Domain, + dm.MatchingType_Full: str.Full, } // References: // https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml // https://unix.stackexchange.com/questions/92441/whats-the-difference-between-local-home-and-lan -var localTLDsAndDotlessDomains = []*NameServer_PriorityDomain{ - {Type: DomainMatchingType_Regex, Domain: "^[^.]+$"}, // This will only match domains without any dot - {Type: DomainMatchingType_Subdomain, Domain: "local"}, - {Type: DomainMatchingType_Subdomain, Domain: "localdomain"}, - {Type: DomainMatchingType_Subdomain, Domain: "localhost"}, - {Type: DomainMatchingType_Subdomain, Domain: "lan"}, - {Type: DomainMatchingType_Subdomain, Domain: "home.arpa"}, - {Type: DomainMatchingType_Subdomain, Domain: "example"}, - {Type: DomainMatchingType_Subdomain, Domain: "invalid"}, - {Type: DomainMatchingType_Subdomain, Domain: "test"}, +var localTLDsAndDotlessDomains = []*dm.Domain{ + {Type: dm.MatchingType_Regex, Value: "^[^.]+$"}, // This will only match domains without any dot + {Type: dm.MatchingType_Subdomain, Value: "local"}, + {Type: dm.MatchingType_Subdomain, Value: "localdomain"}, + {Type: dm.MatchingType_Subdomain, Value: "localhost"}, + {Type: dm.MatchingType_Subdomain, Value: "lan"}, + {Type: dm.MatchingType_Subdomain, Value: "home.arpa"}, + {Type: dm.MatchingType_Subdomain, Value: "example"}, + {Type: dm.MatchingType_Subdomain, Value: "invalid"}, + {Type: dm.MatchingType_Subdomain, Value: "test"}, } var localTLDsAndDotlessDomainsRule = &NameServer_OriginalRule{ @@ -33,7 +34,7 @@ var localTLDsAndDotlessDomainsRule = &NameServer_OriginalRule{ Size: uint32(len(localTLDsAndDotlessDomains)), } -func toStrMatcher(t DomainMatchingType, domain string) (strmatcher.Matcher, error) { +func toStrMatcher(t dm.MatchingType, domain string) (str.Matcher, error) { strMType, f := typeMap[t] if !f { return nil, newError("unknown mapping type", t).AtWarning() diff --git a/app/dns/config.pb.go b/app/dns/config.pb.go index 1f812c4340ef..7937b35bffa5 100644 --- a/app/dns/config.pb.go +++ b/app/dns/config.pb.go @@ -8,7 +8,8 @@ package dns import ( proto "github.com/golang/protobuf/proto" - router "github.com/xtls/xray-core/app/router" + domain "github.com/xtls/xray-core/common/matcher/domain" + geoip "github.com/xtls/xray-core/common/matcher/geoip" net "github.com/xtls/xray-core/common/net" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" @@ -27,58 +28,6 @@ const ( // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 -type DomainMatchingType int32 - -const ( - DomainMatchingType_Full DomainMatchingType = 0 - DomainMatchingType_Subdomain DomainMatchingType = 1 - DomainMatchingType_Keyword DomainMatchingType = 2 - DomainMatchingType_Regex DomainMatchingType = 3 -) - -// Enum value maps for DomainMatchingType. -var ( - DomainMatchingType_name = map[int32]string{ - 0: "Full", - 1: "Subdomain", - 2: "Keyword", - 3: "Regex", - } - DomainMatchingType_value = map[string]int32{ - "Full": 0, - "Subdomain": 1, - "Keyword": 2, - "Regex": 3, - } -) - -func (x DomainMatchingType) Enum() *DomainMatchingType { - p := new(DomainMatchingType) - *p = x - return p -} - -func (x DomainMatchingType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (DomainMatchingType) Descriptor() protoreflect.EnumDescriptor { - return file_app_dns_config_proto_enumTypes[0].Descriptor() -} - -func (DomainMatchingType) Type() protoreflect.EnumType { - return &file_app_dns_config_proto_enumTypes[0] -} - -func (x DomainMatchingType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use DomainMatchingType.Descriptor instead. -func (DomainMatchingType) EnumDescriptor() ([]byte, []int) { - return file_app_dns_config_proto_rawDescGZIP(), []int{0} -} - type QueryStrategy int32 const ( @@ -112,11 +61,11 @@ func (x QueryStrategy) String() string { } func (QueryStrategy) Descriptor() protoreflect.EnumDescriptor { - return file_app_dns_config_proto_enumTypes[1].Descriptor() + return file_app_dns_config_proto_enumTypes[0].Descriptor() } func (QueryStrategy) Type() protoreflect.EnumType { - return &file_app_dns_config_proto_enumTypes[1] + return &file_app_dns_config_proto_enumTypes[0] } func (x QueryStrategy) Number() protoreflect.EnumNumber { @@ -125,7 +74,7 @@ func (x QueryStrategy) Number() protoreflect.EnumNumber { // Deprecated: Use QueryStrategy.Descriptor instead. func (QueryStrategy) EnumDescriptor() ([]byte, []int) { - return file_app_dns_config_proto_rawDescGZIP(), []int{1} + return file_app_dns_config_proto_rawDescGZIP(), []int{0} } type NameServer struct { @@ -133,11 +82,11 @@ type NameServer struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Address *net.Endpoint `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - ClientIp []byte `protobuf:"bytes,5,opt,name=client_ip,json=clientIp,proto3" json:"client_ip,omitempty"` - PrioritizedDomain []*NameServer_PriorityDomain `protobuf:"bytes,2,rep,name=prioritized_domain,json=prioritizedDomain,proto3" json:"prioritized_domain,omitempty"` - Geoip []*router.GeoIP `protobuf:"bytes,3,rep,name=geoip,proto3" json:"geoip,omitempty"` - OriginalRules []*NameServer_OriginalRule `protobuf:"bytes,4,rep,name=original_rules,json=originalRules,proto3" json:"original_rules,omitempty"` + Address *net.Endpoint `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + ClientIp []byte `protobuf:"bytes,5,opt,name=client_ip,json=clientIp,proto3" json:"client_ip,omitempty"` + PrioritizedDomain []*domain.Domain `protobuf:"bytes,2,rep,name=prioritized_domain,json=prioritizedDomain,proto3" json:"prioritized_domain,omitempty"` + Geoip []*geoip.GeoIP `protobuf:"bytes,3,rep,name=geoip,proto3" json:"geoip,omitempty"` + OriginalRules []*NameServer_OriginalRule `protobuf:"bytes,4,rep,name=original_rules,json=originalRules,proto3" json:"original_rules,omitempty"` } func (x *NameServer) Reset() { @@ -186,14 +135,14 @@ func (x *NameServer) GetClientIp() []byte { return nil } -func (x *NameServer) GetPrioritizedDomain() []*NameServer_PriorityDomain { +func (x *NameServer) GetPrioritizedDomain() []*domain.Domain { if x != nil { return x.PrioritizedDomain } return nil } -func (x *NameServer) GetGeoip() []*router.GeoIP { +func (x *NameServer) GetGeoip() []*geoip.GeoIP { if x != nil { return x.Geoip } @@ -326,61 +275,6 @@ func (x *Config) GetQueryStrategy() QueryStrategy { return QueryStrategy_USE_IP } -type NameServer_PriorityDomain struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Type DomainMatchingType `protobuf:"varint,1,opt,name=type,proto3,enum=xray.app.dns.DomainMatchingType" json:"type,omitempty"` - Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"` -} - -func (x *NameServer_PriorityDomain) Reset() { - *x = NameServer_PriorityDomain{} - if protoimpl.UnsafeEnabled { - mi := &file_app_dns_config_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *NameServer_PriorityDomain) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*NameServer_PriorityDomain) ProtoMessage() {} - -func (x *NameServer_PriorityDomain) ProtoReflect() protoreflect.Message { - mi := &file_app_dns_config_proto_msgTypes[2] - 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 NameServer_PriorityDomain.ProtoReflect.Descriptor instead. -func (*NameServer_PriorityDomain) Descriptor() ([]byte, []int) { - return file_app_dns_config_proto_rawDescGZIP(), []int{0, 0} -} - -func (x *NameServer_PriorityDomain) GetType() DomainMatchingType { - if x != nil { - return x.Type - } - return DomainMatchingType_Full -} - -func (x *NameServer_PriorityDomain) GetDomain() string { - if x != nil { - return x.Domain - } - return "" -} - type NameServer_OriginalRule struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -393,7 +287,7 @@ type NameServer_OriginalRule struct { func (x *NameServer_OriginalRule) Reset() { *x = NameServer_OriginalRule{} if protoimpl.UnsafeEnabled { - mi := &file_app_dns_config_proto_msgTypes[3] + mi := &file_app_dns_config_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -406,7 +300,7 @@ func (x *NameServer_OriginalRule) String() string { func (*NameServer_OriginalRule) ProtoMessage() {} func (x *NameServer_OriginalRule) ProtoReflect() protoreflect.Message { - mi := &file_app_dns_config_proto_msgTypes[3] + mi := &file_app_dns_config_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -419,7 +313,7 @@ func (x *NameServer_OriginalRule) ProtoReflect() protoreflect.Message { // Deprecated: Use NameServer_OriginalRule.ProtoReflect.Descriptor instead. func (*NameServer_OriginalRule) Descriptor() ([]byte, []int) { - return file_app_dns_config_proto_rawDescGZIP(), []int{0, 1} + return file_app_dns_config_proto_rawDescGZIP(), []int{0, 0} } func (x *NameServer_OriginalRule) GetRule() string { @@ -441,9 +335,9 @@ type Config_HostMapping struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Type DomainMatchingType `protobuf:"varint,1,opt,name=type,proto3,enum=xray.app.dns.DomainMatchingType" json:"type,omitempty"` - Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"` - Ip [][]byte `protobuf:"bytes,3,rep,name=ip,proto3" json:"ip,omitempty"` + Type domain.MatchingType `protobuf:"varint,1,opt,name=type,proto3,enum=xray.common.matcher.domain.MatchingType" json:"type,omitempty"` + Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"` + Ip [][]byte `protobuf:"bytes,3,rep,name=ip,proto3" json:"ip,omitempty"` // ProxiedDomain indicates the mapped domain has the same IP address on this // domain. Xray will use this domain for IP queries. This field is only // effective if ip is empty. @@ -453,7 +347,7 @@ type Config_HostMapping struct { func (x *Config_HostMapping) Reset() { *x = Config_HostMapping{} if protoimpl.UnsafeEnabled { - mi := &file_app_dns_config_proto_msgTypes[5] + mi := &file_app_dns_config_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -466,7 +360,7 @@ func (x *Config_HostMapping) String() string { func (*Config_HostMapping) ProtoMessage() {} func (x *Config_HostMapping) ProtoReflect() protoreflect.Message { - mi := &file_app_dns_config_proto_msgTypes[5] + mi := &file_app_dns_config_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -482,11 +376,11 @@ func (*Config_HostMapping) Descriptor() ([]byte, []int) { return file_app_dns_config_proto_rawDescGZIP(), []int{1, 1} } -func (x *Config_HostMapping) GetType() DomainMatchingType { +func (x *Config_HostMapping) GetType() domain.MatchingType { if x != nil { return x.Type } - return DomainMatchingType_Full + return domain.MatchingType_Full } func (x *Config_HostMapping) GetDomain() string { @@ -518,91 +412,85 @@ var file_app_dns_config_proto_rawDesc = []byte{ 0x2e, 0x64, 0x6e, 0x73, 0x1a, 0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x64, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x61, 0x70, - 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xca, 0x03, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x12, 0x33, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x56, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, - 0x74, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, - 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x69, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x11, 0x70, 0x72, 0x69, - 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x2c, - 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, - 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x4c, 0x0a, 0x0e, - 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, - 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4f, - 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x6f, 0x72, 0x69, - 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x1a, 0x5e, 0x0a, 0x0e, 0x50, 0x72, - 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x34, 0x0a, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, - 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, - 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x1a, 0x36, 0x0a, 0x0c, 0x4f, 0x72, - 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x75, - 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, - 0x7a, 0x65, 0x22, 0x8d, 0x05, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3f, 0x0a, - 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x64, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x2f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, + 0x2f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0xef, 0x02, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x12, 0x33, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x02, 0x18, - 0x01, 0x52, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x39, - 0x0a, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, - 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0a, 0x6e, - 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x05, 0x48, 0x6f, 0x73, - 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, - 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, - 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x02, 0x18, 0x01, 0x52, 0x05, 0x48, - 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, - 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, - 0x70, 0x12, 0x43, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x68, 0x6f, 0x73, 0x74, - 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, - 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x6f, - 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x61, - 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, - 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x42, 0x0a, 0x0e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, - 0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, - 0x79, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, - 0x1a, 0x55, 0x0a, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, - 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x92, 0x01, 0x0a, 0x0b, 0x48, 0x6f, 0x73, 0x74, - 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, - 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, - 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, - 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, - 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x04, 0x08, 0x07, - 0x10, 0x08, 0x2a, 0x45, 0x0a, 0x12, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, - 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, - 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, - 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x10, 0x02, 0x12, 0x09, - 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x10, 0x03, 0x2a, 0x35, 0x0a, 0x0d, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x53, - 0x45, 0x5f, 0x49, 0x50, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, - 0x34, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x10, 0x02, - 0x42, 0x46, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, - 0x2e, 0x64, 0x6e, 0x73, 0x50, 0x01, 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, - 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x6e, 0x73, 0xaa, 0x02, 0x0c, 0x58, 0x72, 0x61, 0x79, - 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x07, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x5f, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x49, 0x70, 0x12, 0x51, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, + 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x44, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x52, 0x11, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, + 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x36, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x69, + 0x70, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x4c, + 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, + 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x6f, + 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x1a, 0x36, 0x0a, 0x0c, + 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, + 0x73, 0x69, 0x7a, 0x65, 0x22, 0x95, 0x05, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x3f, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, + 0x02, 0x18, 0x01, 0x52, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, + 0x12, 0x39, 0x0a, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, + 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x05, 0x48, + 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, + 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x02, 0x18, 0x01, 0x52, + 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x5f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x49, 0x70, 0x12, 0x43, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x68, 0x6f, + 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0b, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x42, + 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, + 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, + 0x65, 0x67, 0x79, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, + 0x67, 0x79, 0x1a, 0x55, 0x0a, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x9a, 0x01, 0x0a, 0x0b, 0x48, 0x6f, + 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x3c, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x64, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, + 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, + 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x2a, 0x35, 0x0a, 0x0d, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x0a, 0x0a, + 0x06, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, + 0x5f, 0x49, 0x50, 0x34, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, + 0x36, 0x10, 0x02, 0x42, 0x46, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, + 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x50, 0x01, 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, + 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x6e, 0x73, 0xaa, 0x02, 0x0c, 0x58, + 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -617,39 +505,38 @@ func file_app_dns_config_proto_rawDescGZIP() []byte { return file_app_dns_config_proto_rawDescData } -var file_app_dns_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_app_dns_config_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_app_dns_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_app_dns_config_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_app_dns_config_proto_goTypes = []interface{}{ - (DomainMatchingType)(0), // 0: xray.app.dns.DomainMatchingType - (QueryStrategy)(0), // 1: xray.app.dns.QueryStrategy - (*NameServer)(nil), // 2: xray.app.dns.NameServer - (*Config)(nil), // 3: xray.app.dns.Config - (*NameServer_PriorityDomain)(nil), // 4: xray.app.dns.NameServer.PriorityDomain - (*NameServer_OriginalRule)(nil), // 5: xray.app.dns.NameServer.OriginalRule - nil, // 6: xray.app.dns.Config.HostsEntry - (*Config_HostMapping)(nil), // 7: xray.app.dns.Config.HostMapping - (*net.Endpoint)(nil), // 8: xray.common.net.Endpoint - (*router.GeoIP)(nil), // 9: xray.app.router.GeoIP - (*net.IPOrDomain)(nil), // 10: xray.common.net.IPOrDomain + (QueryStrategy)(0), // 0: xray.app.dns.QueryStrategy + (*NameServer)(nil), // 1: xray.app.dns.NameServer + (*Config)(nil), // 2: xray.app.dns.Config + (*NameServer_OriginalRule)(nil), // 3: xray.app.dns.NameServer.OriginalRule + nil, // 4: xray.app.dns.Config.HostsEntry + (*Config_HostMapping)(nil), // 5: xray.app.dns.Config.HostMapping + (*net.Endpoint)(nil), // 6: xray.common.net.Endpoint + (*domain.Domain)(nil), // 7: xray.common.matcher.domain.Domain + (*geoip.GeoIP)(nil), // 8: xray.common.matcher.geoip.GeoIP + (*net.IPOrDomain)(nil), // 9: xray.common.net.IPOrDomain + (domain.MatchingType)(0), // 10: xray.common.matcher.domain.MatchingType } var file_app_dns_config_proto_depIdxs = []int32{ - 8, // 0: xray.app.dns.NameServer.address:type_name -> xray.common.net.Endpoint - 4, // 1: xray.app.dns.NameServer.prioritized_domain:type_name -> xray.app.dns.NameServer.PriorityDomain - 9, // 2: xray.app.dns.NameServer.geoip:type_name -> xray.app.router.GeoIP - 5, // 3: xray.app.dns.NameServer.original_rules:type_name -> xray.app.dns.NameServer.OriginalRule - 8, // 4: xray.app.dns.Config.NameServers:type_name -> xray.common.net.Endpoint - 2, // 5: xray.app.dns.Config.name_server:type_name -> xray.app.dns.NameServer - 6, // 6: xray.app.dns.Config.Hosts:type_name -> xray.app.dns.Config.HostsEntry - 7, // 7: xray.app.dns.Config.static_hosts:type_name -> xray.app.dns.Config.HostMapping - 1, // 8: xray.app.dns.Config.query_strategy:type_name -> xray.app.dns.QueryStrategy - 0, // 9: xray.app.dns.NameServer.PriorityDomain.type:type_name -> xray.app.dns.DomainMatchingType - 10, // 10: xray.app.dns.Config.HostsEntry.value:type_name -> xray.common.net.IPOrDomain - 0, // 11: xray.app.dns.Config.HostMapping.type:type_name -> xray.app.dns.DomainMatchingType - 12, // [12:12] is the sub-list for method output_type - 12, // [12:12] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name + 6, // 0: xray.app.dns.NameServer.address:type_name -> xray.common.net.Endpoint + 7, // 1: xray.app.dns.NameServer.prioritized_domain:type_name -> xray.common.matcher.domain.Domain + 8, // 2: xray.app.dns.NameServer.geoip:type_name -> xray.common.matcher.geoip.GeoIP + 3, // 3: xray.app.dns.NameServer.original_rules:type_name -> xray.app.dns.NameServer.OriginalRule + 6, // 4: xray.app.dns.Config.NameServers:type_name -> xray.common.net.Endpoint + 1, // 5: xray.app.dns.Config.name_server:type_name -> xray.app.dns.NameServer + 4, // 6: xray.app.dns.Config.Hosts:type_name -> xray.app.dns.Config.HostsEntry + 5, // 7: xray.app.dns.Config.static_hosts:type_name -> xray.app.dns.Config.HostMapping + 0, // 8: xray.app.dns.Config.query_strategy:type_name -> xray.app.dns.QueryStrategy + 9, // 9: xray.app.dns.Config.HostsEntry.value:type_name -> xray.common.net.IPOrDomain + 10, // 10: xray.app.dns.Config.HostMapping.type:type_name -> xray.common.matcher.domain.MatchingType + 11, // [11:11] is the sub-list for method output_type + 11, // [11:11] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_app_dns_config_proto_init() } @@ -683,18 +570,6 @@ func file_app_dns_config_proto_init() { } } file_app_dns_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NameServer_PriorityDomain); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_app_dns_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*NameServer_OriginalRule); i { case 0: return &v.state @@ -706,7 +581,7 @@ func file_app_dns_config_proto_init() { return nil } } - file_app_dns_config_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_app_dns_config_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Config_HostMapping); i { case 0: return &v.state @@ -724,8 +599,8 @@ func file_app_dns_config_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_app_dns_config_proto_rawDesc, - NumEnums: 2, - NumMessages: 6, + NumEnums: 1, + NumMessages: 5, NumExtensions: 0, NumServices: 0, }, diff --git a/app/dns/config.proto b/app/dns/config.proto index 5ba5c4c272c3..d0ed5766eaad 100644 --- a/app/dns/config.proto +++ b/app/dns/config.proto @@ -8,34 +8,23 @@ option java_multiple_files = true; import "common/net/address.proto"; import "common/net/destination.proto"; -import "app/router/config.proto"; +import "common/matcher/domain/domain.proto"; +import "common/matcher/geoip/geoip.proto"; message NameServer { xray.common.net.Endpoint address = 1; bytes client_ip = 5; - message PriorityDomain { - DomainMatchingType type = 1; - string domain = 2; - } - message OriginalRule { string rule = 1; uint32 size = 2; } - repeated PriorityDomain prioritized_domain = 2; - repeated xray.app.router.GeoIP geoip = 3; + repeated xray.common.matcher.domain.Domain prioritized_domain = 2; + repeated xray.common.matcher.geoip.GeoIP geoip = 3; repeated OriginalRule original_rules = 4; } -enum DomainMatchingType { - Full = 0; - Subdomain = 1; - Keyword = 2; - Regex = 3; -} - enum QueryStrategy { USE_IP = 0; USE_IP4 = 1; @@ -60,7 +49,7 @@ message Config { bytes client_ip = 3; message HostMapping { - DomainMatchingType type = 1; + xray.common.matcher.domain.MatchingType type = 1; string domain = 2; repeated bytes ip = 3; diff --git a/app/dns/dns.go b/app/dns/dns.go index 90c342bc31d8..47b7f9d8f8fb 100644 --- a/app/dns/dns.go +++ b/app/dns/dns.go @@ -9,12 +9,12 @@ import ( "strings" "sync" - "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/errors" + "github.com/xtls/xray-core/common/matcher/geoip" + "github.com/xtls/xray-core/common/matcher/str" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/session" - "github.com/xtls/xray-core/common/strmatcher" "github.com/xtls/xray-core/features" "github.com/xtls/xray-core/features/dns" ) @@ -28,7 +28,7 @@ type DNS struct { hosts *StaticHosts clients []*Client ctx context.Context - domainMatcher strmatcher.IndexMatcher + domainMatcher str.IndexMatcher matcherInfos []DomainMatcherInfo } @@ -90,8 +90,8 @@ func New(ctx context.Context, config *Config) (*DNS, error) { // MatcherInfos is ensured to cover the maximum index domainMatcher could return, where matcher's index starts from 1 matcherInfos := make([]DomainMatcherInfo, domainRuleCount+1) - domainMatcher := &strmatcher.MatcherGroup{} - geoipContainer := router.GeoIPMatcherContainer{} + domainMatcher := &str.MatcherGroup{} + geoipContainer := geoip.GeoIPMatcherContainer{} for _, endpoint := range config.NameServers { features.PrintDeprecatedFeatureWarning("simple DNS server") @@ -104,7 +104,7 @@ func New(ctx context.Context, config *Config) (*DNS, error) { for _, ns := range config.NameServer { clientIdx := len(clients) - updateDomain := func(domainRule strmatcher.Matcher, originalRuleIdx int, matcherInfos []DomainMatcherInfo) error { + updateDomain := func(domainRule str.Matcher, originalRuleIdx int, matcherInfos []DomainMatcherInfo) error { midx := domainMatcher.Add(domainRule) matcherInfos[midx] = DomainMatcherInfo{ clientIdx: uint16(clientIdx), diff --git a/app/dns/dns_test.go b/app/dns/dns_test.go index 8c96eeea4438..484b244043b8 100644 --- a/app/dns/dns_test.go +++ b/app/dns/dns_test.go @@ -12,8 +12,9 @@ import ( "github.com/xtls/xray-core/app/policy" "github.com/xtls/xray-core/app/proxyman" _ "github.com/xtls/xray-core/app/proxyman/outbound" - "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common" + "github.com/xtls/xray-core/common/matcher/domain" + "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/core" @@ -303,10 +304,10 @@ func TestPrioritizedDomain(t *testing.T) { }, Port: uint32(port), }, - PrioritizedDomain: []*NameServer_PriorityDomain{ + PrioritizedDomain: []*domain.Domain{ { - Type: DomainMatchingType_Full, - Domain: "google.com", + Type: domain.MatchingType_Full, + Value: "google.com", }, }, }, @@ -432,7 +433,7 @@ func TestStaticHostDomain(t *testing.T) { }, StaticHosts: []*Config_HostMapping{ { - Type: DomainMatchingType_Full, + Type: domain.MatchingType_Full, Domain: "example.com", ProxiedDomain: "google.com", }, @@ -496,10 +497,10 @@ func TestIPMatch(t *testing.T) { }, Port: uint32(port), }, - Geoip: []*router.GeoIP{ + Geoip: []*geoip.GeoIP{ { CountryCode: "local", - Cidr: []*router.CIDR{ + Cidr: []*geoip.CIDR{ { // inner ip, will not match Ip: []byte{192, 168, 11, 1}, @@ -520,10 +521,10 @@ func TestIPMatch(t *testing.T) { }, Port: uint32(port), }, - Geoip: []*router.GeoIP{ + Geoip: []*geoip.GeoIP{ { CountryCode: "test", - Cidr: []*router.CIDR{ + Cidr: []*geoip.CIDR{ { Ip: []byte{8, 8, 8, 8}, Prefix: 32, @@ -532,7 +533,7 @@ func TestIPMatch(t *testing.T) { }, { CountryCode: "test", - Cidr: []*router.CIDR{ + Cidr: []*geoip.CIDR{ { Ip: []byte{8, 8, 8, 4}, Prefix: 32, @@ -616,14 +617,14 @@ func TestLocalDomain(t *testing.T) { }, Port: uint32(port), }, - PrioritizedDomain: []*NameServer_PriorityDomain{ + PrioritizedDomain: []*domain.Domain{ // Equivalent of dotless:localhost - {Type: DomainMatchingType_Regex, Domain: "^[^.]*localhost[^.]*$"}, + {Type: domain.MatchingType_Regex, Value: "^[^.]*localhost[^.]*$"}, }, - Geoip: []*router.GeoIP{ + Geoip: []*geoip.GeoIP{ { // Will match localhost, localhost-a and localhost-b, CountryCode: "local", - Cidr: []*router.CIDR{ + Cidr: []*geoip.CIDR{ {Ip: []byte{127, 0, 0, 2}, Prefix: 32}, {Ip: []byte{127, 0, 0, 3}, Prefix: 32}, {Ip: []byte{127, 0, 0, 4}, Prefix: 32}, @@ -641,22 +642,22 @@ func TestLocalDomain(t *testing.T) { }, Port: uint32(port), }, - PrioritizedDomain: []*NameServer_PriorityDomain{ + PrioritizedDomain: []*domain.Domain{ // Equivalent of dotless: and domain:local - {Type: DomainMatchingType_Regex, Domain: "^[^.]*$"}, - {Type: DomainMatchingType_Subdomain, Domain: "local"}, - {Type: DomainMatchingType_Subdomain, Domain: "localdomain"}, + {Type: domain.MatchingType_Regex, Value: "^[^.]*$"}, + {Type: domain.MatchingType_Subdomain, Value: "local"}, + {Type: domain.MatchingType_Subdomain, Value: "localdomain"}, }, }, }, StaticHosts: []*Config_HostMapping{ { - Type: DomainMatchingType_Full, + Type: domain.MatchingType_Full, Domain: "hostnamestatic", Ip: [][]byte{{127, 0, 0, 53}}, }, { - Type: DomainMatchingType_Full, + Type: domain.MatchingType_Full, Domain: "hostnamealias", ProxiedDomain: "hostname.localdomain", }, @@ -812,15 +813,15 @@ func TestMultiMatchPrioritizedDomain(t *testing.T) { }, Port: uint32(port), }, - PrioritizedDomain: []*NameServer_PriorityDomain{ + PrioritizedDomain: []*domain.Domain{ { - Type: DomainMatchingType_Subdomain, - Domain: "google.com", + Type: domain.MatchingType_Subdomain, + Value: "google.com", }, }, - Geoip: []*router.GeoIP{ + Geoip: []*geoip.GeoIP{ { // Will only match 8.8.8.8 and 8.8.4.4 - Cidr: []*router.CIDR{ + Cidr: []*geoip.CIDR{ {Ip: []byte{8, 8, 8, 8}, Prefix: 32}, {Ip: []byte{8, 8, 4, 4}, Prefix: 32}, }, @@ -837,15 +838,15 @@ func TestMultiMatchPrioritizedDomain(t *testing.T) { }, Port: uint32(port), }, - PrioritizedDomain: []*NameServer_PriorityDomain{ + PrioritizedDomain: []*domain.Domain{ { - Type: DomainMatchingType_Subdomain, - Domain: "google.com", + Type: domain.MatchingType_Subdomain, + Value: "google.com", }, }, - Geoip: []*router.GeoIP{ + Geoip: []*geoip.GeoIP{ { // Will match 8.8.8.8 and 8.8.8.7, etc - Cidr: []*router.CIDR{ + Cidr: []*geoip.CIDR{ {Ip: []byte{8, 8, 8, 7}, Prefix: 24}, }, }, @@ -861,15 +862,15 @@ func TestMultiMatchPrioritizedDomain(t *testing.T) { }, Port: uint32(port), }, - PrioritizedDomain: []*NameServer_PriorityDomain{ + PrioritizedDomain: []*domain.Domain{ { - Type: DomainMatchingType_Subdomain, - Domain: "api.google.com", + Type: domain.MatchingType_Subdomain, + Value: "api.google.com", }, }, - Geoip: []*router.GeoIP{ + Geoip: []*geoip.GeoIP{ { // Will only match 8.8.7.7 (api.google.com) - Cidr: []*router.CIDR{ + Cidr: []*geoip.CIDR{ {Ip: []byte{8, 8, 7, 7}, Prefix: 32}, }, }, @@ -885,15 +886,15 @@ func TestMultiMatchPrioritizedDomain(t *testing.T) { }, Port: uint32(port), }, - PrioritizedDomain: []*NameServer_PriorityDomain{ + PrioritizedDomain: []*domain.Domain{ { - Type: DomainMatchingType_Full, - Domain: "v2.api.google.com", + Type: domain.MatchingType_Full, + Value: "v2.api.google.com", }, }, - Geoip: []*router.GeoIP{ + Geoip: []*geoip.GeoIP{ { // Will only match 8.8.7.8 (v2.api.google.com) - Cidr: []*router.CIDR{ + Cidr: []*geoip.CIDR{ {Ip: []byte{8, 8, 7, 8}, Prefix: 32}, }, }, diff --git a/app/dns/hosts.go b/app/dns/hosts.go index af3158033967..1e0783fc3415 100644 --- a/app/dns/hosts.go +++ b/app/dns/hosts.go @@ -2,8 +2,8 @@ package dns import ( "github.com/xtls/xray-core/common" + "github.com/xtls/xray-core/common/matcher/str" "github.com/xtls/xray-core/common/net" - "github.com/xtls/xray-core/common/strmatcher" "github.com/xtls/xray-core/features" "github.com/xtls/xray-core/features/dns" ) @@ -11,12 +11,12 @@ import ( // StaticHosts represents static domain-ip mapping in DNS server. type StaticHosts struct { ips [][]net.Address - matchers *strmatcher.MatcherGroup + matchers *str.MatcherGroup } // NewStaticHosts creates a new StaticHosts instance. func NewStaticHosts(hosts []*Config_HostMapping, legacy map[string]*net.IPOrDomain) (*StaticHosts, error) { - g := new(strmatcher.MatcherGroup) + g := new(str.MatcherGroup) sh := &StaticHosts{ ips: make([][]net.Address, len(hosts)+len(legacy)+16), matchers: g, @@ -26,7 +26,7 @@ func NewStaticHosts(hosts []*Config_HostMapping, legacy map[string]*net.IPOrDoma features.PrintDeprecatedFeatureWarning("simple host mapping") for domain, ip := range legacy { - matcher, err := strmatcher.Full.New(domain) + matcher, err := str.Full.New(domain) common.Must(err) id := g.Add(matcher) diff --git a/app/dns/hosts_test.go b/app/dns/hosts_test.go index 87e487bc65c0..01ede8ab504a 100644 --- a/app/dns/hosts_test.go +++ b/app/dns/hosts_test.go @@ -7,6 +7,7 @@ import ( . "github.com/xtls/xray-core/app/dns" "github.com/xtls/xray-core/common" + "github.com/xtls/xray-core/common/matcher/domain" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/features/dns" ) @@ -14,21 +15,21 @@ import ( func TestStaticHosts(t *testing.T) { pb := []*Config_HostMapping{ { - Type: DomainMatchingType_Full, + Type: domain.MatchingType_Full, Domain: "example.com", Ip: [][]byte{ {1, 1, 1, 1}, }, }, { - Type: DomainMatchingType_Subdomain, + Type: domain.MatchingType_Subdomain, Domain: "example.cn", Ip: [][]byte{ {2, 2, 2, 2}, }, }, { - Type: DomainMatchingType_Subdomain, + Type: domain.MatchingType_Subdomain, Domain: "baidu.com", Ip: [][]byte{ {127, 0, 0, 1}, diff --git a/app/dns/nameserver.go b/app/dns/nameserver.go index 36341f656c7f..1bdda0add21a 100644 --- a/app/dns/nameserver.go +++ b/app/dns/nameserver.go @@ -6,10 +6,10 @@ import ( "strings" "time" - "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common/errors" + "github.com/xtls/xray-core/common/matcher/geoip" + "github.com/xtls/xray-core/common/matcher/str" "github.com/xtls/xray-core/common/net" - "github.com/xtls/xray-core/common/strmatcher" core "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/features/dns" "github.com/xtls/xray-core/features/routing" @@ -28,7 +28,7 @@ type Client struct { server Server clientIP net.IP domains []string - expectIPs []*router.GeoIPMatcher + expectIPs []*geoip.GeoIPMatcher } var errExpectedIPNonMatch = errors.New("expectIPs not match") @@ -63,7 +63,7 @@ func NewServer(dest net.Destination, dispatcher routing.Dispatcher) (Server, err } // NewClient creates a DNS client managing a name server with client IP, domain rules and expected IPs. -func NewClient(ctx context.Context, ns *NameServer, clientIP net.IP, container router.GeoIPMatcherContainer, matcherInfos *[]DomainMatcherInfo, updateDomainRule func(strmatcher.Matcher, int, []DomainMatcherInfo) error) (*Client, error) { +func NewClient(ctx context.Context, ns *NameServer, clientIP net.IP, container geoip.GeoIPMatcherContainer, matcherInfos *[]DomainMatcherInfo, updateDomainRule func(str.Matcher, int, []DomainMatcherInfo) error) (*Client, error) { client := &Client{} err := core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error { // Create a new server for each client for now @@ -93,7 +93,7 @@ func NewClient(ctx context.Context, ns *NameServer, clientIP net.IP, container r ruleCurr := 0 ruleIter := 0 for _, domain := range ns.PrioritizedDomain { - domainRule, err := toStrMatcher(domain.Type, domain.Domain) + domainRule, err := toStrMatcher(domain.Type, domain.Value) if err != nil { return newError("failed to create prioritized domain").Base(err).AtWarning() } @@ -119,7 +119,7 @@ func NewClient(ctx context.Context, ns *NameServer, clientIP net.IP, container r } // Establish expected IPs - var matchers []*router.GeoIPMatcher + var matchers []*geoip.GeoIPMatcher for _, geoip := range ns.Geoip { matcher, err := container.Add(geoip) if err != nil { diff --git a/app/router/command/command_test.go b/app/router/command/command_test.go index e8e50cc65ba2..459af45092b0 100644 --- a/app/router/command/command_test.go +++ b/app/router/command/command_test.go @@ -12,6 +12,8 @@ import ( . "github.com/xtls/xray-core/app/router/command" "github.com/xtls/xray-core/app/stats" "github.com/xtls/xray-core/common" + "github.com/xtls/xray-core/common/matcher/domain" + "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/features/routing" "github.com/xtls/xray-core/testing/mocks" @@ -231,11 +233,11 @@ func TestSerivceTestRoute(t *testing.T) { TargetTag: &router.RoutingRule_Tag{Tag: "out"}, }, { - Domain: []*router.Domain{{Type: router.Domain_Domain, Value: "com"}}, + Domain: []*domain.Domain{{Type: domain.MatchingType_Subdomain, Value: "com"}}, TargetTag: &router.RoutingRule_Tag{Tag: "out"}, }, { - SourceGeoip: []*router.GeoIP{{CountryCode: "private", Cidr: []*router.CIDR{{Ip: []byte{127, 0, 0, 0}, Prefix: 8}}}}, + SourceGeoip: []*geoip.GeoIP{{CountryCode: "private", Cidr: []*geoip.CIDR{{Ip: []byte{127, 0, 0, 0}, Prefix: 8}}}}, TargetTag: &router.RoutingRule_Tag{Tag: "out"}, }, { diff --git a/app/router/condition.go b/app/router/condition.go index 8c5d1de87b1b..c6e344f10247 100644 --- a/app/router/condition.go +++ b/app/router/condition.go @@ -6,8 +6,9 @@ import ( "go.starlark.net/starlark" "go.starlark.net/syntax" + dm "github.com/xtls/xray-core/common/matcher/domain" + "github.com/xtls/xray-core/common/matcher/str" "github.com/xtls/xray-core/common/net" - "github.com/xtls/xray-core/common/strmatcher" "github.com/xtls/xray-core/features/routing" ) @@ -41,14 +42,14 @@ func (v *ConditionChan) Len() int { return len(*v) } -var matcherTypeMap = map[Domain_Type]strmatcher.Type{ - Domain_Plain: strmatcher.Substr, - Domain_Regex: strmatcher.Regex, - Domain_Domain: strmatcher.Domain, - Domain_Full: strmatcher.Full, +var matcherTypeMap = map[dm.MatchingType]str.Type{ + dm.MatchingType_Keyword: str.Substr, + dm.MatchingType_Regex: str.Regex, + dm.MatchingType_Subdomain: str.Domain, + dm.MatchingType_Full: str.Full, } -func domainToMatcher(domain *Domain) (strmatcher.Matcher, error) { +func domainToMatcher(domain *dm.Domain) (str.Matcher, error) { matcherType, f := matcherTypeMap[domain.Type] if !f { return nil, newError("unsupported domain type", domain.Type) @@ -63,11 +64,11 @@ func domainToMatcher(domain *Domain) (strmatcher.Matcher, error) { } type DomainMatcher struct { - matchers strmatcher.IndexMatcher + matchers str.IndexMatcher } -func NewDomainMatcher(domains []*Domain) (*DomainMatcher, error) { - g := new(strmatcher.MatcherGroup) +func NewDomainMatcher(domains []*dm.Domain) (*DomainMatcher, error) { + g := new(str.MatcherGroup) for _, d := range domains { m, err := domainToMatcher(d) if err != nil { @@ -94,47 +95,6 @@ func (m *DomainMatcher) Apply(ctx routing.Context) bool { return m.ApplyDomain(strings.ToLower(domain)) } -type MultiGeoIPMatcher struct { - matchers []*GeoIPMatcher - onSource bool -} - -func NewMultiGeoIPMatcher(geoips []*GeoIP, onSource bool) (*MultiGeoIPMatcher, error) { - var matchers []*GeoIPMatcher - for _, geoip := range geoips { - matcher, err := globalGeoIPContainer.Add(geoip) - if err != nil { - return nil, err - } - matchers = append(matchers, matcher) - } - - matcher := &MultiGeoIPMatcher{ - matchers: matchers, - onSource: onSource, - } - - return matcher, nil -} - -// Apply implements Condition. -func (m *MultiGeoIPMatcher) Apply(ctx routing.Context) bool { - var ips []net.IP - if m.onSource { - ips = ctx.GetSourceIPs() - } else { - ips = ctx.GetTargetIPs() - } - for _, ip := range ips { - for _, matcher := range m.matchers { - if matcher.Match(ip) { - return true - } - } - } - return false -} - type PortMatcher struct { port net.MemoryPortList onSource bool diff --git a/app/router/condition_test.go b/app/router/condition_test.go index 3f7185e6633c..2ee1c0202cae 100644 --- a/app/router/condition_test.go +++ b/app/router/condition_test.go @@ -11,6 +11,9 @@ import ( . "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/errors" + "github.com/xtls/xray-core/common/matcher/domain" + "github.com/xtls/xray-core/common/matcher/geoip" + "github.com/xtls/xray-core/common/matcher/geosite" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/platform" "github.com/xtls/xray-core/common/platform/filesystem" @@ -26,10 +29,10 @@ func init() { common.Must(err) if _, err := os.Stat(platform.GetAssetLocation("geoip.dat")); err != nil && os.IsNotExist(err) { - common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoip.dat"), filepath.Join(wd, "..", "..", "release", "config", "geoip.dat"))) + common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoip.dat"), filepath.Join(wd, "..", "..", "resources", "geoip.dat"))) } if _, err := os.Stat(platform.GetAssetLocation("geosite.dat")); err != nil && os.IsNotExist(err) { - common.Must(filesystem.CopyFile(platform.GetAssetLocation("geosite.dat"), filepath.Join(wd, "..", "..", "release", "config", "geosite.dat"))) + common.Must(filesystem.CopyFile(platform.GetAssetLocation("geosite.dat"), filepath.Join(wd, "..", "..", "resources", "geosite.dat"))) } } @@ -61,18 +64,18 @@ func TestRoutingRule(t *testing.T) { }{ { rule: &RoutingRule{ - Domain: []*Domain{ + Domain: []*domain.Domain{ { Value: "example.com", - Type: Domain_Plain, + Type: domain.MatchingType_Keyword, }, { Value: "google.com", - Type: Domain_Domain, + Type: domain.MatchingType_Subdomain, }, { Value: "^facebook\\.com$", - Type: Domain_Regex, + Type: domain.MatchingType_Regex, }, }, }, @@ -109,7 +112,7 @@ func TestRoutingRule(t *testing.T) { }, { rule: &RoutingRule{ - Cidr: []*CIDR{ + Cidr: []*geoip.CIDR{ { Ip: []byte{8, 8, 8, 8}, Prefix: 32, @@ -145,9 +148,9 @@ func TestRoutingRule(t *testing.T) { }, { rule: &RoutingRule{ - Geoip: []*GeoIP{ + Geoip: []*geoip.GeoIP{ { - Cidr: []*CIDR{ + Cidr: []*geoip.CIDR{ { Ip: []byte{8, 8, 8, 8}, Prefix: 32, @@ -185,7 +188,7 @@ func TestRoutingRule(t *testing.T) { }, { rule: &RoutingRule{ - SourceCidr: []*CIDR{ + SourceCidr: []*geoip.CIDR{ { Ip: []byte{192, 168, 0, 0}, Prefix: 16, @@ -333,19 +336,19 @@ func TestRoutingRule(t *testing.T) { } } -func loadGeoSite(country string) ([]*Domain, error) { +func loadGeoSite(country string) ([]*domain.Domain, error) { geositeBytes, err := filesystem.ReadAsset("geosite.dat") if err != nil { return nil, err } - var geositeList GeoSiteList + var geositeList geosite.GeoSiteList if err := proto.Unmarshal(geositeBytes, &geositeList); err != nil { return nil, err } for _, site := range geositeList.Entry { if site.CountryCode == country { - return site.Domain, nil + return geosite.ToDomains(site.Domain), nil } } @@ -394,13 +397,32 @@ func TestChinaSites(t *testing.T) { } } +func loadGeoIP(country string) ([]*geoip.CIDR, error) { + geoipBytes, err := filesystem.ReadAsset("dat") + if err != nil { + return nil, err + } + var geoipList geoip.GeoIPList + if err := proto.Unmarshal(geoipBytes, &geoipList); err != nil { + return nil, err + } + + for _, geoip := range geoipList.Entry { + if geoip.CountryCode == country { + return geoip.Cidr, nil + } + } + + panic("country not found: " + country) +} + func BenchmarkMultiGeoIPMatcher(b *testing.B) { - var geoips []*GeoIP + var geoips []*geoip.GeoIP { ips, err := loadGeoIP("CN") common.Must(err) - geoips = append(geoips, &GeoIP{ + geoips = append(geoips, &geoip.GeoIP{ CountryCode: "CN", Cidr: ips, }) @@ -409,7 +431,7 @@ func BenchmarkMultiGeoIPMatcher(b *testing.B) { { ips, err := loadGeoIP("JP") common.Must(err) - geoips = append(geoips, &GeoIP{ + geoips = append(geoips, &geoip.GeoIP{ CountryCode: "JP", Cidr: ips, }) @@ -418,7 +440,7 @@ func BenchmarkMultiGeoIPMatcher(b *testing.B) { { ips, err := loadGeoIP("CA") common.Must(err) - geoips = append(geoips, &GeoIP{ + geoips = append(geoips, &geoip.GeoIP{ CountryCode: "CA", Cidr: ips, }) @@ -427,13 +449,13 @@ func BenchmarkMultiGeoIPMatcher(b *testing.B) { { ips, err := loadGeoIP("US") common.Must(err) - geoips = append(geoips, &GeoIP{ + geoips = append(geoips, &geoip.GeoIP{ CountryCode: "US", Cidr: ips, }) } - matcher, err := NewMultiGeoIPMatcher(geoips, false) + matcher, err := geoip.NewMultiGeoIPMatcher(geoips, false) common.Must(err) ctx := withOutbound(&session.Outbound{Target: net.TCPDestination(net.ParseAddress("8.8.8.8"), 80)}) diff --git a/app/router/config.go b/app/router/config.go index 07167a530198..6fdfeda8b994 100644 --- a/app/router/config.go +++ b/app/router/config.go @@ -1,50 +1,12 @@ package router import ( + "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/features/outbound" "github.com/xtls/xray-core/features/routing" ) -// CIDRList is an alias of []*CIDR to provide sort.Interface. -type CIDRList []*CIDR - -// Len implements sort.Interface. -func (l *CIDRList) Len() int { - return len(*l) -} - -// Less implements sort.Interface. -func (l *CIDRList) Less(i int, j int) bool { - ci := (*l)[i] - cj := (*l)[j] - - if len(ci.Ip) < len(cj.Ip) { - return true - } - - if len(ci.Ip) > len(cj.Ip) { - return false - } - - for k := 0; k < len(ci.Ip); k++ { - if ci.Ip[k] < cj.Ip[k] { - return true - } - - if ci.Ip[k] > cj.Ip[k] { - return false - } - } - - return ci.Prefix < cj.Prefix -} - -// Swap implements sort.Interface. -func (l *CIDRList) Swap(i int, j int) { - (*l)[i], (*l)[j] = (*l)[j], (*l)[i] -} - type Rule struct { Tag string Balancer *Balancer @@ -99,13 +61,13 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) { } if len(rr.Geoip) > 0 { - cond, err := NewMultiGeoIPMatcher(rr.Geoip, false) + cond, err := geoip.NewMultiGeoIPMatcher(rr.Geoip, false) if err != nil { return nil, err } conds.Add(cond) } else if len(rr.Cidr) > 0 { - cond, err := NewMultiGeoIPMatcher([]*GeoIP{{Cidr: rr.Cidr}}, false) + cond, err := geoip.NewMultiGeoIPMatcher([]*geoip.GeoIP{{Cidr: rr.Cidr}}, false) if err != nil { return nil, err } @@ -113,13 +75,13 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) { } if len(rr.SourceGeoip) > 0 { - cond, err := NewMultiGeoIPMatcher(rr.SourceGeoip, true) + cond, err := geoip.NewMultiGeoIPMatcher(rr.SourceGeoip, true) if err != nil { return nil, err } conds.Add(cond) } else if len(rr.SourceCidr) > 0 { - cond, err := NewMultiGeoIPMatcher([]*GeoIP{{Cidr: rr.SourceCidr}}, true) + cond, err := geoip.NewMultiGeoIPMatcher([]*geoip.GeoIP{{Cidr: rr.SourceCidr}}, true) if err != nil { return nil, err } diff --git a/app/router/config.pb.go b/app/router/config.pb.go index 69abd3706158..ce69e5328412 100644 --- a/app/router/config.pb.go +++ b/app/router/config.pb.go @@ -1,13 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 -// protoc v3.14.0 +// protoc v3.15.6 // source: app/router/config.proto package router import ( proto "github.com/golang/protobuf/proto" + domain "github.com/xtls/xray-core/common/matcher/domain" + geoip "github.com/xtls/xray-core/common/matcher/geoip" net "github.com/xtls/xray-core/common/net" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" @@ -26,63 +28,6 @@ const ( // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 -// Type of domain value. -type Domain_Type int32 - -const ( - // The value is used as is. - Domain_Plain Domain_Type = 0 - // The value is used as a regular expression. - Domain_Regex Domain_Type = 1 - // The value is a root domain. - Domain_Domain Domain_Type = 2 - // The value is a domain. - Domain_Full Domain_Type = 3 -) - -// Enum value maps for Domain_Type. -var ( - Domain_Type_name = map[int32]string{ - 0: "Plain", - 1: "Regex", - 2: "Domain", - 3: "Full", - } - Domain_Type_value = map[string]int32{ - "Plain": 0, - "Regex": 1, - "Domain": 2, - "Full": 3, - } -) - -func (x Domain_Type) Enum() *Domain_Type { - p := new(Domain_Type) - *p = x - return p -} - -func (x Domain_Type) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Domain_Type) Descriptor() protoreflect.EnumDescriptor { - return file_app_router_config_proto_enumTypes[0].Descriptor() -} - -func (Domain_Type) Type() protoreflect.EnumType { - return &file_app_router_config_proto_enumTypes[0] -} - -func (x Domain_Type) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Domain_Type.Descriptor instead. -func (Domain_Type) EnumDescriptor() ([]byte, []int) { - return file_app_router_config_proto_rawDescGZIP(), []int{0, 0} -} - type Config_DomainStrategy int32 const ( @@ -123,11 +68,11 @@ func (x Config_DomainStrategy) String() string { } func (Config_DomainStrategy) Descriptor() protoreflect.EnumDescriptor { - return file_app_router_config_proto_enumTypes[1].Descriptor() + return file_app_router_config_proto_enumTypes[0].Descriptor() } func (Config_DomainStrategy) Type() protoreflect.EnumType { - return &file_app_router_config_proto_enumTypes[1] + return &file_app_router_config_proto_enumTypes[0] } func (x Config_DomainStrategy) Number() protoreflect.EnumNumber { @@ -136,336 +81,7 @@ func (x Config_DomainStrategy) Number() protoreflect.EnumNumber { // Deprecated: Use Config_DomainStrategy.Descriptor instead. func (Config_DomainStrategy) EnumDescriptor() ([]byte, []int) { - return file_app_router_config_proto_rawDescGZIP(), []int{8, 0} -} - -// Domain for routing decision. -type Domain struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Domain matching type. - Type Domain_Type `protobuf:"varint,1,opt,name=type,proto3,enum=xray.app.router.Domain_Type" json:"type,omitempty"` - // Domain value. - Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` - // Attributes of this domain. May be used for filtering. - Attribute []*Domain_Attribute `protobuf:"bytes,3,rep,name=attribute,proto3" json:"attribute,omitempty"` -} - -func (x *Domain) Reset() { - *x = Domain{} - if protoimpl.UnsafeEnabled { - mi := &file_app_router_config_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Domain) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Domain) ProtoMessage() {} - -func (x *Domain) ProtoReflect() protoreflect.Message { - mi := &file_app_router_config_proto_msgTypes[0] - 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 Domain.ProtoReflect.Descriptor instead. -func (*Domain) Descriptor() ([]byte, []int) { - return file_app_router_config_proto_rawDescGZIP(), []int{0} -} - -func (x *Domain) GetType() Domain_Type { - if x != nil { - return x.Type - } - return Domain_Plain -} - -func (x *Domain) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -func (x *Domain) GetAttribute() []*Domain_Attribute { - if x != nil { - return x.Attribute - } - return nil -} - -// IP for routing decision, in CIDR form. -type CIDR struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // IP address, should be either 4 or 16 bytes. - Ip []byte `protobuf:"bytes,1,opt,name=ip,proto3" json:"ip,omitempty"` - // Number of leading ones in the network mask. - Prefix uint32 `protobuf:"varint,2,opt,name=prefix,proto3" json:"prefix,omitempty"` -} - -func (x *CIDR) Reset() { - *x = CIDR{} - if protoimpl.UnsafeEnabled { - mi := &file_app_router_config_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CIDR) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CIDR) ProtoMessage() {} - -func (x *CIDR) ProtoReflect() protoreflect.Message { - mi := &file_app_router_config_proto_msgTypes[1] - 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 CIDR.ProtoReflect.Descriptor instead. -func (*CIDR) Descriptor() ([]byte, []int) { - return file_app_router_config_proto_rawDescGZIP(), []int{1} -} - -func (x *CIDR) GetIp() []byte { - if x != nil { - return x.Ip - } - return nil -} - -func (x *CIDR) GetPrefix() uint32 { - if x != nil { - return x.Prefix - } - return 0 -} - -type GeoIP struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - CountryCode string `protobuf:"bytes,1,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"` - Cidr []*CIDR `protobuf:"bytes,2,rep,name=cidr,proto3" json:"cidr,omitempty"` -} - -func (x *GeoIP) Reset() { - *x = GeoIP{} - if protoimpl.UnsafeEnabled { - mi := &file_app_router_config_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GeoIP) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GeoIP) ProtoMessage() {} - -func (x *GeoIP) ProtoReflect() protoreflect.Message { - mi := &file_app_router_config_proto_msgTypes[2] - 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 GeoIP.ProtoReflect.Descriptor instead. -func (*GeoIP) Descriptor() ([]byte, []int) { - return file_app_router_config_proto_rawDescGZIP(), []int{2} -} - -func (x *GeoIP) GetCountryCode() string { - if x != nil { - return x.CountryCode - } - return "" -} - -func (x *GeoIP) GetCidr() []*CIDR { - if x != nil { - return x.Cidr - } - return nil -} - -type GeoIPList struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Entry []*GeoIP `protobuf:"bytes,1,rep,name=entry,proto3" json:"entry,omitempty"` -} - -func (x *GeoIPList) Reset() { - *x = GeoIPList{} - if protoimpl.UnsafeEnabled { - mi := &file_app_router_config_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GeoIPList) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GeoIPList) ProtoMessage() {} - -func (x *GeoIPList) ProtoReflect() protoreflect.Message { - mi := &file_app_router_config_proto_msgTypes[3] - 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 GeoIPList.ProtoReflect.Descriptor instead. -func (*GeoIPList) Descriptor() ([]byte, []int) { - return file_app_router_config_proto_rawDescGZIP(), []int{3} -} - -func (x *GeoIPList) GetEntry() []*GeoIP { - if x != nil { - return x.Entry - } - return nil -} - -type GeoSite struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - CountryCode string `protobuf:"bytes,1,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"` - Domain []*Domain `protobuf:"bytes,2,rep,name=domain,proto3" json:"domain,omitempty"` -} - -func (x *GeoSite) Reset() { - *x = GeoSite{} - if protoimpl.UnsafeEnabled { - mi := &file_app_router_config_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GeoSite) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GeoSite) ProtoMessage() {} - -func (x *GeoSite) ProtoReflect() protoreflect.Message { - mi := &file_app_router_config_proto_msgTypes[4] - 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 GeoSite.ProtoReflect.Descriptor instead. -func (*GeoSite) Descriptor() ([]byte, []int) { - return file_app_router_config_proto_rawDescGZIP(), []int{4} -} - -func (x *GeoSite) GetCountryCode() string { - if x != nil { - return x.CountryCode - } - return "" -} - -func (x *GeoSite) GetDomain() []*Domain { - if x != nil { - return x.Domain - } - return nil -} - -type GeoSiteList struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Entry []*GeoSite `protobuf:"bytes,1,rep,name=entry,proto3" json:"entry,omitempty"` -} - -func (x *GeoSiteList) Reset() { - *x = GeoSiteList{} - if protoimpl.UnsafeEnabled { - mi := &file_app_router_config_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GeoSiteList) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GeoSiteList) ProtoMessage() {} - -func (x *GeoSiteList) ProtoReflect() protoreflect.Message { - mi := &file_app_router_config_proto_msgTypes[5] - 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 GeoSiteList.ProtoReflect.Descriptor instead. -func (*GeoSiteList) Descriptor() ([]byte, []int) { - return file_app_router_config_proto_rawDescGZIP(), []int{5} -} - -func (x *GeoSiteList) GetEntry() []*GeoSite { - if x != nil { - return x.Entry - } - return nil + return file_app_router_config_proto_rawDescGZIP(), []int{2, 0} } type RoutingRule struct { @@ -478,17 +94,17 @@ type RoutingRule struct { // *RoutingRule_BalancingTag TargetTag isRoutingRule_TargetTag `protobuf_oneof:"target_tag"` // List of domains for target domain matching. - Domain []*Domain `protobuf:"bytes,2,rep,name=domain,proto3" json:"domain,omitempty"` + Domain []*domain.Domain `protobuf:"bytes,2,rep,name=domain,proto3" json:"domain,omitempty"` // List of CIDRs for target IP address matching. // Deprecated. Use geoip below. // // Deprecated: Do not use. - Cidr []*CIDR `protobuf:"bytes,3,rep,name=cidr,proto3" json:"cidr,omitempty"` + Cidr []*geoip.CIDR `protobuf:"bytes,3,rep,name=cidr,proto3" json:"cidr,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 []*GeoIP `protobuf:"bytes,10,rep,name=geoip,proto3" json:"geoip,omitempty"` + Geoip []*geoip.GeoIP `protobuf:"bytes,10,rep,name=geoip,proto3" json:"geoip,omitempty"` // A range of port [from, to]. If the destination port is in this range, this // rule takes effect. Deprecated. Use port_list. // @@ -505,10 +121,10 @@ type RoutingRule struct { // List of CIDRs for source IP address matching. // // Deprecated: Do not use. - SourceCidr []*CIDR `protobuf:"bytes,6,rep,name=source_cidr,json=sourceCidr,proto3" json:"source_cidr,omitempty"` + SourceCidr []*geoip.CIDR `protobuf:"bytes,6,rep,name=source_cidr,json=sourceCidr,proto3" json:"source_cidr,omitempty"` // List of GeoIPs for source IP address matching. If this entry exists, the // source_cidr above will have no effect. - SourceGeoip []*GeoIP `protobuf:"bytes,11,rep,name=source_geoip,json=sourceGeoip,proto3" json:"source_geoip,omitempty"` + SourceGeoip []*geoip.GeoIP `protobuf:"bytes,11,rep,name=source_geoip,json=sourceGeoip,proto3" json:"source_geoip,omitempty"` // List of ports for source port matching. SourcePortList *net.PortList `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"` @@ -520,7 +136,7 @@ type RoutingRule struct { func (x *RoutingRule) Reset() { *x = RoutingRule{} if protoimpl.UnsafeEnabled { - mi := &file_app_router_config_proto_msgTypes[6] + mi := &file_app_router_config_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -533,7 +149,7 @@ func (x *RoutingRule) String() string { func (*RoutingRule) ProtoMessage() {} func (x *RoutingRule) ProtoReflect() protoreflect.Message { - mi := &file_app_router_config_proto_msgTypes[6] + mi := &file_app_router_config_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -546,7 +162,7 @@ func (x *RoutingRule) ProtoReflect() protoreflect.Message { // Deprecated: Use RoutingRule.ProtoReflect.Descriptor instead. func (*RoutingRule) Descriptor() ([]byte, []int) { - return file_app_router_config_proto_rawDescGZIP(), []int{6} + return file_app_router_config_proto_rawDescGZIP(), []int{0} } func (m *RoutingRule) GetTargetTag() isRoutingRule_TargetTag { @@ -570,7 +186,7 @@ func (x *RoutingRule) GetBalancingTag() string { return "" } -func (x *RoutingRule) GetDomain() []*Domain { +func (x *RoutingRule) GetDomain() []*domain.Domain { if x != nil { return x.Domain } @@ -578,14 +194,14 @@ func (x *RoutingRule) GetDomain() []*Domain { } // Deprecated: Do not use. -func (x *RoutingRule) GetCidr() []*CIDR { +func (x *RoutingRule) GetCidr() []*geoip.CIDR { if x != nil { return x.Cidr } return nil } -func (x *RoutingRule) GetGeoip() []*GeoIP { +func (x *RoutingRule) GetGeoip() []*geoip.GeoIP { if x != nil { return x.Geoip } @@ -623,14 +239,14 @@ func (x *RoutingRule) GetNetworks() []net.Network { } // Deprecated: Do not use. -func (x *RoutingRule) GetSourceCidr() []*CIDR { +func (x *RoutingRule) GetSourceCidr() []*geoip.CIDR { if x != nil { return x.SourceCidr } return nil } -func (x *RoutingRule) GetSourceGeoip() []*GeoIP { +func (x *RoutingRule) GetSourceGeoip() []*geoip.GeoIP { if x != nil { return x.SourceGeoip } @@ -702,7 +318,7 @@ type BalancingRule struct { func (x *BalancingRule) Reset() { *x = BalancingRule{} if protoimpl.UnsafeEnabled { - mi := &file_app_router_config_proto_msgTypes[7] + mi := &file_app_router_config_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -715,7 +331,7 @@ func (x *BalancingRule) String() string { func (*BalancingRule) ProtoMessage() {} func (x *BalancingRule) ProtoReflect() protoreflect.Message { - mi := &file_app_router_config_proto_msgTypes[7] + mi := &file_app_router_config_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -728,7 +344,7 @@ func (x *BalancingRule) ProtoReflect() protoreflect.Message { // Deprecated: Use BalancingRule.ProtoReflect.Descriptor instead. func (*BalancingRule) Descriptor() ([]byte, []int) { - return file_app_router_config_proto_rawDescGZIP(), []int{7} + return file_app_router_config_proto_rawDescGZIP(), []int{1} } func (x *BalancingRule) GetTag() string { @@ -758,7 +374,7 @@ type Config struct { func (x *Config) Reset() { *x = Config{} if protoimpl.UnsafeEnabled { - mi := &file_app_router_config_proto_msgTypes[8] + mi := &file_app_router_config_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -771,7 +387,7 @@ func (x *Config) String() string { func (*Config) ProtoMessage() {} func (x *Config) ProtoReflect() protoreflect.Message { - mi := &file_app_router_config_proto_msgTypes[8] + mi := &file_app_router_config_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -784,7 +400,7 @@ func (x *Config) ProtoReflect() protoreflect.Message { // Deprecated: Use Config.ProtoReflect.Descriptor instead. func (*Config) Descriptor() ([]byte, []int) { - return file_app_router_config_proto_rawDescGZIP(), []int{8} + return file_app_router_config_proto_rawDescGZIP(), []int{2} } func (x *Config) GetDomainStrategy() Config_DomainStrategy { @@ -808,94 +424,6 @@ func (x *Config) GetBalancingRule() []*BalancingRule { return nil } -type Domain_Attribute struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - // Types that are assignable to TypedValue: - // *Domain_Attribute_BoolValue - // *Domain_Attribute_IntValue - TypedValue isDomain_Attribute_TypedValue `protobuf_oneof:"typed_value"` -} - -func (x *Domain_Attribute) Reset() { - *x = Domain_Attribute{} - if protoimpl.UnsafeEnabled { - mi := &file_app_router_config_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Domain_Attribute) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Domain_Attribute) ProtoMessage() {} - -func (x *Domain_Attribute) ProtoReflect() protoreflect.Message { - mi := &file_app_router_config_proto_msgTypes[9] - 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 Domain_Attribute.ProtoReflect.Descriptor instead. -func (*Domain_Attribute) Descriptor() ([]byte, []int) { - return file_app_router_config_proto_rawDescGZIP(), []int{0, 0} -} - -func (x *Domain_Attribute) GetKey() string { - if x != nil { - return x.Key - } - return "" -} - -func (m *Domain_Attribute) GetTypedValue() isDomain_Attribute_TypedValue { - if m != nil { - return m.TypedValue - } - return nil -} - -func (x *Domain_Attribute) GetBoolValue() bool { - if x, ok := x.GetTypedValue().(*Domain_Attribute_BoolValue); ok { - return x.BoolValue - } - return false -} - -func (x *Domain_Attribute) GetIntValue() int64 { - if x, ok := x.GetTypedValue().(*Domain_Attribute_IntValue); ok { - return x.IntValue - } - return 0 -} - -type isDomain_Attribute_TypedValue interface { - isDomain_Attribute_TypedValue() -} - -type Domain_Attribute_BoolValue struct { - BoolValue bool `protobuf:"varint,2,opt,name=bool_value,json=boolValue,proto3,oneof"` -} - -type Domain_Attribute_IntValue struct { - IntValue int64 `protobuf:"varint,3,opt,name=int_value,json=intValue,proto3,oneof"` -} - -func (*Domain_Attribute_BoolValue) isDomain_Attribute_TypedValue() {} - -func (*Domain_Attribute_IntValue) isDomain_Attribute_TypedValue() {} - var File_app_router_config_proto protoreflect.FileDescriptor var file_app_router_config_proto_rawDesc = []byte{ @@ -904,126 +432,92 @@ var file_app_router_config_proto_rawDesc = []byte{ 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x1a, 0x15, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x6e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb3, 0x02, 0x0a, 0x06, - 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x30, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, - 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3f, - 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x1a, - 0x6c, 0x0a, 0x09, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1f, - 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, - 0x1d, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0d, - 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x32, 0x0a, - 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x10, 0x00, - 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, - 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, - 0x03, 0x22, 0x2e, 0x0a, 0x04, 0x43, 0x49, 0x44, 0x52, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, - 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, - 0x78, 0x22, 0x55, 0x0a, 0x05, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x29, 0x0a, - 0x04, 0x63, 0x69, 0x64, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x49, - 0x44, 0x52, 0x52, 0x04, 0x63, 0x69, 0x64, 0x72, 0x22, 0x39, 0x0a, 0x09, 0x47, 0x65, 0x6f, 0x49, - 0x50, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, - 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x65, 0x6e, - 0x74, 0x72, 0x79, 0x22, 0x5d, 0x0a, 0x07, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x12, 0x21, - 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, - 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, - 0x69, 0x6e, 0x22, 0x3d, 0x0a, 0x0b, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, - 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, - 0x79, 0x22, 0x8e, 0x06, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x2f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2f, + 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0xc1, 0x06, 0x0a, 0x0b, 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, 0x2f, 0x0a, 0x06, - 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x78, - 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, - 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x2d, 0x0a, - 0x04, 0x63, 0x69, 0x64, 0x72, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x49, - 0x44, 0x52, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x63, 0x69, 0x64, 0x72, 0x12, 0x2c, 0x0a, 0x05, - 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, - 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x3d, 0x0a, 0x0a, 0x70, 0x6f, - 0x72, 0x74, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, - 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, - 0x70, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x70, 0x6f, 0x72, - 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, - 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, - 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x08, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, - 0x74, 0x12, 0x43, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x6c, 0x69, 0x73, - 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x52, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x12, 0x3a, 0x0a, 0x0b, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x69, 0x64, 0x72, 0x18, 0x06, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x15, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x2e, 0x43, 0x49, 0x44, 0x52, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0a, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x43, 0x69, 0x64, 0x72, 0x12, 0x39, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x5f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, - 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x65, - 0x6f, 0x69, 0x70, 0x12, 0x43, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x6f, - 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x67, 0x12, 0x3a, 0x0a, 0x06, + 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x78, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x72, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x37, 0x0a, 0x04, 0x63, 0x69, 0x64, 0x72, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, + 0x69, 0x70, 0x2e, 0x43, 0x49, 0x44, 0x52, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x63, 0x69, 0x64, + 0x72, 0x12, 0x36, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2e, 0x47, 0x65, 0x6f, + 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x3d, 0x0a, 0x0a, 0x70, 0x6f, 0x72, + 0x74, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, - 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 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, 0x42, 0x0c, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, - 0x61, 0x67, 0x22, 0x4e, 0x0a, 0x0d, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, - 0x75, 0x6c, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, - 0x64, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x10, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x22, 0x9b, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4f, 0x0a, - 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, - 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, 0x30, - 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, - 0x72, 0x61, 0x79, 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, 0x45, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, - 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 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, 0x22, 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, 0x4f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, - 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, - 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0xaa, - 0x02, 0x0f, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x50, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x70, + 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x70, 0x6f, 0x72, 0x74, + 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, + 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x6f, + 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x08, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, + 0x12, 0x43, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x6c, 0x69, 0x73, 0x74, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x4c, 0x69, 0x73, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x52, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x12, 0x44, 0x0a, 0x0b, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x69, 0x64, 0x72, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2e, 0x43, 0x49, 0x44, + 0x52, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x69, 0x64, + 0x72, 0x12, 0x43, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x67, 0x65, 0x6f, 0x69, + 0x70, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, + 0x6f, 0x69, 0x70, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x47, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x43, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, + 0x65, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 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, 0x42, 0x0c, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x5f, 0x74, 0x61, 0x67, 0x22, 0x4e, 0x0a, 0x0d, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, + 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62, + 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x9b, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x4f, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, + 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 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, 0x30, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 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, 0x45, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, + 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, + 0x61, 0x79, 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, 0x22, 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, 0x4f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, + 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, + 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0xaa, 0x02, 0x0f, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1038,51 +532,40 @@ func file_app_router_config_proto_rawDescGZIP() []byte { return file_app_router_config_proto_rawDescData } -var file_app_router_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_app_router_config_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_app_router_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_app_router_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_app_router_config_proto_goTypes = []interface{}{ - (Domain_Type)(0), // 0: xray.app.router.Domain.Type - (Config_DomainStrategy)(0), // 1: xray.app.router.Config.DomainStrategy - (*Domain)(nil), // 2: xray.app.router.Domain - (*CIDR)(nil), // 3: xray.app.router.CIDR - (*GeoIP)(nil), // 4: xray.app.router.GeoIP - (*GeoIPList)(nil), // 5: xray.app.router.GeoIPList - (*GeoSite)(nil), // 6: xray.app.router.GeoSite - (*GeoSiteList)(nil), // 7: xray.app.router.GeoSiteList - (*RoutingRule)(nil), // 8: xray.app.router.RoutingRule - (*BalancingRule)(nil), // 9: xray.app.router.BalancingRule - (*Config)(nil), // 10: xray.app.router.Config - (*Domain_Attribute)(nil), // 11: xray.app.router.Domain.Attribute - (*net.PortRange)(nil), // 12: xray.common.net.PortRange - (*net.PortList)(nil), // 13: xray.common.net.PortList - (*net.NetworkList)(nil), // 14: xray.common.net.NetworkList - (net.Network)(0), // 15: xray.common.net.Network + (Config_DomainStrategy)(0), // 0: xray.app.router.Config.DomainStrategy + (*RoutingRule)(nil), // 1: xray.app.router.RoutingRule + (*BalancingRule)(nil), // 2: xray.app.router.BalancingRule + (*Config)(nil), // 3: xray.app.router.Config + (*domain.Domain)(nil), // 4: xray.common.matcher.domain.Domain + (*geoip.CIDR)(nil), // 5: xray.common.matcher.geoip.CIDR + (*geoip.GeoIP)(nil), // 6: xray.common.matcher.geoip.GeoIP + (*net.PortRange)(nil), // 7: xray.common.net.PortRange + (*net.PortList)(nil), // 8: xray.common.net.PortList + (*net.NetworkList)(nil), // 9: xray.common.net.NetworkList + (net.Network)(0), // 10: xray.common.net.Network } var file_app_router_config_proto_depIdxs = []int32{ - 0, // 0: xray.app.router.Domain.type:type_name -> xray.app.router.Domain.Type - 11, // 1: xray.app.router.Domain.attribute:type_name -> xray.app.router.Domain.Attribute - 3, // 2: xray.app.router.GeoIP.cidr:type_name -> xray.app.router.CIDR - 4, // 3: xray.app.router.GeoIPList.entry:type_name -> xray.app.router.GeoIP - 2, // 4: xray.app.router.GeoSite.domain:type_name -> xray.app.router.Domain - 6, // 5: xray.app.router.GeoSiteList.entry:type_name -> xray.app.router.GeoSite - 2, // 6: xray.app.router.RoutingRule.domain:type_name -> xray.app.router.Domain - 3, // 7: xray.app.router.RoutingRule.cidr:type_name -> xray.app.router.CIDR - 4, // 8: xray.app.router.RoutingRule.geoip:type_name -> xray.app.router.GeoIP - 12, // 9: xray.app.router.RoutingRule.port_range:type_name -> xray.common.net.PortRange - 13, // 10: xray.app.router.RoutingRule.port_list:type_name -> xray.common.net.PortList - 14, // 11: xray.app.router.RoutingRule.network_list:type_name -> xray.common.net.NetworkList - 15, // 12: xray.app.router.RoutingRule.networks:type_name -> xray.common.net.Network - 3, // 13: xray.app.router.RoutingRule.source_cidr:type_name -> xray.app.router.CIDR - 4, // 14: xray.app.router.RoutingRule.source_geoip:type_name -> xray.app.router.GeoIP - 13, // 15: xray.app.router.RoutingRule.source_port_list:type_name -> xray.common.net.PortList - 1, // 16: xray.app.router.Config.domain_strategy:type_name -> xray.app.router.Config.DomainStrategy - 8, // 17: xray.app.router.Config.rule:type_name -> xray.app.router.RoutingRule - 9, // 18: xray.app.router.Config.balancing_rule:type_name -> xray.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 + 4, // 0: xray.app.router.RoutingRule.domain:type_name -> xray.common.matcher.domain.Domain + 5, // 1: xray.app.router.RoutingRule.cidr:type_name -> xray.common.matcher.geoip.CIDR + 6, // 2: xray.app.router.RoutingRule.geoip:type_name -> xray.common.matcher.geoip.GeoIP + 7, // 3: xray.app.router.RoutingRule.port_range:type_name -> xray.common.net.PortRange + 8, // 4: xray.app.router.RoutingRule.port_list:type_name -> xray.common.net.PortList + 9, // 5: xray.app.router.RoutingRule.network_list:type_name -> xray.common.net.NetworkList + 10, // 6: xray.app.router.RoutingRule.networks:type_name -> xray.common.net.Network + 5, // 7: xray.app.router.RoutingRule.source_cidr:type_name -> xray.common.matcher.geoip.CIDR + 6, // 8: xray.app.router.RoutingRule.source_geoip:type_name -> xray.common.matcher.geoip.GeoIP + 8, // 9: xray.app.router.RoutingRule.source_port_list:type_name -> xray.common.net.PortList + 0, // 10: xray.app.router.Config.domain_strategy:type_name -> xray.app.router.Config.DomainStrategy + 1, // 11: xray.app.router.Config.rule:type_name -> xray.app.router.RoutingRule + 2, // 12: xray.app.router.Config.balancing_rule:type_name -> xray.app.router.BalancingRule + 13, // [13:13] is the sub-list for method output_type + 13, // [13:13] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name } func init() { file_app_router_config_proto_init() } @@ -1092,78 +575,6 @@ func file_app_router_config_proto_init() { } if !protoimpl.UnsafeEnabled { file_app_router_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Domain); 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[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CIDR); 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[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GeoIP); 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[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GeoIPList); 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[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GeoSite); 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[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GeoSiteList); 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[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RoutingRule); i { case 0: return &v.state @@ -1175,7 +586,7 @@ func file_app_router_config_proto_init() { return nil } } - file_app_router_config_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_app_router_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BalancingRule); i { case 0: return &v.state @@ -1187,7 +598,7 @@ func file_app_router_config_proto_init() { return nil } } - file_app_router_config_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_app_router_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Config); i { case 0: return &v.state @@ -1199,34 +610,18 @@ func file_app_router_config_proto_init() { return nil } } - file_app_router_config_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Domain_Attribute); 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[6].OneofWrappers = []interface{}{ + file_app_router_config_proto_msgTypes[0].OneofWrappers = []interface{}{ (*RoutingRule_Tag)(nil), (*RoutingRule_BalancingTag)(nil), } - file_app_router_config_proto_msgTypes[9].OneofWrappers = []interface{}{ - (*Domain_Attribute_BoolValue)(nil), - (*Domain_Attribute_IntValue)(nil), - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_app_router_config_proto_rawDesc, - NumEnums: 2, - NumMessages: 10, + NumEnums: 1, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, diff --git a/app/router/config.proto b/app/router/config.proto index c5e655adeafc..ab243445af5a 100644 --- a/app/router/config.proto +++ b/app/router/config.proto @@ -8,66 +8,8 @@ option java_multiple_files = true; import "common/net/port.proto"; import "common/net/network.proto"; - -// Domain for routing decision. -message Domain { - // Type of domain value. - enum Type { - // The value is used as is. - Plain = 0; - // The value is used as a regular expression. - Regex = 1; - // The value is a root domain. - Domain = 2; - // The value is a domain. - Full = 3; - } - - // Domain matching type. - Type type = 1; - - // Domain value. - string value = 2; - - message Attribute { - string key = 1; - - oneof typed_value { - bool bool_value = 2; - int64 int_value = 3; - } - } - - // Attributes of this domain. May be used for filtering. - repeated Attribute attribute = 3; -} - -// IP for routing decision, in CIDR form. -message CIDR { - // IP address, should be either 4 or 16 bytes. - bytes ip = 1; - - // Number of leading ones in the network mask. - uint32 prefix = 2; -} - -message GeoIP { - string country_code = 1; - repeated CIDR cidr = 2; -} - -message GeoIPList { - repeated GeoIP entry = 1; -} - -message GeoSite { - string country_code = 1; - repeated Domain domain = 2; -} - -message GeoSiteList { - repeated GeoSite entry = 1; -} +import "common/matcher/domain/domain.proto"; +import "common/matcher/geoip/geoip.proto"; message RoutingRule { oneof target_tag { @@ -79,17 +21,17 @@ message RoutingRule { } // List of domains for target domain matching. - repeated Domain domain = 2; + repeated xray.common.matcher.domain.Domain domain = 2; // List of CIDRs for target IP address matching. // Deprecated. Use geoip below. - repeated CIDR cidr = 3 [deprecated = true]; + repeated xray.common.matcher.geoip.CIDR cidr = 3 [deprecated = true]; // 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 GeoIP geoip = 10; + repeated xray.common.matcher.geoip.GeoIP geoip = 10; // A range of port [from, to]. If the destination port is in this range, this // rule takes effect. Deprecated. Use port_list. @@ -105,11 +47,11 @@ message RoutingRule { repeated xray.common.net.Network networks = 13; // List of CIDRs for source IP address matching. - repeated CIDR source_cidr = 6 [deprecated = true]; + repeated xray.common.matcher.geoip.CIDR source_cidr = 6 [deprecated = true]; // List of GeoIPs for source IP address matching. If this entry exists, the // source_cidr above will have no effect. - repeated GeoIP source_geoip = 11; + repeated xray.common.matcher.geoip.GeoIP source_geoip = 11; // List of ports for source port matching. xray.common.net.PortList source_port_list = 16; diff --git a/app/router/router_test.go b/app/router/router_test.go index cd0b7154c992..f4e4cab0e602 100644 --- a/app/router/router_test.go +++ b/app/router/router_test.go @@ -7,6 +7,7 @@ import ( "github.com/golang/mock/gomock" . "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common" + "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/features/outbound" @@ -101,7 +102,7 @@ func TestIPOnDemand(t *testing.T) { TargetTag: &RoutingRule_Tag{ Tag: "test", }, - Cidr: []*CIDR{ + Cidr: []*geoip.CIDR{ { Ip: []byte{192, 168, 0, 0}, Prefix: 16, @@ -136,7 +137,7 @@ func TestIPIfNonMatchDomain(t *testing.T) { TargetTag: &RoutingRule_Tag{ Tag: "test", }, - Cidr: []*CIDR{ + Cidr: []*geoip.CIDR{ { Ip: []byte{192, 168, 0, 0}, Prefix: 16, @@ -171,7 +172,7 @@ func TestIPIfNonMatchIP(t *testing.T) { TargetTag: &RoutingRule_Tag{ Tag: "test", }, - Cidr: []*CIDR{ + Cidr: []*geoip.CIDR{ { Ip: []byte{127, 0, 0, 0}, Prefix: 8, diff --git a/app/stats/command/command.go b/app/stats/command/command.go index 3c9f54243696..ae227728d4fd 100644 --- a/app/stats/command/command.go +++ b/app/stats/command/command.go @@ -11,7 +11,7 @@ import ( "github.com/xtls/xray-core/app/stats" "github.com/xtls/xray-core/common" - "github.com/xtls/xray-core/common/strmatcher" + "github.com/xtls/xray-core/common/matcher/str" "github.com/xtls/xray-core/core" feature_stats "github.com/xtls/xray-core/features/stats" ) @@ -49,7 +49,7 @@ func (s *statsServer) GetStats(ctx context.Context, request *GetStatsRequest) (* } func (s *statsServer) QueryStats(ctx context.Context, request *QueryStatsRequest) (*QueryStatsResponse, error) { - matcher, err := strmatcher.Substr.New(request.Pattern) + matcher, err := str.Substr.New(request.Pattern) if err != nil { return nil, err } diff --git a/common/matcher/conf/conf.go b/common/matcher/conf/conf.go new file mode 100644 index 000000000000..9bd3f6674d51 --- /dev/null +++ b/common/matcher/conf/conf.go @@ -0,0 +1,3 @@ +package conf + +//go:generate go run github.com/xtls/xray-core/common/errors/errorgen diff --git a/common/matcher/conf/domain.go b/common/matcher/conf/domain.go new file mode 100644 index 000000000000..e71a9cc6f1c3 --- /dev/null +++ b/common/matcher/conf/domain.go @@ -0,0 +1,78 @@ +package conf + +import ( + "strings" + + dm "github.com/xtls/xray-core/common/matcher/domain" + "github.com/xtls/xray-core/common/matcher/geosite" +) + +func ParaseDomainRule(domain string) ([]*dm.Domain, error) { + if strings.HasPrefix(domain, "geosite:") { + country := strings.ToUpper(domain[8:]) + domains, err := geosite.LoadGeositeWithAttr("geosite.dat", country) + if err != nil { + return nil, newError("failed to load geosite: ", country).Base(err) + } + return domains, nil + } + var isExtDatFile = 0 + { + const prefix = "ext:" + if strings.HasPrefix(domain, prefix) { + isExtDatFile = len(prefix) + } + const prefixQualified = "ext-domain:" + if strings.HasPrefix(domain, prefixQualified) { + isExtDatFile = len(prefixQualified) + } + } + if isExtDatFile != 0 { + kv := strings.Split(domain[isExtDatFile:], ":") + if len(kv) != 2 { + return nil, newError("invalid external resource: ", domain) + } + filename := kv[0] + country := kv[1] + domains, err := geosite.LoadGeositeWithAttr(filename, country) + if err != nil { + return nil, newError("failed to load external sites: ", country, " from ", filename).Base(err) + } + return domains, nil + } + + domainRule := new(dm.Domain) + switch { + case strings.HasPrefix(domain, "regexp:"): + domainRule.Type = dm.MatchingType_Regex + domainRule.Value = domain[7:] + + case strings.HasPrefix(domain, "domain:"): + domainRule.Type = dm.MatchingType_Subdomain + domainRule.Value = domain[7:] + + case strings.HasPrefix(domain, "full:"): + domainRule.Type = dm.MatchingType_Full + domainRule.Value = domain[5:] + + case strings.HasPrefix(domain, "keyword:"): + domainRule.Type = dm.MatchingType_Keyword + domainRule.Value = domain[8:] + + case strings.HasPrefix(domain, "dotless:"): + domainRule.Type = dm.MatchingType_Regex + switch substr := domain[8:]; { + case substr == "": + domainRule.Value = "^[^.]*$" + case !strings.Contains(substr, "."): + domainRule.Value = "^[^.]*" + substr + "[^.]*$" + default: + return nil, newError("substr in dotless rule should not contain a dot: ", substr) + } + + default: + domainRule.Type = dm.MatchingType_Keyword + domainRule.Value = domain + } + return []*dm.Domain{domainRule}, nil +} diff --git a/common/matcher/conf/errors.generated.go b/common/matcher/conf/errors.generated.go new file mode 100644 index 000000000000..a80cc1405061 --- /dev/null +++ b/common/matcher/conf/errors.generated.go @@ -0,0 +1,9 @@ +package conf + +import "github.com/xtls/xray-core/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} diff --git a/common/matcher/domain/domain.go b/common/matcher/domain/domain.go new file mode 100644 index 000000000000..29651ac936e2 --- /dev/null +++ b/common/matcher/domain/domain.go @@ -0,0 +1,3 @@ +package domain + +//go:generate go run github.com/xtls/xray-core/common/errors/errorgen diff --git a/common/matcher/domain/domain.pb.go b/common/matcher/domain/domain.pb.go new file mode 100644 index 000000000000..94e94f9d6f80 --- /dev/null +++ b/common/matcher/domain/domain.pb.go @@ -0,0 +1,229 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0 +// protoc v3.15.6 +// source: common/matcher/domain/domain.proto + +package domain + +import ( + proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type MatchingType int32 + +const ( + MatchingType_Full MatchingType = 0 + MatchingType_Subdomain MatchingType = 1 + MatchingType_Keyword MatchingType = 2 + MatchingType_Regex MatchingType = 3 +) + +// Enum value maps for MatchingType. +var ( + MatchingType_name = map[int32]string{ + 0: "Full", + 1: "Subdomain", + 2: "Keyword", + 3: "Regex", + } + MatchingType_value = map[string]int32{ + "Full": 0, + "Subdomain": 1, + "Keyword": 2, + "Regex": 3, + } +) + +func (x MatchingType) Enum() *MatchingType { + p := new(MatchingType) + *p = x + return p +} + +func (x MatchingType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (MatchingType) Descriptor() protoreflect.EnumDescriptor { + return file_common_matcher_domain_domain_proto_enumTypes[0].Descriptor() +} + +func (MatchingType) Type() protoreflect.EnumType { + return &file_common_matcher_domain_domain_proto_enumTypes[0] +} + +func (x MatchingType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use MatchingType.Descriptor instead. +func (MatchingType) EnumDescriptor() ([]byte, []int) { + return file_common_matcher_domain_domain_proto_rawDescGZIP(), []int{0} +} + +type Domain struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Domain matching type. + Type MatchingType `protobuf:"varint,1,opt,name=type,proto3,enum=xray.common.matcher.domain.MatchingType" json:"type,omitempty"` + // Domain value. + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *Domain) Reset() { + *x = Domain{} + if protoimpl.UnsafeEnabled { + mi := &file_common_matcher_domain_domain_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Domain) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Domain) ProtoMessage() {} + +func (x *Domain) ProtoReflect() protoreflect.Message { + mi := &file_common_matcher_domain_domain_proto_msgTypes[0] + 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 Domain.ProtoReflect.Descriptor instead. +func (*Domain) Descriptor() ([]byte, []int) { + return file_common_matcher_domain_domain_proto_rawDescGZIP(), []int{0} +} + +func (x *Domain) GetType() MatchingType { + if x != nil { + return x.Type + } + return MatchingType_Full +} + +func (x *Domain) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +var File_common_matcher_domain_domain_proto protoreflect.FileDescriptor + +var file_common_matcher_domain_domain_proto_rawDesc = []byte{ + 0x0a, 0x22, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, + 0x2f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1a, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x22, 0x5c, 0x0a, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3c, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x3f, + 0x0a, 0x0c, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, + 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x77, 0x6f, + 0x72, 0x64, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x10, 0x03, 0x42, + 0x70, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x50, 0x01, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x64, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0xaa, 0x02, 0x1a, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_common_matcher_domain_domain_proto_rawDescOnce sync.Once + file_common_matcher_domain_domain_proto_rawDescData = file_common_matcher_domain_domain_proto_rawDesc +) + +func file_common_matcher_domain_domain_proto_rawDescGZIP() []byte { + file_common_matcher_domain_domain_proto_rawDescOnce.Do(func() { + file_common_matcher_domain_domain_proto_rawDescData = protoimpl.X.CompressGZIP(file_common_matcher_domain_domain_proto_rawDescData) + }) + return file_common_matcher_domain_domain_proto_rawDescData +} + +var file_common_matcher_domain_domain_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_common_matcher_domain_domain_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_common_matcher_domain_domain_proto_goTypes = []interface{}{ + (MatchingType)(0), // 0: xray.common.matcher.domain.MatchingType + (*Domain)(nil), // 1: xray.common.matcher.domain.Domain +} +var file_common_matcher_domain_domain_proto_depIdxs = []int32{ + 0, // 0: xray.common.matcher.domain.Domain.type:type_name -> xray.common.matcher.domain.MatchingType + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_common_matcher_domain_domain_proto_init() } +func file_common_matcher_domain_domain_proto_init() { + if File_common_matcher_domain_domain_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_common_matcher_domain_domain_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Domain); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_common_matcher_domain_domain_proto_rawDesc, + NumEnums: 1, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_common_matcher_domain_domain_proto_goTypes, + DependencyIndexes: file_common_matcher_domain_domain_proto_depIdxs, + EnumInfos: file_common_matcher_domain_domain_proto_enumTypes, + MessageInfos: file_common_matcher_domain_domain_proto_msgTypes, + }.Build() + File_common_matcher_domain_domain_proto = out.File + file_common_matcher_domain_domain_proto_rawDesc = nil + file_common_matcher_domain_domain_proto_goTypes = nil + file_common_matcher_domain_domain_proto_depIdxs = nil +} diff --git a/common/matcher/domain/domain.proto b/common/matcher/domain/domain.proto new file mode 100644 index 000000000000..f028b1edf698 --- /dev/null +++ b/common/matcher/domain/domain.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; + +package xray.common.matcher.domain; +option csharp_namespace = "Xray.Common.Matcher.Domain"; +option go_package = "github.com/xtls/xray-core/common/matcher/domain"; +option java_package = "com.xray.common.matcher.domain"; +option java_multiple_files = true; + +enum MatchingType { + Full = 0; + Subdomain = 1; + Keyword = 2; + Regex = 3; +} + +message Domain { + // Domain matching type. + MatchingType type = 1; + + // Domain value. + string value = 2; +} + +/* +func toDomainMatchingType(t router.Domain_Type) dns.DomainMatchingType { + switch t { + case router.Domain_Domain: + return dns.DomainMatchingType_Subdomain + case router.Domain_Full: + return dns.DomainMatchingType_Full + case router.Domain_Plain: + return dns.DomainMatchingType_Keyword + case router.Domain_Regex: + return dns.DomainMatchingType_Regex + default: + panic("unknown domain type") + } +} + */ \ No newline at end of file diff --git a/common/matcher/domain/errors.generated.go b/common/matcher/domain/errors.generated.go new file mode 100644 index 000000000000..f0676c1fd86f --- /dev/null +++ b/common/matcher/domain/errors.generated.go @@ -0,0 +1,9 @@ +package domain + +import "github.com/xtls/xray-core/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} diff --git a/common/matcher/geoip/conf.go b/common/matcher/geoip/conf.go new file mode 100644 index 000000000000..d5be09cce17f --- /dev/null +++ b/common/matcher/geoip/conf.go @@ -0,0 +1,90 @@ +package geoip + +import ( + "runtime" + + "github.com/golang/protobuf/proto" + "github.com/xtls/xray-core/common/platform/filesystem" +) + +var ( + FileCache = make(map[string][]byte) + IPCache = make(map[string]*GeoIP) +) + +func LoadGeoIP(code string) ([]*CIDR, error) { + return LoadIPFile("geoip.dat", code) +} + +func LoadIPFile(file, code string) ([]*CIDR, error) { + index := file + ":" + code + if IPCache[index] == nil { + bs, err := loadFile(file) + if err != nil { + return nil, newError("failed to load file: ", file).Base(err) + } + bs = find(bs, []byte(code)) + if bs == nil { + return nil, newError("code not found in ", file, ": ", code) + } + var geoipdat GeoIP + if err := proto.Unmarshal(bs, &geoipdat); err != nil { + return nil, newError("error unmarshal IP in ", file, ": ", code).Base(err) + } + defer runtime.GC() // or debug.FreeOSMemory() + return geoipdat.Cidr, nil // do not cache geoip + IPCache[index] = &geoipdat + } + return IPCache[index].Cidr, nil +} + +func loadFile(file string) ([]byte, error) { + if FileCache[file] == nil { + bs, err := filesystem.ReadAsset(file) + if err != nil { + return nil, newError("failed to open file: ", file).Base(err) + } + if len(bs) == 0 { + return nil, newError("empty file: ", file) + } + // Do not cache file, may save RAM when there + // are many files, but consume CPU each time. + return bs, nil + FileCache[file] = bs + } + return FileCache[file], nil +} + +func find(data, code []byte) []byte { + codeL := len(code) + if codeL == 0 { + return nil + } + for { + dataL := len(data) + if dataL < 2 { + return nil + } + x, y := proto.DecodeVarint(data[1:]) + if x == 0 && y == 0 { + return nil + } + headL, bodyL := 1+y, int(x) + dataL -= headL + if dataL < bodyL { + return nil + } + data = data[headL:] + if int(data[1]) == codeL { + for i := 0; i < codeL && data[2+i] == code[i]; i++ { + if i+1 == codeL { + return data[:bodyL] + } + } + } + if dataL == bodyL { + return nil + } + data = data[bodyL:] + } +} diff --git a/common/matcher/geoip/crid.go b/common/matcher/geoip/crid.go new file mode 100644 index 000000000000..3716acd37458 --- /dev/null +++ b/common/matcher/geoip/crid.go @@ -0,0 +1,40 @@ +package geoip + +// CIDRList is an alias of []*CIDR to provide sort.Interface. +type CIDRList []*CIDR + +// Len implements sort.Interface. +func (l *CIDRList) Len() int { + return len(*l) +} + +// Less implements sort.Interface. +func (l *CIDRList) Less(i int, j int) bool { + ci := (*l)[i] + cj := (*l)[j] + + if len(ci.Ip) < len(cj.Ip) { + return true + } + + if len(ci.Ip) > len(cj.Ip) { + return false + } + + for k := 0; k < len(ci.Ip); k++ { + if ci.Ip[k] < cj.Ip[k] { + return true + } + + if ci.Ip[k] > cj.Ip[k] { + return false + } + } + + return ci.Prefix < cj.Prefix +} + +// Swap implements sort.Interface. +func (l *CIDRList) Swap(i int, j int) { + (*l)[i], (*l)[j] = (*l)[j], (*l)[i] +} diff --git a/common/matcher/geoip/errors.generated.go b/common/matcher/geoip/errors.generated.go new file mode 100644 index 000000000000..c75fe73282c0 --- /dev/null +++ b/common/matcher/geoip/errors.generated.go @@ -0,0 +1,9 @@ +package geoip + +import "github.com/xtls/xray-core/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} diff --git a/app/router/condition_geoip.go b/common/matcher/geoip/geoip.go similarity index 96% rename from app/router/condition_geoip.go rename to common/matcher/geoip/geoip.go index 90ad7da7bb8b..08eaf26ac538 100644 --- a/app/router/condition_geoip.go +++ b/common/matcher/geoip/geoip.go @@ -1,4 +1,4 @@ -package router +package geoip import ( "encoding/binary" @@ -7,6 +7,8 @@ import ( "github.com/xtls/xray-core/common/net" ) +//go:generate go run github.com/xtls/xray-core/common/errors/errorgen + type ipv6 struct { a uint64 b uint64 @@ -187,5 +189,5 @@ func (c *GeoIPMatcherContainer) Add(geoip *GeoIP) (*GeoIPMatcher, error) { } var ( - globalGeoIPContainer GeoIPMatcherContainer + GlobalGeoIPContainer GeoIPMatcherContainer ) diff --git a/common/matcher/geoip/geoip.pb.go b/common/matcher/geoip/geoip.pb.go new file mode 100644 index 000000000000..4176127ff102 --- /dev/null +++ b/common/matcher/geoip/geoip.pb.go @@ -0,0 +1,307 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0 +// protoc v3.15.6 +// source: common/matcher/geoip/geoip.proto + +package geoip + +import ( + proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +// IP for routing decision, in CIDR form. +type CIDR struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // IP address, should be either 4 or 16 bytes. + Ip []byte `protobuf:"bytes,1,opt,name=ip,proto3" json:"ip,omitempty"` + // Number of leading ones in the network mask. + Prefix uint32 `protobuf:"varint,2,opt,name=prefix,proto3" json:"prefix,omitempty"` +} + +func (x *CIDR) Reset() { + *x = CIDR{} + if protoimpl.UnsafeEnabled { + mi := &file_common_matcher_geoip_geoip_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CIDR) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CIDR) ProtoMessage() {} + +func (x *CIDR) ProtoReflect() protoreflect.Message { + mi := &file_common_matcher_geoip_geoip_proto_msgTypes[0] + 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 CIDR.ProtoReflect.Descriptor instead. +func (*CIDR) Descriptor() ([]byte, []int) { + return file_common_matcher_geoip_geoip_proto_rawDescGZIP(), []int{0} +} + +func (x *CIDR) GetIp() []byte { + if x != nil { + return x.Ip + } + return nil +} + +func (x *CIDR) GetPrefix() uint32 { + if x != nil { + return x.Prefix + } + return 0 +} + +type GeoIP struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CountryCode string `protobuf:"bytes,1,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"` + Cidr []*CIDR `protobuf:"bytes,2,rep,name=cidr,proto3" json:"cidr,omitempty"` +} + +func (x *GeoIP) Reset() { + *x = GeoIP{} + if protoimpl.UnsafeEnabled { + mi := &file_common_matcher_geoip_geoip_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GeoIP) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GeoIP) ProtoMessage() {} + +func (x *GeoIP) ProtoReflect() protoreflect.Message { + mi := &file_common_matcher_geoip_geoip_proto_msgTypes[1] + 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 GeoIP.ProtoReflect.Descriptor instead. +func (*GeoIP) Descriptor() ([]byte, []int) { + return file_common_matcher_geoip_geoip_proto_rawDescGZIP(), []int{1} +} + +func (x *GeoIP) GetCountryCode() string { + if x != nil { + return x.CountryCode + } + return "" +} + +func (x *GeoIP) GetCidr() []*CIDR { + if x != nil { + return x.Cidr + } + return nil +} + +type GeoIPList struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Entry []*GeoIP `protobuf:"bytes,1,rep,name=entry,proto3" json:"entry,omitempty"` +} + +func (x *GeoIPList) Reset() { + *x = GeoIPList{} + if protoimpl.UnsafeEnabled { + mi := &file_common_matcher_geoip_geoip_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GeoIPList) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GeoIPList) ProtoMessage() {} + +func (x *GeoIPList) ProtoReflect() protoreflect.Message { + mi := &file_common_matcher_geoip_geoip_proto_msgTypes[2] + 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 GeoIPList.ProtoReflect.Descriptor instead. +func (*GeoIPList) Descriptor() ([]byte, []int) { + return file_common_matcher_geoip_geoip_proto_rawDescGZIP(), []int{2} +} + +func (x *GeoIPList) GetEntry() []*GeoIP { + if x != nil { + return x.Entry + } + return nil +} + +var File_common_matcher_geoip_geoip_proto protoreflect.FileDescriptor + +var file_common_matcher_geoip_geoip_proto_rawDesc = []byte{ + 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, + 0x2f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x19, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x22, 0x2e, 0x0a, + 0x04, 0x43, 0x49, 0x44, 0x52, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0x5f, 0x0a, + 0x05, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, + 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x63, 0x69, 0x64, + 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, + 0x6f, 0x69, 0x70, 0x2e, 0x43, 0x49, 0x44, 0x52, 0x52, 0x04, 0x63, 0x69, 0x64, 0x72, 0x22, 0x43, + 0x0a, 0x09, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x05, 0x65, + 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, + 0x2e, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x65, 0x6e, + 0x74, 0x72, 0x79, 0x42, 0x6d, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, + 0x65, 0x6f, 0x69, 0x70, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, + 0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, + 0x2f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0xaa, 0x02, 0x19, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x43, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, + 0x49, 0x50, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_common_matcher_geoip_geoip_proto_rawDescOnce sync.Once + file_common_matcher_geoip_geoip_proto_rawDescData = file_common_matcher_geoip_geoip_proto_rawDesc +) + +func file_common_matcher_geoip_geoip_proto_rawDescGZIP() []byte { + file_common_matcher_geoip_geoip_proto_rawDescOnce.Do(func() { + file_common_matcher_geoip_geoip_proto_rawDescData = protoimpl.X.CompressGZIP(file_common_matcher_geoip_geoip_proto_rawDescData) + }) + return file_common_matcher_geoip_geoip_proto_rawDescData +} + +var file_common_matcher_geoip_geoip_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_common_matcher_geoip_geoip_proto_goTypes = []interface{}{ + (*CIDR)(nil), // 0: xray.common.matcher.geoip.CIDR + (*GeoIP)(nil), // 1: xray.common.matcher.geoip.GeoIP + (*GeoIPList)(nil), // 2: xray.common.matcher.geoip.GeoIPList +} +var file_common_matcher_geoip_geoip_proto_depIdxs = []int32{ + 0, // 0: xray.common.matcher.geoip.GeoIP.cidr:type_name -> xray.common.matcher.geoip.CIDR + 1, // 1: xray.common.matcher.geoip.GeoIPList.entry:type_name -> xray.common.matcher.geoip.GeoIP + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_common_matcher_geoip_geoip_proto_init() } +func file_common_matcher_geoip_geoip_proto_init() { + if File_common_matcher_geoip_geoip_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_common_matcher_geoip_geoip_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CIDR); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_matcher_geoip_geoip_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GeoIP); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_matcher_geoip_geoip_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GeoIPList); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_common_matcher_geoip_geoip_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_common_matcher_geoip_geoip_proto_goTypes, + DependencyIndexes: file_common_matcher_geoip_geoip_proto_depIdxs, + MessageInfos: file_common_matcher_geoip_geoip_proto_msgTypes, + }.Build() + File_common_matcher_geoip_geoip_proto = out.File + file_common_matcher_geoip_geoip_proto_rawDesc = nil + file_common_matcher_geoip_geoip_proto_goTypes = nil + file_common_matcher_geoip_geoip_proto_depIdxs = nil +} diff --git a/common/matcher/geoip/geoip.proto b/common/matcher/geoip/geoip.proto new file mode 100644 index 000000000000..a781ff09504f --- /dev/null +++ b/common/matcher/geoip/geoip.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +package xray.common.matcher.geoip; +option csharp_namespace = "Xray.Common.Matcher.GeoIP"; +option go_package = "github.com/xtls/xray-core/common/matcher/geoip"; +option java_package = "com.xray.common.matcher.geoip"; +option java_multiple_files = true; + +// IP for routing decision, in CIDR form. +message CIDR { + // IP address, should be either 4 or 16 bytes. + bytes ip = 1; + + // Number of leading ones in the network mask. + uint32 prefix = 2; +} + +message GeoIP { + string country_code = 1; + repeated CIDR cidr = 2; +} + +message GeoIPList { + repeated GeoIP entry = 1; +} diff --git a/app/router/condition_geoip_test.go b/common/matcher/geoip/geoip_test.go similarity index 85% rename from app/router/condition_geoip_test.go rename to common/matcher/geoip/geoip_test.go index 596478c664ff..f959b9447809 100644 --- a/app/router/condition_geoip_test.go +++ b/common/matcher/geoip/geoip_test.go @@ -1,4 +1,4 @@ -package router_test +package geoip_test import ( "os" @@ -6,8 +6,8 @@ import ( "testing" "github.com/golang/protobuf/proto" - "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common" + . "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/platform" "github.com/xtls/xray-core/common/platform/filesystem" @@ -18,27 +18,27 @@ func init() { common.Must(err) if _, err := os.Stat(platform.GetAssetLocation("geoip.dat")); err != nil && os.IsNotExist(err) { - common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoip.dat"), filepath.Join(wd, "..", "..", "resources", "geoip.dat"))) + common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoip.dat"), filepath.Join(wd, "..", "..", "..", "resources", "geoip.dat"))) } if _, err := os.Stat(platform.GetAssetLocation("geosite.dat")); err != nil && os.IsNotExist(err) { - common.Must(filesystem.CopyFile(platform.GetAssetLocation("geosite.dat"), filepath.Join(wd, "..", "..", "resources", "geosite.dat"))) + common.Must(filesystem.CopyFile(platform.GetAssetLocation("geosite.dat"), filepath.Join(wd, "..", "..", "..", "resources", "geosite.dat"))) } } func TestGeoIPMatcherContainer(t *testing.T) { - container := &router.GeoIPMatcherContainer{} + container := &GeoIPMatcherContainer{} - m1, err := container.Add(&router.GeoIP{ + m1, err := container.Add(&GeoIP{ CountryCode: "CN", }) common.Must(err) - m2, err := container.Add(&router.GeoIP{ + m2, err := container.Add(&GeoIP{ CountryCode: "US", }) common.Must(err) - m3, err := container.Add(&router.GeoIP{ + m3, err := container.Add(&GeoIP{ CountryCode: "CN", }) common.Must(err) @@ -53,7 +53,7 @@ func TestGeoIPMatcherContainer(t *testing.T) { } func TestGeoIPMatcher(t *testing.T) { - cidrList := router.CIDRList{ + cidrList := CIDRList{ {Ip: []byte{0, 0, 0, 0}, Prefix: 8}, {Ip: []byte{10, 0, 0, 0}, Prefix: 8}, {Ip: []byte{100, 64, 0, 0}, Prefix: 10}, @@ -70,7 +70,7 @@ func TestGeoIPMatcher(t *testing.T) { {Ip: []byte{91, 108, 4, 0}, Prefix: 16}, } - matcher := &router.GeoIPMatcher{} + matcher := &GeoIPMatcher{} common.Must(matcher.Init(cidrList)) testCases := []struct { @@ -127,7 +127,7 @@ func TestGeoIPMatcher4CN(t *testing.T) { ips, err := loadGeoIP("CN") common.Must(err) - matcher := &router.GeoIPMatcher{} + matcher := &GeoIPMatcher{} common.Must(matcher.Init(ips)) if matcher.Match([]byte{8, 8, 8, 8}) { @@ -139,7 +139,7 @@ func TestGeoIPMatcher6US(t *testing.T) { ips, err := loadGeoIP("US") common.Must(err) - matcher := &router.GeoIPMatcher{} + matcher := &GeoIPMatcher{} common.Must(matcher.Init(ips)) if !matcher.Match(net.ParseAddress("2001:4860:4860::8888").IP()) { @@ -147,12 +147,12 @@ func TestGeoIPMatcher6US(t *testing.T) { } } -func loadGeoIP(country string) ([]*router.CIDR, error) { +func loadGeoIP(country string) ([]*CIDR, error) { geoipBytes, err := filesystem.ReadAsset("geoip.dat") if err != nil { return nil, err } - var geoipList router.GeoIPList + var geoipList GeoIPList if err := proto.Unmarshal(geoipBytes, &geoipList); err != nil { return nil, err } @@ -170,7 +170,7 @@ func BenchmarkGeoIPMatcher4CN(b *testing.B) { ips, err := loadGeoIP("CN") common.Must(err) - matcher := &router.GeoIPMatcher{} + matcher := &GeoIPMatcher{} common.Must(matcher.Init(ips)) b.ResetTimer() @@ -184,7 +184,7 @@ func BenchmarkGeoIPMatcher6US(b *testing.B) { ips, err := loadGeoIP("US") common.Must(err) - matcher := &router.GeoIPMatcher{} + matcher := &GeoIPMatcher{} common.Must(matcher.Init(ips)) b.ResetTimer() diff --git a/common/matcher/geoip/matcher.go b/common/matcher/geoip/matcher.go new file mode 100644 index 000000000000..c98ed115493d --- /dev/null +++ b/common/matcher/geoip/matcher.go @@ -0,0 +1,47 @@ +package geoip + +import ( + "github.com/xtls/xray-core/common/net" + "github.com/xtls/xray-core/features/routing" +) + +type MultiGeoIPMatcher struct { + matchers []*GeoIPMatcher + onSource bool +} + +func NewMultiGeoIPMatcher(geoips []*GeoIP, onSource bool) (*MultiGeoIPMatcher, error) { + var matchers []*GeoIPMatcher + for _, geoip := range geoips { + matcher, err := GlobalGeoIPContainer.Add(geoip) + if err != nil { + return nil, err + } + matchers = append(matchers, matcher) + } + + matcher := &MultiGeoIPMatcher{ + matchers: matchers, + onSource: onSource, + } + + return matcher, nil +} + +// Apply implements Condition. +func (m *MultiGeoIPMatcher) Apply(ctx routing.Context) bool { + var ips []net.IP + if m.onSource { + ips = ctx.GetSourceIPs() + } else { + ips = ctx.GetTargetIPs() + } + for _, ip := range ips { + for _, matcher := range m.matchers { + if matcher.Match(ip) { + return true + } + } + } + return false +} diff --git a/common/matcher/geosite/attribute.go b/common/matcher/geosite/attribute.go new file mode 100644 index 000000000000..a16361c169e2 --- /dev/null +++ b/common/matcher/geosite/attribute.go @@ -0,0 +1,33 @@ +package geosite + +type AttributeList struct { + matcher []AttributeMatcher +} + +func (al *AttributeList) Match(domain *Domain) bool { + for _, matcher := range al.matcher { + if !matcher.Match(domain) { + return false + } + } + return true +} + +func (al *AttributeList) IsEmpty() bool { + return len(al.matcher) == 0 +} + +type AttributeMatcher interface { + Match(*Domain) bool +} + +type BooleanMatcher string + +func (m BooleanMatcher) Match(domain *Domain) bool { + for _, attr := range domain.Attribute { + if attr.Key == string(m) { + return true + } + } + return false +} diff --git a/common/matcher/geosite/conf.go b/common/matcher/geosite/conf.go new file mode 100644 index 000000000000..5061b1427752 --- /dev/null +++ b/common/matcher/geosite/conf.go @@ -0,0 +1,42 @@ +package geosite + +import ( + "strings" + + dm "github.com/xtls/xray-core/common/matcher/domain" +) + +func LoadGeositeWithAttr(file string, siteWithAttr string) ([]*dm.Domain, error) { + parts := strings.Split(siteWithAttr, "@") + if len(parts) == 0 { + return nil, newError("empty site") + } + country := strings.ToUpper(parts[0]) + attrs := parseAttrs(parts[1:]) + domains, err := loadSite(file, country) + if err != nil { + return nil, err + } + + if attrs.IsEmpty() { + return ToDomains(domains), nil + } + + filteredDomains := make([]*dm.Domain, 0, len(domains)) + for _, domain := range domains { + if attrs.Match(domain) { + filteredDomains = append(filteredDomains, domain.ToDomain()) + } + } + + return filteredDomains, nil +} + +func parseAttrs(attrs []string) *AttributeList { + al := new(AttributeList) + for _, attr := range attrs { + lc := strings.ToLower(attr) + al.matcher = append(al.matcher, BooleanMatcher(lc)) + } + return al +} diff --git a/common/matcher/geosite/errors.generated.go b/common/matcher/geosite/errors.generated.go new file mode 100644 index 000000000000..c1457eee2ad6 --- /dev/null +++ b/common/matcher/geosite/errors.generated.go @@ -0,0 +1,9 @@ +package geosite + +import "github.com/xtls/xray-core/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} diff --git a/common/matcher/geosite/file.go b/common/matcher/geosite/file.go new file mode 100644 index 000000000000..e9a6ec384e11 --- /dev/null +++ b/common/matcher/geosite/file.go @@ -0,0 +1,86 @@ +package geosite + +import ( + "runtime" + + "github.com/golang/protobuf/proto" + "github.com/xtls/xray-core/common/platform/filesystem" +) + +var ( + SiteCache = make(map[string]*GeoSite) + FileCache = make(map[string][]byte) +) + +func loadFile(file string) ([]byte, error) { + if FileCache[file] == nil { + bs, err := filesystem.ReadAsset(file) + if err != nil { + return nil, newError("failed to open file: ", file).Base(err) + } + if len(bs) == 0 { + return nil, newError("empty file: ", file) + } + // Do not cache file, may save RAM when there + // are many files, but consume CPU each time. + return bs, nil + FileCache[file] = bs + } + return FileCache[file], nil +} + +func loadSite(file, code string) ([]*Domain, error) { + index := file + ":" + code + if SiteCache[index] == nil { + bs, err := loadFile(file) + if err != nil { + return nil, newError("failed to load file: ", file).Base(err) + } + bs = find(bs, []byte(code)) + if bs == nil { + return nil, newError("list not found in ", file, ": ", code) + } + var ges GeoSite + if err := proto.Unmarshal(bs, &ges); err != nil { + return nil, newError("error unmarshal Site in ", file, ": ", code).Base(err) + } + defer runtime.GC() // or debug.FreeOSMemory() + return ges.Domain, nil // do not cache geosite + SiteCache[index] = &ges + } + return SiteCache[index].Domain, nil +} + +func find(data, code []byte) []byte { + codeL := len(code) + if codeL == 0 { + return nil + } + for { + dataL := len(data) + if dataL < 2 { + return nil + } + x, y := proto.DecodeVarint(data[1:]) + if x == 0 && y == 0 { + return nil + } + headL, bodyL := 1+y, int(x) + dataL -= headL + if dataL < bodyL { + return nil + } + data = data[headL:] + if int(data[1]) == codeL { + for i := 0; i < codeL && data[2+i] == code[i]; i++ { + if i+1 == codeL { + return data[:bodyL] + } + } + } + if dataL == bodyL { + return nil + } + data = data[bodyL:] + } +} diff --git a/common/matcher/geosite/geosite.go b/common/matcher/geosite/geosite.go new file mode 100644 index 000000000000..47480e5c89d5 --- /dev/null +++ b/common/matcher/geosite/geosite.go @@ -0,0 +1,19 @@ +package geosite + +import "github.com/xtls/xray-core/common/matcher/domain" + +//go:generate go run github.com/xtls/xray-core/common/errors/errorgen + +func ToDomains(dms []*Domain) []*domain.Domain { + dm := make([]*domain.Domain, len(dms)) + + for idx, entry := range dms { + dm[idx] = entry.ToDomain() + } + + return dm +} + +func (d *Domain) ToDomain() *domain.Domain { + return &domain.Domain{Type: d.Type, Value: d.Value} +} diff --git a/common/matcher/geosite/geosite.pb.go b/common/matcher/geosite/geosite.pb.go new file mode 100644 index 000000000000..d8d166980c81 --- /dev/null +++ b/common/matcher/geosite/geosite.pb.go @@ -0,0 +1,443 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0 +// protoc v3.15.6 +// source: common/matcher/geosite/geosite.proto + +package geosite + +import ( + proto "github.com/golang/protobuf/proto" + domain "github.com/xtls/xray-core/common/matcher/domain" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type Domain struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Domain matching type. + Type domain.MatchingType `protobuf:"varint,1,opt,name=type,proto3,enum=xray.common.matcher.domain.MatchingType" json:"type,omitempty"` + // Domain value. + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + // Attributes of this domain. May be used for filtering. + Attribute []*Domain_Attribute `protobuf:"bytes,3,rep,name=attribute,proto3" json:"attribute,omitempty"` +} + +func (x *Domain) Reset() { + *x = Domain{} + if protoimpl.UnsafeEnabled { + mi := &file_common_matcher_geosite_geosite_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Domain) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Domain) ProtoMessage() {} + +func (x *Domain) ProtoReflect() protoreflect.Message { + mi := &file_common_matcher_geosite_geosite_proto_msgTypes[0] + 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 Domain.ProtoReflect.Descriptor instead. +func (*Domain) Descriptor() ([]byte, []int) { + return file_common_matcher_geosite_geosite_proto_rawDescGZIP(), []int{0} +} + +func (x *Domain) GetType() domain.MatchingType { + if x != nil { + return x.Type + } + return domain.MatchingType_Full +} + +func (x *Domain) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *Domain) GetAttribute() []*Domain_Attribute { + if x != nil { + return x.Attribute + } + return nil +} + +type GeoSite struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CountryCode string `protobuf:"bytes,1,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"` + Domain []*Domain `protobuf:"bytes,2,rep,name=domain,proto3" json:"domain,omitempty"` +} + +func (x *GeoSite) Reset() { + *x = GeoSite{} + if protoimpl.UnsafeEnabled { + mi := &file_common_matcher_geosite_geosite_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GeoSite) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GeoSite) ProtoMessage() {} + +func (x *GeoSite) ProtoReflect() protoreflect.Message { + mi := &file_common_matcher_geosite_geosite_proto_msgTypes[1] + 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 GeoSite.ProtoReflect.Descriptor instead. +func (*GeoSite) Descriptor() ([]byte, []int) { + return file_common_matcher_geosite_geosite_proto_rawDescGZIP(), []int{1} +} + +func (x *GeoSite) GetCountryCode() string { + if x != nil { + return x.CountryCode + } + return "" +} + +func (x *GeoSite) GetDomain() []*Domain { + if x != nil { + return x.Domain + } + return nil +} + +type GeoSiteList struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Entry []*GeoSite `protobuf:"bytes,1,rep,name=entry,proto3" json:"entry,omitempty"` +} + +func (x *GeoSiteList) Reset() { + *x = GeoSiteList{} + if protoimpl.UnsafeEnabled { + mi := &file_common_matcher_geosite_geosite_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GeoSiteList) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GeoSiteList) ProtoMessage() {} + +func (x *GeoSiteList) ProtoReflect() protoreflect.Message { + mi := &file_common_matcher_geosite_geosite_proto_msgTypes[2] + 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 GeoSiteList.ProtoReflect.Descriptor instead. +func (*GeoSiteList) Descriptor() ([]byte, []int) { + return file_common_matcher_geosite_geosite_proto_rawDescGZIP(), []int{2} +} + +func (x *GeoSiteList) GetEntry() []*GeoSite { + if x != nil { + return x.Entry + } + return nil +} + +type Domain_Attribute struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // Types that are assignable to TypedValue: + // *Domain_Attribute_BoolValue + // *Domain_Attribute_IntValue + TypedValue isDomain_Attribute_TypedValue `protobuf_oneof:"typed_value"` +} + +func (x *Domain_Attribute) Reset() { + *x = Domain_Attribute{} + if protoimpl.UnsafeEnabled { + mi := &file_common_matcher_geosite_geosite_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Domain_Attribute) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Domain_Attribute) ProtoMessage() {} + +func (x *Domain_Attribute) ProtoReflect() protoreflect.Message { + mi := &file_common_matcher_geosite_geosite_proto_msgTypes[3] + 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 Domain_Attribute.ProtoReflect.Descriptor instead. +func (*Domain_Attribute) Descriptor() ([]byte, []int) { + return file_common_matcher_geosite_geosite_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *Domain_Attribute) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (m *Domain_Attribute) GetTypedValue() isDomain_Attribute_TypedValue { + if m != nil { + return m.TypedValue + } + return nil +} + +func (x *Domain_Attribute) GetBoolValue() bool { + if x, ok := x.GetTypedValue().(*Domain_Attribute_BoolValue); ok { + return x.BoolValue + } + return false +} + +func (x *Domain_Attribute) GetIntValue() int64 { + if x, ok := x.GetTypedValue().(*Domain_Attribute_IntValue); ok { + return x.IntValue + } + return 0 +} + +type isDomain_Attribute_TypedValue interface { + isDomain_Attribute_TypedValue() +} + +type Domain_Attribute_BoolValue struct { + BoolValue bool `protobuf:"varint,2,opt,name=bool_value,json=boolValue,proto3,oneof"` +} + +type Domain_Attribute_IntValue struct { + IntValue int64 `protobuf:"varint,3,opt,name=int_value,json=intValue,proto3,oneof"` +} + +func (*Domain_Attribute_BoolValue) isDomain_Attribute_TypedValue() {} + +func (*Domain_Attribute_IntValue) isDomain_Attribute_TypedValue() {} + +var File_common_matcher_geosite_geosite_proto protoreflect.FileDescriptor + +var file_common_matcher_geosite_geosite_proto_rawDesc = []byte{ + 0x0a, 0x24, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, + 0x2f, 0x67, 0x65, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x2f, 0x67, 0x65, 0x6f, 0x73, 0x69, 0x74, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x73, + 0x69, 0x74, 0x65, 0x1a, 0x22, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x74, 0x63, + 0x68, 0x65, 0x72, 0x2f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x97, 0x02, 0x0a, 0x06, 0x44, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x12, 0x3c, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x28, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4b, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, + 0x67, 0x65, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x1a, 0x6c, 0x0a, 0x09, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x1d, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x42, 0x0d, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x69, 0x0a, 0x07, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, + 0x3b, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x23, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x2e, 0x44, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x49, 0x0a, 0x0b, + 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x05, 0x65, + 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, + 0x2e, 0x67, 0x65, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x2e, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, + 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x73, 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x78, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, + 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6f, 0x73, 0x69, 0x74, 0x65, 0xaa, 0x02, + 0x1b, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_common_matcher_geosite_geosite_proto_rawDescOnce sync.Once + file_common_matcher_geosite_geosite_proto_rawDescData = file_common_matcher_geosite_geosite_proto_rawDesc +) + +func file_common_matcher_geosite_geosite_proto_rawDescGZIP() []byte { + file_common_matcher_geosite_geosite_proto_rawDescOnce.Do(func() { + file_common_matcher_geosite_geosite_proto_rawDescData = protoimpl.X.CompressGZIP(file_common_matcher_geosite_geosite_proto_rawDescData) + }) + return file_common_matcher_geosite_geosite_proto_rawDescData +} + +var file_common_matcher_geosite_geosite_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_common_matcher_geosite_geosite_proto_goTypes = []interface{}{ + (*Domain)(nil), // 0: xray.common.matcher.geosite.Domain + (*GeoSite)(nil), // 1: xray.common.matcher.geosite.GeoSite + (*GeoSiteList)(nil), // 2: xray.common.matcher.geosite.GeoSiteList + (*Domain_Attribute)(nil), // 3: xray.common.matcher.geosite.Domain.Attribute + (domain.MatchingType)(0), // 4: xray.common.matcher.domain.MatchingType +} +var file_common_matcher_geosite_geosite_proto_depIdxs = []int32{ + 4, // 0: xray.common.matcher.geosite.Domain.type:type_name -> xray.common.matcher.domain.MatchingType + 3, // 1: xray.common.matcher.geosite.Domain.attribute:type_name -> xray.common.matcher.geosite.Domain.Attribute + 0, // 2: xray.common.matcher.geosite.GeoSite.domain:type_name -> xray.common.matcher.geosite.Domain + 1, // 3: xray.common.matcher.geosite.GeoSiteList.entry:type_name -> xray.common.matcher.geosite.GeoSite + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_common_matcher_geosite_geosite_proto_init() } +func file_common_matcher_geosite_geosite_proto_init() { + if File_common_matcher_geosite_geosite_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_common_matcher_geosite_geosite_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Domain); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_matcher_geosite_geosite_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GeoSite); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_matcher_geosite_geosite_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GeoSiteList); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_matcher_geosite_geosite_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Domain_Attribute); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_common_matcher_geosite_geosite_proto_msgTypes[3].OneofWrappers = []interface{}{ + (*Domain_Attribute_BoolValue)(nil), + (*Domain_Attribute_IntValue)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_common_matcher_geosite_geosite_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_common_matcher_geosite_geosite_proto_goTypes, + DependencyIndexes: file_common_matcher_geosite_geosite_proto_depIdxs, + MessageInfos: file_common_matcher_geosite_geosite_proto_msgTypes, + }.Build() + File_common_matcher_geosite_geosite_proto = out.File + file_common_matcher_geosite_geosite_proto_rawDesc = nil + file_common_matcher_geosite_geosite_proto_goTypes = nil + file_common_matcher_geosite_geosite_proto_depIdxs = nil +} diff --git a/common/matcher/geosite/geosite.proto b/common/matcher/geosite/geosite.proto new file mode 100644 index 000000000000..3a5816567b68 --- /dev/null +++ b/common/matcher/geosite/geosite.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; + +package xray.common.matcher.geosite; +option csharp_namespace = "Xray.Common.Matcher.GeoSite"; +option go_package = "github.com/xtls/xray-core/common/matcher/geosite"; +option java_package = "com.xray.common.matcher.geosite"; +option java_multiple_files = true; + +import "common/matcher/domain/domain.proto"; + +message Domain { + // Domain matching type. + xray.common.matcher.domain.MatchingType type = 1; + + // Domain value. + string value = 2; + + message Attribute { + string key = 1; + + oneof typed_value { + bool bool_value = 2; + int64 int_value = 3; + } + } + + // Attributes of this domain. May be used for filtering. + repeated Attribute attribute = 3; +} + +message GeoSite { + string country_code = 1; + repeated Domain domain = 2; +} + +message GeoSiteList { + repeated GeoSite entry = 1; +} \ No newline at end of file diff --git a/common/strmatcher/benchmark_test.go b/common/matcher/str/benchmark_test.go similarity index 91% rename from common/strmatcher/benchmark_test.go rename to common/matcher/str/benchmark_test.go index 3e70ca0421a6..e9432325a3dd 100644 --- a/common/strmatcher/benchmark_test.go +++ b/common/matcher/str/benchmark_test.go @@ -1,11 +1,11 @@ -package strmatcher_test +package str_test import ( "strconv" "testing" "github.com/xtls/xray-core/common" - . "github.com/xtls/xray-core/common/strmatcher" + . "github.com/xtls/xray-core/common/matcher/str" ) func BenchmarkDomainMatcherGroup(b *testing.B) { diff --git a/common/strmatcher/domain_matcher.go b/common/matcher/str/domain_matcher.go similarity index 98% rename from common/strmatcher/domain_matcher.go rename to common/matcher/str/domain_matcher.go index ae8e65bc211e..742d2e980410 100644 --- a/common/strmatcher/domain_matcher.go +++ b/common/matcher/str/domain_matcher.go @@ -1,4 +1,4 @@ -package strmatcher +package str import "strings" diff --git a/common/strmatcher/domain_matcher_test.go b/common/matcher/str/domain_matcher_test.go similarity index 94% rename from common/strmatcher/domain_matcher_test.go rename to common/matcher/str/domain_matcher_test.go index 5a8ca35b2460..6d4d29d71308 100644 --- a/common/strmatcher/domain_matcher_test.go +++ b/common/matcher/str/domain_matcher_test.go @@ -1,10 +1,10 @@ -package strmatcher_test +package str_test import ( "reflect" "testing" - . "github.com/xtls/xray-core/common/strmatcher" + . "github.com/xtls/xray-core/common/matcher/str" ) func TestDomainMatcherGroup(t *testing.T) { diff --git a/common/strmatcher/full_matcher.go b/common/matcher/str/full_matcher.go similarity index 96% rename from common/strmatcher/full_matcher.go rename to common/matcher/str/full_matcher.go index e00d02aa9c7d..578af84b2bb4 100644 --- a/common/strmatcher/full_matcher.go +++ b/common/matcher/str/full_matcher.go @@ -1,4 +1,4 @@ -package strmatcher +package str type FullMatcherGroup struct { matchers map[string][]uint32 diff --git a/common/strmatcher/full_matcher_test.go b/common/matcher/str/full_matcher_test.go similarity index 91% rename from common/strmatcher/full_matcher_test.go rename to common/matcher/str/full_matcher_test.go index 73d60d51f17b..75bb2bd5ad28 100644 --- a/common/strmatcher/full_matcher_test.go +++ b/common/matcher/str/full_matcher_test.go @@ -1,10 +1,10 @@ -package strmatcher_test +package str_test import ( "reflect" "testing" - . "github.com/xtls/xray-core/common/strmatcher" + . "github.com/xtls/xray-core/common/matcher/str" ) func TestFullMatcherGroup(t *testing.T) { diff --git a/common/strmatcher/matchers.go b/common/matcher/str/matchers.go similarity index 97% rename from common/strmatcher/matchers.go rename to common/matcher/str/matchers.go index b5ab09c4cb9f..1d3771fa1c9d 100644 --- a/common/strmatcher/matchers.go +++ b/common/matcher/str/matchers.go @@ -1,4 +1,4 @@ -package strmatcher +package str import ( "regexp" diff --git a/common/strmatcher/matchers_test.go b/common/matcher/str/matchers_test.go similarity index 94% rename from common/strmatcher/matchers_test.go rename to common/matcher/str/matchers_test.go index d39c522c8143..c793fdd3c922 100644 --- a/common/strmatcher/matchers_test.go +++ b/common/matcher/str/matchers_test.go @@ -1,10 +1,10 @@ -package strmatcher_test +package str_test import ( "testing" "github.com/xtls/xray-core/common" - . "github.com/xtls/xray-core/common/strmatcher" + . "github.com/xtls/xray-core/common/matcher/str" ) func TestMatcher(t *testing.T) { diff --git a/common/strmatcher/strmatcher.go b/common/matcher/str/strmatcher.go similarity index 99% rename from common/strmatcher/strmatcher.go rename to common/matcher/str/strmatcher.go index 9728047d5632..bcadec6e4b34 100644 --- a/common/strmatcher/strmatcher.go +++ b/common/matcher/str/strmatcher.go @@ -1,4 +1,4 @@ -package strmatcher +package str import ( "regexp" diff --git a/common/strmatcher/strmatcher_test.go b/common/matcher/str/strmatcher_test.go similarity index 95% rename from common/strmatcher/strmatcher_test.go rename to common/matcher/str/strmatcher_test.go index 87d6c5b34f2e..c3e967301fab 100644 --- a/common/strmatcher/strmatcher_test.go +++ b/common/matcher/str/strmatcher_test.go @@ -1,11 +1,11 @@ -package strmatcher_test +package str_test import ( "reflect" "testing" "github.com/xtls/xray-core/common" - . "github.com/xtls/xray-core/common/strmatcher" + . "github.com/xtls/xray-core/common/matcher/str" ) func TestMatcherGroup(t *testing.T) { diff --git a/infra/conf/dns.go b/infra/conf/dns.go index b1c988251c53..b96230401c07 100644 --- a/infra/conf/dns.go +++ b/infra/conf/dns.go @@ -6,7 +6,9 @@ import ( "strings" "github.com/xtls/xray-core/app/dns" - "github.com/xtls/xray-core/app/router" + "github.com/xtls/xray-core/common/matcher/conf" + dm "github.com/xtls/xray-core/common/matcher/domain" + "github.com/xtls/xray-core/common/matcher/geosite" "github.com/xtls/xray-core/common/net" ) @@ -41,39 +43,24 @@ func (c *NameServerConfig) UnmarshalJSON(data []byte) error { return newError("failed to parse name server: ", string(data)) } -func toDomainMatchingType(t router.Domain_Type) dns.DomainMatchingType { - switch t { - case router.Domain_Domain: - return dns.DomainMatchingType_Subdomain - case router.Domain_Full: - return dns.DomainMatchingType_Full - case router.Domain_Plain: - return dns.DomainMatchingType_Keyword - case router.Domain_Regex: - return dns.DomainMatchingType_Regex - default: - panic("unknown domain type") - } -} - func (c *NameServerConfig) Build() (*dns.NameServer, error) { if c.Address == nil { return nil, newError("NameServer address is not specified.") } - var domains []*dns.NameServer_PriorityDomain + var domains []*dm.Domain var originalRules []*dns.NameServer_OriginalRule for _, rule := range c.Domains { - parsedDomain, err := parseDomainRule(rule) + parsedDomain, err := conf.ParaseDomainRule(rule) if err != nil { return nil, newError("invalid domain rule: ", rule).Base(err) } for _, pd := range parsedDomain { - domains = append(domains, &dns.NameServer_PriorityDomain{ - Type: toDomainMatchingType(pd.Type), - Domain: pd.Value, + domains = append(domains, &dm.Domain{ + Type: pd.Type, + Value: pd.Value, }) } originalRules = append(originalRules, &dns.NameServer_OriginalRule{ @@ -99,13 +86,6 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) { }, nil } -var typeMap = map[router.Domain_Type]dns.DomainMatchingType{ - router.Domain_Full: dns.DomainMatchingType_Full, - router.Domain_Domain: dns.DomainMatchingType_Subdomain, - router.Domain_Plain: dns.DomainMatchingType_Keyword, - router.Domain_Regex: dns.DomainMatchingType_Regex, -} - // DNSConfig is a JSON serializable object for dns.Config. type DNSConfig struct { Servers []*NameServerConfig `json:"servers"` @@ -177,7 +157,7 @@ func (c *DNSConfig) Build() (*dns.Config, error) { return nil, newError("empty domain type of rule: ", domain) } mapping := getHostMapping(addr) - mapping.Type = dns.DomainMatchingType_Subdomain + mapping.Type = dm.MatchingType_Subdomain mapping.Domain = domainName mappings = append(mappings, mapping) @@ -186,13 +166,13 @@ func (c *DNSConfig) Build() (*dns.Config, error) { if len(listName) == 0 { return nil, newError("empty geosite rule: ", domain) } - domains, err := loadGeositeWithAttr("geosite.dat", listName) + domains, err := geosite.LoadGeositeWithAttr("geosite.dat", listName) if err != nil { return nil, newError("failed to load geosite: ", listName).Base(err) } for _, d := range domains { mapping := getHostMapping(addr) - mapping.Type = typeMap[d.Type] + mapping.Type = d.Type mapping.Domain = d.Value mappings = append(mappings, mapping) } @@ -203,7 +183,7 @@ func (c *DNSConfig) Build() (*dns.Config, error) { return nil, newError("empty regexp type of rule: ", domain) } mapping := getHostMapping(addr) - mapping.Type = dns.DomainMatchingType_Regex + mapping.Type = dm.MatchingType_Regex mapping.Domain = regexpVal mappings = append(mappings, mapping) @@ -213,7 +193,7 @@ func (c *DNSConfig) Build() (*dns.Config, error) { return nil, newError("empty keyword type of rule: ", domain) } mapping := getHostMapping(addr) - mapping.Type = dns.DomainMatchingType_Keyword + mapping.Type = dm.MatchingType_Keyword mapping.Domain = keywordVal mappings = append(mappings, mapping) @@ -223,13 +203,13 @@ func (c *DNSConfig) Build() (*dns.Config, error) { return nil, newError("empty full domain type of rule: ", domain) } mapping := getHostMapping(addr) - mapping.Type = dns.DomainMatchingType_Full + mapping.Type = dm.MatchingType_Full mapping.Domain = fullVal mappings = append(mappings, mapping) case strings.HasPrefix(domain, "dotless:"): mapping := getHostMapping(addr) - mapping.Type = dns.DomainMatchingType_Regex + mapping.Type = dm.MatchingType_Regex switch substr := domain[8:]; { case substr == "": mapping.Domain = "^[^.]*$" @@ -247,20 +227,20 @@ func (c *DNSConfig) Build() (*dns.Config, error) { } filename := kv[0] list := kv[1] - domains, err := loadGeositeWithAttr(filename, list) + domains, err := geosite.LoadGeositeWithAttr(filename, list) if err != nil { return nil, newError("failed to load domain list: ", list, " from ", filename).Base(err) } for _, d := range domains { mapping := getHostMapping(addr) - mapping.Type = typeMap[d.Type] + mapping.Type = d.Type mapping.Domain = d.Value mappings = append(mappings, mapping) } default: mapping := getHostMapping(addr) - mapping.Type = dns.DomainMatchingType_Full + mapping.Type = dm.MatchingType_Full mapping.Domain = domain mappings = append(mappings, mapping) } diff --git a/infra/conf/dns_test.go b/infra/conf/dns_test.go index 00284fbbd1f8..cc1779afa9f2 100644 --- a/infra/conf/dns_test.go +++ b/infra/conf/dns_test.go @@ -8,8 +8,9 @@ import ( "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/app/dns" - "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common" + "github.com/xtls/xray-core/common/matcher/domain" + "github.com/xtls/xray-core/common/matcher/geosite" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/platform" "github.com/xtls/xray-core/common/platform/filesystem" @@ -30,12 +31,12 @@ func init() { common.Must(err) defer geositeFile.Close() - list := &router.GeoSiteList{ - Entry: []*router.GeoSite{ + list := &geosite.GeoSiteList{ + Entry: []*geosite.GeoSite{ { CountryCode: "TEST", - Domain: []*router.Domain{ - {Type: router.Domain_Full, Value: "example.com"}, + Domain: []*geosite.Domain{ + {Type: domain.MatchingType_Full, Value: "example.com"}, }, }, }, @@ -94,10 +95,10 @@ func TestDNSConfigParsing(t *testing.T) { Network: net.Network_UDP, Port: 5353, }, - PrioritizedDomain: []*dns.NameServer_PriorityDomain{ + PrioritizedDomain: []*domain.Domain{ { - Type: dns.DomainMatchingType_Subdomain, - Domain: "example.com", + Type: domain.MatchingType_Subdomain, + Value: "example.com", }, }, OriginalRules: []*dns.NameServer_OriginalRule{ @@ -110,27 +111,27 @@ func TestDNSConfigParsing(t *testing.T) { }, StaticHosts: []*dns.Config_HostMapping{ { - Type: dns.DomainMatchingType_Subdomain, + Type: domain.MatchingType_Subdomain, Domain: "example.com", ProxiedDomain: "google.com", }, { - Type: dns.DomainMatchingType_Full, + Type: domain.MatchingType_Full, Domain: "example.com", Ip: [][]byte{{127, 0, 0, 1}}, }, { - Type: dns.DomainMatchingType_Full, + Type: domain.MatchingType_Full, Domain: "example.com", Ip: [][]byte{{10, 0, 0, 1}}, }, { - Type: dns.DomainMatchingType_Keyword, + Type: domain.MatchingType_Keyword, Domain: "google", Ip: [][]byte{{8, 8, 8, 8}}, }, { - Type: dns.DomainMatchingType_Regex, + Type: domain.MatchingType_Regex, Domain: ".*\\.com", Ip: [][]byte{{8, 8, 4, 4}}, }, diff --git a/infra/conf/router.go b/infra/conf/router.go index a93da6b11500..de6246cbf1a9 100644 --- a/infra/conf/router.go +++ b/infra/conf/router.go @@ -2,13 +2,13 @@ package conf import ( "encoding/json" - "runtime" "strconv" "strings" - "github.com/golang/protobuf/proto" - "github.com/xtls/xray-core/app/router" + "github.com/xtls/xray-core/common/matcher/conf" + "github.com/xtls/xray-core/common/matcher/geoip" + "github.com/xtls/xray-core/common/matcher/geosite" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/platform/filesystem" ) @@ -100,7 +100,7 @@ type RouterRule struct { BalancerTag string `json:"balancerTag"` } -func ParseIP(s string) (*router.CIDR, error) { +func ParseIP(s string) (*geoip.CIDR, error) { var addr, mask string i := strings.Index(s, "/") if i < 0 { @@ -123,7 +123,7 @@ func ParseIP(s string) (*router.CIDR, error) { if bits > 32 { return nil, newError("invalid network mask for router: ", bits) } - return &router.CIDR{ + return &geoip.CIDR{ Ip: []byte(ip.IP()), Prefix: bits, }, nil @@ -139,8 +139,8 @@ func ParseIP(s string) (*router.CIDR, error) { if bits > 128 { return nil, newError("invalid network mask for router: ", bits) } - return &router.CIDR{ - Ip: []byte(ip.IP()), + return &geoip.CIDR{ + Ip: ip.IP(), Prefix: bits, }, nil default: @@ -148,14 +148,9 @@ func ParseIP(s string) (*router.CIDR, error) { } } -func loadGeoIP(code string) ([]*router.CIDR, error) { - return loadIP("geoip.dat", code) -} - var ( FileCache = make(map[string][]byte) - IPCache = make(map[string]*router.GeoIP) - SiteCache = make(map[string]*router.GeoSite) + IPCache = make(map[string]*geoip.GeoIP) ) func loadFile(file string) ([]byte, error) { @@ -175,236 +170,21 @@ func loadFile(file string) ([]byte, error) { return FileCache[file], nil } -func loadIP(file, code string) ([]*router.CIDR, error) { - index := file + ":" + code - if IPCache[index] == nil { - bs, err := loadFile(file) - if err != nil { - return nil, newError("failed to load file: ", file).Base(err) - } - bs = find(bs, []byte(code)) - if bs == nil { - return nil, newError("code not found in ", file, ": ", code) - } - var geoip router.GeoIP - if err := proto.Unmarshal(bs, &geoip); err != nil { - return nil, newError("error unmarshal IP in ", file, ": ", code).Base(err) - } - defer runtime.GC() // or debug.FreeOSMemory() - return geoip.Cidr, nil // do not cache geoip - IPCache[index] = &geoip - } - return IPCache[index].Cidr, nil -} - -func loadSite(file, code string) ([]*router.Domain, error) { - index := file + ":" + code - if SiteCache[index] == nil { - bs, err := loadFile(file) - if err != nil { - return nil, newError("failed to load file: ", file).Base(err) - } - bs = find(bs, []byte(code)) - if bs == nil { - return nil, newError("list not found in ", file, ": ", code) - } - var geosite router.GeoSite - if err := proto.Unmarshal(bs, &geosite); err != nil { - return nil, newError("error unmarshal Site in ", file, ": ", code).Base(err) - } - defer runtime.GC() // or debug.FreeOSMemory() - return geosite.Domain, nil // do not cache geosite - SiteCache[index] = &geosite - } - return SiteCache[index].Domain, nil -} - -func find(data, code []byte) []byte { - codeL := len(code) - if codeL == 0 { - return nil - } - for { - dataL := len(data) - if dataL < 2 { - return nil - } - x, y := proto.DecodeVarint(data[1:]) - if x == 0 && y == 0 { - return nil - } - headL, bodyL := 1+y, int(x) - dataL -= headL - if dataL < bodyL { - return nil - } - data = data[headL:] - if int(data[1]) == codeL { - for i := 0; i < codeL && data[2+i] == code[i]; i++ { - if i+1 == codeL { - return data[:bodyL] - } - } - } - if dataL == bodyL { - return nil - } - data = data[bodyL:] - } -} - -type AttributeMatcher interface { - Match(*router.Domain) bool -} - -type BooleanMatcher string - -func (m BooleanMatcher) Match(domain *router.Domain) bool { - for _, attr := range domain.Attribute { - if attr.Key == string(m) { - return true - } - } - return false -} - -type AttributeList struct { - matcher []AttributeMatcher -} - -func (al *AttributeList) Match(domain *router.Domain) bool { - for _, matcher := range al.matcher { - if !matcher.Match(domain) { - return false - } - } - return true -} - -func (al *AttributeList) IsEmpty() bool { - return len(al.matcher) == 0 -} - -func parseAttrs(attrs []string) *AttributeList { - al := new(AttributeList) - for _, attr := range attrs { - lc := strings.ToLower(attr) - al.matcher = append(al.matcher, BooleanMatcher(lc)) - } - return al -} - -func loadGeositeWithAttr(file string, siteWithAttr string) ([]*router.Domain, error) { - parts := strings.Split(siteWithAttr, "@") - if len(parts) == 0 { - return nil, newError("empty site") - } - country := strings.ToUpper(parts[0]) - attrs := parseAttrs(parts[1:]) - domains, err := loadSite(file, country) - if err != nil { - return nil, err - } - - if attrs.IsEmpty() { - return domains, nil - } - - filteredDomains := make([]*router.Domain, 0, len(domains)) - for _, domain := range domains { - if attrs.Match(domain) { - filteredDomains = append(filteredDomains, domain) - } - } - - return filteredDomains, nil -} - -func parseDomainRule(domain string) ([]*router.Domain, error) { - if strings.HasPrefix(domain, "geosite:") { - country := strings.ToUpper(domain[8:]) - domains, err := loadGeositeWithAttr("geosite.dat", country) - if err != nil { - return nil, newError("failed to load geosite: ", country).Base(err) - } - return domains, nil - } - var isExtDatFile = 0 - { - const prefix = "ext:" - if strings.HasPrefix(domain, prefix) { - isExtDatFile = len(prefix) - } - const prefixQualified = "ext-domain:" - if strings.HasPrefix(domain, prefixQualified) { - isExtDatFile = len(prefixQualified) - } - } - if isExtDatFile != 0 { - kv := strings.Split(domain[isExtDatFile:], ":") - if len(kv) != 2 { - return nil, newError("invalid external resource: ", domain) - } - filename := kv[0] - country := kv[1] - domains, err := loadGeositeWithAttr(filename, country) - if err != nil { - return nil, newError("failed to load external sites: ", country, " from ", filename).Base(err) - } - return domains, nil - } - - domainRule := new(router.Domain) - switch { - case strings.HasPrefix(domain, "regexp:"): - domainRule.Type = router.Domain_Regex - domainRule.Value = domain[7:] - - case strings.HasPrefix(domain, "domain:"): - domainRule.Type = router.Domain_Domain - domainRule.Value = domain[7:] - - case strings.HasPrefix(domain, "full:"): - domainRule.Type = router.Domain_Full - domainRule.Value = domain[5:] - - case strings.HasPrefix(domain, "keyword:"): - domainRule.Type = router.Domain_Plain - domainRule.Value = domain[8:] - - case strings.HasPrefix(domain, "dotless:"): - domainRule.Type = router.Domain_Regex - switch substr := domain[8:]; { - case substr == "": - domainRule.Value = "^[^.]*$" - case !strings.Contains(substr, "."): - domainRule.Value = "^[^.]*" + substr + "[^.]*$" - default: - return nil, newError("substr in dotless rule should not contain a dot: ", substr) - } - - default: - domainRule.Type = router.Domain_Plain - domainRule.Value = domain - } - return []*router.Domain{domainRule}, nil -} - -func toCidrList(ips StringList) ([]*router.GeoIP, error) { - var geoipList []*router.GeoIP - var customCidrs []*router.CIDR +func toCidrList(ips StringList) ([]*geoip.GeoIP, error) { + var geoipList []*geoip.GeoIP + var customCidrs []*geoip.CIDR for _, ip := range ips { if strings.HasPrefix(ip, "geoip:") { country := ip[6:] - geoip, err := loadGeoIP(strings.ToUpper(country)) + geoipc, err := geoip.LoadGeoIP(strings.ToUpper(country)) if err != nil { return nil, newError("failed to load GeoIP: ", country).Base(err) } - geoipList = append(geoipList, &router.GeoIP{ + geoipList = append(geoipList, &geoip.GeoIP{ CountryCode: strings.ToUpper(country), - Cidr: geoip, + Cidr: geoipc, }) continue } @@ -427,14 +207,14 @@ func toCidrList(ips StringList) ([]*router.GeoIP, error) { filename := kv[0] country := kv[1] - geoip, err := loadIP(filename, strings.ToUpper(country)) + geoipc, err := geoip.LoadIPFile(filename, strings.ToUpper(country)) if err != nil { return nil, newError("failed to load IPs: ", country, " from ", filename).Base(err) } - geoipList = append(geoipList, &router.GeoIP{ + geoipList = append(geoipList, &geoip.GeoIP{ CountryCode: strings.ToUpper(filename + "_" + country), - Cidr: geoip, + Cidr: geoipc, }) continue @@ -448,7 +228,7 @@ func toCidrList(ips StringList) ([]*router.GeoIP, error) { } if len(customCidrs) > 0 { - geoipList = append(geoipList, &router.GeoIP{ + geoipList = append(geoipList, &geoip.GeoIP{ Cidr: customCidrs, }) } @@ -493,7 +273,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { if rawFieldRule.Domain != nil { for _, domain := range *rawFieldRule.Domain { - rules, err := parseDomainRule(domain) + rules, err := conf.ParaseDomainRule(domain) if err != nil { return nil, newError("failed to parse domain rule: ", domain).Base(err) } @@ -503,7 +283,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { if rawFieldRule.Domains != nil { for _, domain := range *rawFieldRule.Domains { - rules, err := parseDomainRule(domain) + rules, err := conf.ParaseDomainRule(domain) if err != nil { return nil, newError("failed to parse domain rule: ", domain).Base(err) } @@ -600,7 +380,7 @@ func parseChinaIPRule(data []byte) (*router.RoutingRule, error) { if err != nil { return nil, newError("invalid router rule").Base(err) } - chinaIPs, err := loadGeoIP("CN") + chinaIPs, err := geoip.LoadGeoIP("CN") if err != nil { return nil, newError("failed to load geoip:cn").Base(err) } @@ -618,7 +398,7 @@ func parseChinaSitesRule(data []byte) (*router.RoutingRule, error) { if err != nil { return nil, newError("invalid router rule").Base(err).AtError() } - domains, err := loadGeositeWithAttr("geosite.dat", "CN") + domains, err := geosite.LoadGeositeWithAttr("geosite.dat", "CN") if err != nil { return nil, newError("failed to load geosite:cn.").Base(err) } diff --git a/infra/conf/router_test.go b/infra/conf/router_test.go index bb4fdc7d41a6..95a5332dc7cf 100644 --- a/infra/conf/router_test.go +++ b/infra/conf/router_test.go @@ -7,6 +7,8 @@ import ( "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/app/router" + "github.com/xtls/xray-core/common/matcher/domain" + "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/net" . "github.com/xtls/xray-core/infra/conf" ) @@ -73,13 +75,13 @@ func TestRouterConfig(t *testing.T) { }, Rule: []*router.RoutingRule{ { - Domain: []*router.Domain{ + Domain: []*domain.Domain{ { - Type: router.Domain_Plain, + Type: domain.MatchingType_Keyword, Value: "baidu.com", }, { - Type: router.Domain_Plain, + Type: domain.MatchingType_Keyword, Value: "qq.com", }, }, @@ -88,9 +90,9 @@ func TestRouterConfig(t *testing.T) { }, }, { - Geoip: []*router.GeoIP{ + Geoip: []*geoip.GeoIP{ { - Cidr: []*router.CIDR{ + Cidr: []*geoip.CIDR{ { Ip: []byte{10, 0, 0, 0}, Prefix: 8, @@ -161,13 +163,13 @@ func TestRouterConfig(t *testing.T) { DomainStrategy: router.Config_IpIfNonMatch, Rule: []*router.RoutingRule{ { - Domain: []*router.Domain{ + Domain: []*domain.Domain{ { - Type: router.Domain_Plain, + Type: domain.MatchingType_Keyword, Value: "baidu.com", }, { - Type: router.Domain_Plain, + Type: domain.MatchingType_Keyword, Value: "qq.com", }, }, @@ -176,9 +178,9 @@ func TestRouterConfig(t *testing.T) { }, }, { - Geoip: []*router.GeoIP{ + Geoip: []*geoip.GeoIP{ { - Cidr: []*router.CIDR{ + Cidr: []*geoip.CIDR{ { Ip: []byte{10, 0, 0, 0}, Prefix: 8, @@ -224,13 +226,13 @@ func TestRouterConfig(t *testing.T) { DomainStrategy: router.Config_AsIs, Rule: []*router.RoutingRule{ { - Domain: []*router.Domain{ + Domain: []*domain.Domain{ { - Type: router.Domain_Plain, + Type: domain.MatchingType_Keyword, Value: "baidu.com", }, { - Type: router.Domain_Plain, + Type: domain.MatchingType_Keyword, Value: "qq.com", }, }, @@ -239,9 +241,9 @@ func TestRouterConfig(t *testing.T) { }, }, { - Geoip: []*router.GeoIP{ + Geoip: []*geoip.GeoIP{ { - Cidr: []*router.CIDR{ + Cidr: []*geoip.CIDR{ { Ip: []byte{10, 0, 0, 0}, Prefix: 8, diff --git a/infra/conf/xray_test.go b/infra/conf/xray_test.go index d4f0ba6b51fa..96df370ee514 100644 --- a/infra/conf/xray_test.go +++ b/infra/conf/xray_test.go @@ -13,6 +13,7 @@ import ( "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common" clog "github.com/xtls/xray-core/common/log" + "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" @@ -154,9 +155,9 @@ func TestXrayConfig(t *testing.T) { DomainStrategy: router.Config_AsIs, Rule: []*router.RoutingRule{ { - Geoip: []*router.GeoIP{ + Geoip: []*geoip.GeoIP{ { - Cidr: []*router.CIDR{ + Cidr: []*geoip.CIDR{ { Ip: []byte{10, 0, 0, 0}, Prefix: 8, diff --git a/testing/scenarios/dns_test.go b/testing/scenarios/dns_test.go index 886068d769e0..26daa4dcd36b 100644 --- a/testing/scenarios/dns_test.go +++ b/testing/scenarios/dns_test.go @@ -9,6 +9,7 @@ import ( "github.com/xtls/xray-core/app/proxyman" "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common" + "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/core" @@ -39,7 +40,7 @@ func TestResolveIP(t *testing.T) { DomainStrategy: router.Config_IpIfNonMatch, Rule: []*router.RoutingRule{ { - Cidr: []*router.CIDR{ + Cidr: []*geoip.CIDR{ { Ip: []byte{127, 0, 0, 0}, Prefix: 8, diff --git a/testing/scenarios/reverse_test.go b/testing/scenarios/reverse_test.go index cbe9abdf6004..acf061fbfffb 100644 --- a/testing/scenarios/reverse_test.go +++ b/testing/scenarios/reverse_test.go @@ -13,6 +13,7 @@ import ( "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common" clog "github.com/xtls/xray-core/common/log" + "github.com/xtls/xray-core/common/matcher/domain" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" @@ -53,8 +54,8 @@ func TestReverseProxy(t *testing.T) { serial.ToTypedMessage(&router.Config{ Rule: []*router.RoutingRule{ { - Domain: []*router.Domain{ - {Type: router.Domain_Full, Value: "test.example.com"}, + Domain: []*domain.Domain{ + {Type: domain.MatchingType_Full, Value: "test.example.com"}, }, TargetTag: &router.RoutingRule_Tag{ Tag: "portal", @@ -122,8 +123,8 @@ func TestReverseProxy(t *testing.T) { serial.ToTypedMessage(&router.Config{ Rule: []*router.RoutingRule{ { - Domain: []*router.Domain{ - {Type: router.Domain_Full, Value: "test.example.com"}, + Domain: []*domain.Domain{ + {Type: domain.MatchingType_Full, Value: "test.example.com"}, }, TargetTag: &router.RoutingRule_Tag{ Tag: "reverse", @@ -238,8 +239,8 @@ func TestReverseProxyLongRunning(t *testing.T) { serial.ToTypedMessage(&router.Config{ Rule: []*router.RoutingRule{ { - Domain: []*router.Domain{ - {Type: router.Domain_Full, Value: "test.example.com"}, + Domain: []*domain.Domain{ + {Type: domain.MatchingType_Full, Value: "test.example.com"}, }, TargetTag: &router.RoutingRule_Tag{ Tag: "portal", @@ -321,8 +322,8 @@ func TestReverseProxyLongRunning(t *testing.T) { serial.ToTypedMessage(&router.Config{ Rule: []*router.RoutingRule{ { - Domain: []*router.Domain{ - {Type: router.Domain_Full, Value: "test.example.com"}, + Domain: []*domain.Domain{ + {Type: domain.MatchingType_Full, Value: "test.example.com"}, }, TargetTag: &router.RoutingRule_Tag{ Tag: "reverse", From 14189eba071ebc7bb4b502924e495cec13b5f166 Mon Sep 17 00:00:00 2001 From: JimhHan <50871214+JimhHan@users.noreply.github.com> Date: Fri, 26 Mar 2021 15:28:27 +0800 Subject: [PATCH 02/20] Replace: domain conf loader --- common/matcher/{ => domain}/conf/conf.go | 0 common/matcher/{ => domain}/conf/domain.go | 0 common/matcher/{ => domain}/conf/errors.generated.go | 0 infra/conf/dns.go | 2 +- infra/conf/router.go | 2 +- 5 files changed, 2 insertions(+), 2 deletions(-) rename common/matcher/{ => domain}/conf/conf.go (100%) rename common/matcher/{ => domain}/conf/domain.go (100%) rename common/matcher/{ => domain}/conf/errors.generated.go (100%) diff --git a/common/matcher/conf/conf.go b/common/matcher/domain/conf/conf.go similarity index 100% rename from common/matcher/conf/conf.go rename to common/matcher/domain/conf/conf.go diff --git a/common/matcher/conf/domain.go b/common/matcher/domain/conf/domain.go similarity index 100% rename from common/matcher/conf/domain.go rename to common/matcher/domain/conf/domain.go diff --git a/common/matcher/conf/errors.generated.go b/common/matcher/domain/conf/errors.generated.go similarity index 100% rename from common/matcher/conf/errors.generated.go rename to common/matcher/domain/conf/errors.generated.go diff --git a/infra/conf/dns.go b/infra/conf/dns.go index b96230401c07..ce7bc24ea97e 100644 --- a/infra/conf/dns.go +++ b/infra/conf/dns.go @@ -6,8 +6,8 @@ import ( "strings" "github.com/xtls/xray-core/app/dns" - "github.com/xtls/xray-core/common/matcher/conf" dm "github.com/xtls/xray-core/common/matcher/domain" + "github.com/xtls/xray-core/common/matcher/domain/conf" "github.com/xtls/xray-core/common/matcher/geosite" "github.com/xtls/xray-core/common/net" ) diff --git a/infra/conf/router.go b/infra/conf/router.go index de6246cbf1a9..128096ab67e6 100644 --- a/infra/conf/router.go +++ b/infra/conf/router.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/xtls/xray-core/app/router" - "github.com/xtls/xray-core/common/matcher/conf" + "github.com/xtls/xray-core/common/matcher/domain/conf" "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/matcher/geosite" "github.com/xtls/xray-core/common/net" From 06fc82bad13315d8b16bea7ed91d739042afb14c Mon Sep 17 00:00:00 2001 From: JimhHan <50871214+JimhHan@users.noreply.github.com> Date: Fri, 26 Mar 2021 16:56:43 +0800 Subject: [PATCH 03/20] Feat: sniffer exclude domain & ip --- app/dispatcher/default.go | 20 +- app/proxyman/config.go | 32 +++ app/proxyman/config.pb.go | 323 +++++++++++++------------ app/proxyman/config.proto | 6 +- app/proxyman/errors.generated.go | 9 + app/proxyman/inbound/always.go | 18 +- app/proxyman/inbound/worker.go | 8 +- app/router/condition.go | 55 ----- app/router/config.go | 3 +- common/matcher/domain/conf/domain.go | 2 +- common/matcher/domain/matcher.go | 60 +++++ common/matcher/geoip/conf.go | 120 ++++++++- common/matcher/geoip/matcher.go | 10 + common/session/session.go | 5 +- infra/conf/{ => common}/common.go | 4 +- infra/conf/{ => common}/common_test.go | 4 +- infra/conf/common/errors.generated.go | 9 + infra/conf/dns.go | 34 +-- infra/conf/dns_proxy.go | 7 +- infra/conf/dokodemo.go | 13 +- infra/conf/http.go | 3 +- infra/conf/router.go | 124 ++-------- infra/conf/shadowsocks.go | 15 +- infra/conf/socks.go | 5 +- infra/conf/transport_authenticators.go | 19 +- infra/conf/transport_internet.go | 45 ++-- infra/conf/trojan.go | 13 +- infra/conf/vless.go | 3 +- infra/conf/vmess.go | 3 +- infra/conf/xray.go | 45 +++- infra/conf/xray_test.go | 47 ++++ 31 files changed, 653 insertions(+), 411 deletions(-) create mode 100644 app/proxyman/errors.generated.go create mode 100644 common/matcher/domain/matcher.go rename infra/conf/{ => common}/common.go (98%) rename infra/conf/{ => common}/common_test.go (98%) create mode 100644 infra/conf/common/errors.generated.go diff --git a/app/dispatcher/default.go b/app/dispatcher/default.go index 1c0ba79cb03e..97322ab2d586 100644 --- a/app/dispatcher/default.go +++ b/app/dispatcher/default.go @@ -178,8 +178,8 @@ func (d *DefaultDispatcher) getLink(ctx context.Context) (*transport.Link, *tran func shouldOverride(ctx context.Context, result SniffResult, request session.SniffingRequest, destination net.Destination) bool { domain := result.Domain() - for _, d := range request.ExcludeForDomain { - if domain == d { + if request.ExcludedDomainMatcher != nil { + if request.ExcludedDomainMatcher.ApplyDomain(domain) { return false } } @@ -205,6 +205,16 @@ func shouldOverride(ctx context.Context, result SniffResult, request session.Sni return false } +func canSniff(ctx context.Context, req session.SniffingRequest, destination net.Destination) bool { + if destination.Address.Family().IsIP() && req.ExcludedIPMatcher != nil { + if req.ExcludedIPMatcher.MatchIP(destination.Address.IP()) { + return false + } + } + + return true +} + // Dispatch implements routing.Dispatcher. func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destination) (*transport.Link, error) { if !destination.IsValid() { @@ -222,6 +232,12 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin ctx = session.ContextWithContent(ctx, content) } sniffingRequest := content.SniffingRequest + + if !canSniff(ctx, sniffingRequest, destination) { + newError("skip sniffing for ip ", destination.Address.String()).AtDebug().WriteToLog() + sniffingRequest.Enabled = false + } + switch { case !sniffingRequest.Enabled: go d.routedDispatch(ctx, outbound, destination) diff --git a/app/proxyman/config.go b/app/proxyman/config.go index 73c00c74a14e..302d208f61de 100644 --- a/app/proxyman/config.go +++ b/app/proxyman/config.go @@ -1,5 +1,12 @@ package proxyman +import ( + "github.com/xtls/xray-core/common/matcher/domain" + "github.com/xtls/xray-core/common/matcher/geoip" +) + +//go:generate go run github.com/xtls/xray-core/common/errors/errorgen + func (s *AllocationStrategy) GetConcurrencyValue() uint32 { if s == nil || s.Concurrency == nil { return 3 @@ -37,3 +44,28 @@ func (c *ReceiverConfig) GetEffectiveSniffingSettings() *SniffingConfig { return nil } + +type SniffingMatcher struct { + ExDomain *domain.DomainMatcher + ExIP *geoip.MultiGeoIPMatcher +} + +func NewSniffingMatcher(sc *SniffingConfig) (*SniffingMatcher, error) { + m := new(SniffingMatcher) + + if sc.DomainsExcluded != nil { + exDomain, err := domain.NewDomainMatcher(sc.DomainsExcluded) + if err != nil { + return nil, newError("failed to parse domain").Base(err) + } + m.ExDomain = exDomain + } + if sc.IpsExcluded != nil { + exIP, err := geoip.NewMultiGeoIPMatcher(sc.IpsExcluded, true) + if err != nil { + return nil, newError("failed to parse ip").Base(err) + } + m.ExIP = exIP + } + return m, nil +} diff --git a/app/proxyman/config.pb.go b/app/proxyman/config.pb.go index 4e42cfd56c4a..d8c82e65b11b 100644 --- a/app/proxyman/config.pb.go +++ b/app/proxyman/config.pb.go @@ -1,13 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 -// protoc (unknown) +// protoc v3.15.6 // source: app/proxyman/config.proto package proxyman import ( proto "github.com/golang/protobuf/proto" + domain "github.com/xtls/xray-core/common/matcher/domain" + geoip "github.com/xtls/xray-core/common/matcher/geoip" net "github.com/xtls/xray-core/common/net" serial "github.com/xtls/xray-core/common/serial" internet "github.com/xtls/xray-core/transport/internet" @@ -240,8 +242,9 @@ type SniffingConfig struct { Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` // Override target destination if sniff'ed protocol is in the given list. // Supported values are "http", "tls", "fakedns". - DestinationOverride []string `protobuf:"bytes,2,rep,name=destination_override,json=destinationOverride,proto3" json:"destination_override,omitempty"` - DomainsExcluded []string `protobuf:"bytes,3,rep,name=domains_excluded,json=domainsExcluded,proto3" json:"domains_excluded,omitempty"` + DestinationOverride []string `protobuf:"bytes,2,rep,name=destination_override,json=destinationOverride,proto3" json:"destination_override,omitempty"` + DomainsExcluded []*domain.Domain `protobuf:"bytes,3,rep,name=domains_excluded,json=domainsExcluded,proto3" json:"domains_excluded,omitempty"` + IpsExcluded []*geoip.GeoIP `protobuf:"bytes,5,rep,name=ips_excluded,json=ipsExcluded,proto3" json:"ips_excluded,omitempty"` // Whether should only try to sniff metadata without waiting for client input. // Can be used to support SMTP like protocol where server send the first message. MetadataOnly bool `protobuf:"varint,4,opt,name=metadata_only,json=metadataOnly,proto3" json:"metadata_only,omitempty"` @@ -293,13 +296,20 @@ func (x *SniffingConfig) GetDestinationOverride() []string { return nil } -func (x *SniffingConfig) GetDomainsExcluded() []string { +func (x *SniffingConfig) GetDomainsExcluded() []*domain.Domain { if x != nil { return x.DomainsExcluded } return nil } +func (x *SniffingConfig) GetIpsExcluded() []*geoip.GeoIP { + if x != nil { + return x.IpsExcluded + } + return nil +} + func (x *SniffingConfig) GetMetadataOnly() bool { if x != nil { return x.MetadataOnly @@ -738,133 +748,144 @@ var File_app_proxyman_config_proto protoreflect.FileDescriptor var file_app_proxyman_config_proto_rawDesc = []byte{ 0x0a, 0x19, 0x61, 0x70, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x78, 0x72, 0x61, - 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x1a, 0x18, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x1f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x65, 0x74, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2f, - 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0x0f, 0x0a, 0x0d, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x22, 0xae, 0x03, 0x0a, 0x12, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x3e, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x1a, 0x22, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, + 0x2f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, + 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x73, + 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x0f, 0x0a, 0x0d, 0x49, 0x6e, 0x62, + 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xae, 0x03, 0x0a, 0x12, 0x41, + 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, + 0x79, 0x12, 0x3e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x2a, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, + 0x6d, 0x61, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, + 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x65, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, + 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x2e, 0x41, 0x6c, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, + 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x0b, 0x63, 0x6f, 0x6e, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x59, 0x0a, 0x07, 0x72, 0x65, 0x66, 0x72, + 0x65, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, - 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x65, 0x0a, 0x0b, 0x63, - 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x43, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, - 0x72, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, - 0x63, 0x79, 0x12, 0x59, 0x0a, 0x07, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x65, 0x66, - 0x72, 0x65, 0x73, 0x68, 0x52, 0x07, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x1a, 0x35, 0x0a, - 0x1d, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, - 0x65, 0x67, 0x79, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x31, 0x0a, 0x19, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, - 0x68, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x2c, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x0a, 0x0a, 0x06, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x52, - 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x45, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x10, 0x02, 0x22, 0xad, 0x01, 0x0a, 0x0e, 0x53, 0x6e, 0x69, 0x66, 0x66, 0x69, - 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x12, 0x31, 0x0a, 0x14, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x13, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x76, 0x65, - 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, - 0x5f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, - 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6f, 0x6e, 0x6c, - 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x90, 0x04, 0x0a, 0x0e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, - 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x39, 0x0a, 0x0a, 0x70, 0x6f, 0x72, 0x74, - 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x78, - 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, - 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x61, - 0x6e, 0x67, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, - 0x52, 0x06, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x12, 0x56, 0x0a, 0x13, 0x61, 0x6c, 0x6c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, - 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x12, 0x61, 0x6c, + 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, + 0x65, 0x67, 0x79, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x07, 0x72, 0x65, 0x66, 0x72, + 0x65, 0x73, 0x68, 0x1a, 0x35, 0x0a, 0x1d, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x63, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x31, 0x0a, 0x19, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, - 0x12, 0x4e, 0x0a, 0x0f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, - 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x52, 0x0e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, - 0x12, 0x40, 0x0a, 0x1c, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x72, 0x69, 0x67, - 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x4f, - 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x4e, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x6f, 0x76, 0x65, - 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, - 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x42, 0x02, - 0x18, 0x01, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, - 0x64, 0x65, 0x12, 0x4e, 0x0a, 0x11, 0x73, 0x6e, 0x69, 0x66, 0x66, 0x69, 0x6e, 0x67, 0x5f, 0x73, - 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, - 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, - 0x6e, 0x2e, 0x53, 0x6e, 0x69, 0x66, 0x66, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x52, 0x10, 0x73, 0x6e, 0x69, 0x66, 0x66, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, - 0x67, 0x73, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x22, 0xc0, 0x01, 0x0a, 0x14, 0x49, 0x6e, 0x62, - 0x6f, 0x75, 0x6e, 0x64, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x74, 0x61, 0x67, 0x12, 0x4d, 0x0a, 0x11, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x5f, - 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, - 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, - 0x69, 0x61, 0x6c, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x10, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, - 0x67, 0x73, 0x12, 0x47, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, - 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, - 0x54, 0x79, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0d, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x10, 0x0a, 0x0e, 0x4f, - 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xb0, 0x02, - 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2d, - 0x0a, 0x03, 0x76, 0x69, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, - 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x03, 0x76, 0x69, 0x61, 0x12, 0x4e, 0x0a, - 0x0f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, - 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, - 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x4b, 0x0a, - 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, - 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x54, 0x0a, 0x12, 0x6d, 0x75, - 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, - 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, - 0x70, 0x6c, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x6d, - 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, - 0x22, 0x50, 0x0a, 0x12, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x6e, 0x67, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, - 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, - 0x63, 0x79, 0x2a, 0x23, 0x0a, 0x0e, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x73, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x00, 0x12, 0x07, - 0x0a, 0x03, 0x54, 0x4c, 0x53, 0x10, 0x01, 0x42, 0x55, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x78, + 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x2c, 0x0a, + 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x10, + 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x10, 0x01, 0x12, 0x0c, 0x0a, + 0x08, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x10, 0x02, 0x22, 0x96, 0x02, 0x0a, 0x0e, + 0x53, 0x6e, 0x69, 0x66, 0x66, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, + 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x31, 0x0a, 0x14, 0x64, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x4d, 0x0a, 0x10, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x5f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x73, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x0c, 0x69, 0x70, + 0x73, 0x5f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2e, 0x47, 0x65, 0x6f, + 0x49, 0x50, 0x52, 0x0b, 0x69, 0x70, 0x73, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x12, + 0x23, 0x0a, 0x0d, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x90, 0x04, 0x0a, 0x0e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x39, 0x0a, 0x0a, 0x70, 0x6f, 0x72, 0x74, 0x5f, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x78, 0x72, + 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x6f, + 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, + 0x67, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, + 0x06, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x12, 0x56, 0x0a, 0x13, 0x61, 0x6c, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x12, 0x61, 0x6c, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, + 0x4e, 0x0a, 0x0f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, + 0x0e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, + 0x40, 0x0a, 0x1c, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x72, 0x69, 0x67, 0x69, + 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x4f, 0x72, + 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x4e, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x6f, 0x76, 0x65, 0x72, + 0x72, 0x69, 0x64, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x78, 0x72, 0x61, + 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x4b, + 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x42, 0x02, 0x18, + 0x01, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, + 0x65, 0x12, 0x4e, 0x0a, 0x11, 0x73, 0x6e, 0x69, 0x66, 0x66, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, - 0x50, 0x01, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, - 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, - 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0xaa, 0x02, 0x11, 0x58, 0x72, 0x61, - 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x53, 0x6e, 0x69, 0x66, 0x66, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, + 0x10, 0x73, 0x6e, 0x69, 0x66, 0x66, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x22, 0xc0, 0x01, 0x0a, 0x14, 0x49, 0x6e, 0x62, 0x6f, + 0x75, 0x6e, 0x64, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, + 0x61, 0x67, 0x12, 0x4d, 0x0a, 0x11, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x73, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, + 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, 0x69, + 0x61, 0x6c, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x10, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x12, 0x47, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, + 0x6e, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x54, + 0x79, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0d, 0x70, 0x72, 0x6f, + 0x78, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x10, 0x0a, 0x0e, 0x4f, 0x75, + 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xb0, 0x02, 0x0a, + 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2d, 0x0a, + 0x03, 0x76, 0x69, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, + 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x03, 0x76, 0x69, 0x61, 0x12, 0x4e, 0x0a, 0x0f, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x4b, 0x0a, 0x0e, + 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x50, + 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, + 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x54, 0x0a, 0x12, 0x6d, 0x75, 0x6c, + 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, + 0x6c, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x6d, 0x75, + 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, + 0x50, 0x0a, 0x12, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, + 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, + 0x79, 0x2a, 0x23, 0x0a, 0x0e, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x73, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, + 0x03, 0x54, 0x4c, 0x53, 0x10, 0x01, 0x42, 0x55, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, + 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x50, + 0x01, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, + 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, + 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0xaa, 0x02, 0x11, 0x58, 0x72, 0x61, 0x79, + 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -894,33 +915,37 @@ var file_app_proxyman_config_proto_goTypes = []interface{}{ (*MultiplexingConfig)(nil), // 9: xray.app.proxyman.MultiplexingConfig (*AllocationStrategy_AllocationStrategyConcurrency)(nil), // 10: xray.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency (*AllocationStrategy_AllocationStrategyRefresh)(nil), // 11: xray.app.proxyman.AllocationStrategy.AllocationStrategyRefresh - (*net.PortRange)(nil), // 12: xray.common.net.PortRange - (*net.IPOrDomain)(nil), // 13: xray.common.net.IPOrDomain - (*internet.StreamConfig)(nil), // 14: xray.transport.internet.StreamConfig - (*serial.TypedMessage)(nil), // 15: xray.common.serial.TypedMessage - (*internet.ProxyConfig)(nil), // 16: xray.transport.internet.ProxyConfig + (*domain.Domain)(nil), // 12: xray.common.matcher.domain.Domain + (*geoip.GeoIP)(nil), // 13: xray.common.matcher.geoip.GeoIP + (*net.PortRange)(nil), // 14: xray.common.net.PortRange + (*net.IPOrDomain)(nil), // 15: xray.common.net.IPOrDomain + (*internet.StreamConfig)(nil), // 16: xray.transport.internet.StreamConfig + (*serial.TypedMessage)(nil), // 17: xray.common.serial.TypedMessage + (*internet.ProxyConfig)(nil), // 18: xray.transport.internet.ProxyConfig } var file_app_proxyman_config_proto_depIdxs = []int32{ 1, // 0: xray.app.proxyman.AllocationStrategy.type:type_name -> xray.app.proxyman.AllocationStrategy.Type 10, // 1: xray.app.proxyman.AllocationStrategy.concurrency:type_name -> xray.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency 11, // 2: xray.app.proxyman.AllocationStrategy.refresh:type_name -> xray.app.proxyman.AllocationStrategy.AllocationStrategyRefresh - 12, // 3: xray.app.proxyman.ReceiverConfig.port_range:type_name -> xray.common.net.PortRange - 13, // 4: xray.app.proxyman.ReceiverConfig.listen:type_name -> xray.common.net.IPOrDomain - 3, // 5: xray.app.proxyman.ReceiverConfig.allocation_strategy:type_name -> xray.app.proxyman.AllocationStrategy - 14, // 6: xray.app.proxyman.ReceiverConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig - 0, // 7: xray.app.proxyman.ReceiverConfig.domain_override:type_name -> xray.app.proxyman.KnownProtocols - 4, // 8: xray.app.proxyman.ReceiverConfig.sniffing_settings:type_name -> xray.app.proxyman.SniffingConfig - 15, // 9: xray.app.proxyman.InboundHandlerConfig.receiver_settings:type_name -> xray.common.serial.TypedMessage - 15, // 10: xray.app.proxyman.InboundHandlerConfig.proxy_settings:type_name -> xray.common.serial.TypedMessage - 13, // 11: xray.app.proxyman.SenderConfig.via:type_name -> xray.common.net.IPOrDomain - 14, // 12: xray.app.proxyman.SenderConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig - 16, // 13: xray.app.proxyman.SenderConfig.proxy_settings:type_name -> xray.transport.internet.ProxyConfig - 9, // 14: xray.app.proxyman.SenderConfig.multiplex_settings:type_name -> xray.app.proxyman.MultiplexingConfig - 15, // [15:15] is the sub-list for method output_type - 15, // [15:15] is the sub-list for method input_type - 15, // [15:15] is the sub-list for extension type_name - 15, // [15:15] is the sub-list for extension extendee - 0, // [0:15] is the sub-list for field type_name + 12, // 3: xray.app.proxyman.SniffingConfig.domains_excluded:type_name -> xray.common.matcher.domain.Domain + 13, // 4: xray.app.proxyman.SniffingConfig.ips_excluded:type_name -> xray.common.matcher.geoip.GeoIP + 14, // 5: xray.app.proxyman.ReceiverConfig.port_range:type_name -> xray.common.net.PortRange + 15, // 6: xray.app.proxyman.ReceiverConfig.listen:type_name -> xray.common.net.IPOrDomain + 3, // 7: xray.app.proxyman.ReceiverConfig.allocation_strategy:type_name -> xray.app.proxyman.AllocationStrategy + 16, // 8: xray.app.proxyman.ReceiverConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig + 0, // 9: xray.app.proxyman.ReceiverConfig.domain_override:type_name -> xray.app.proxyman.KnownProtocols + 4, // 10: xray.app.proxyman.ReceiverConfig.sniffing_settings:type_name -> xray.app.proxyman.SniffingConfig + 17, // 11: xray.app.proxyman.InboundHandlerConfig.receiver_settings:type_name -> xray.common.serial.TypedMessage + 17, // 12: xray.app.proxyman.InboundHandlerConfig.proxy_settings:type_name -> xray.common.serial.TypedMessage + 15, // 13: xray.app.proxyman.SenderConfig.via:type_name -> xray.common.net.IPOrDomain + 16, // 14: xray.app.proxyman.SenderConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig + 18, // 15: xray.app.proxyman.SenderConfig.proxy_settings:type_name -> xray.transport.internet.ProxyConfig + 9, // 16: xray.app.proxyman.SenderConfig.multiplex_settings:type_name -> xray.app.proxyman.MultiplexingConfig + 17, // [17:17] is the sub-list for method output_type + 17, // [17:17] is the sub-list for method input_type + 17, // [17:17] is the sub-list for extension type_name + 17, // [17:17] is the sub-list for extension extendee + 0, // [0:17] is the sub-list for field type_name } func init() { file_app_proxyman_config_proto_init() } diff --git a/app/proxyman/config.proto b/app/proxyman/config.proto index 83d5ad5e47ca..69fa4f15f0a7 100644 --- a/app/proxyman/config.proto +++ b/app/proxyman/config.proto @@ -6,6 +6,8 @@ option go_package = "github.com/xtls/xray-core/app/proxyman"; option java_package = "com.xray.app.proxyman"; option java_multiple_files = true; +import "common/matcher/domain/domain.proto"; +import "common/matcher/geoip/geoip.proto"; import "common/net/address.proto"; import "common/net/port.proto"; import "transport/internet/config.proto"; @@ -56,7 +58,9 @@ message SniffingConfig { // Override target destination if sniff'ed protocol is in the given list. // Supported values are "http", "tls", "fakedns". repeated string destination_override = 2; - repeated string domains_excluded = 3; + + repeated xray.common.matcher.domain.Domain domains_excluded = 3; + repeated xray.common.matcher.geoip.GeoIP ips_excluded = 5; // Whether should only try to sniff metadata without waiting for client input. // Can be used to support SMTP like protocol where server send the first message. diff --git a/app/proxyman/errors.generated.go b/app/proxyman/errors.generated.go new file mode 100644 index 000000000000..56dc500fb90f --- /dev/null +++ b/app/proxyman/errors.generated.go @@ -0,0 +1,9 @@ +package proxyman + +import "github.com/xtls/xray-core/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} diff --git a/app/proxyman/inbound/always.go b/app/proxyman/inbound/always.go index a29e7d320b97..8918ba515db9 100644 --- a/app/proxyman/inbound/always.go +++ b/app/proxyman/inbound/always.go @@ -91,13 +91,20 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig * if net.HasNetwork(nl, net.Network_UNIX) { newError("creating unix domain socket worker on ", address).AtDebug().WriteToLog() + sc := receiverConfig.GetEffectiveSniffingSettings() + sm, err := proxyman.NewSniffingMatcher(sc) + if err != nil { + return nil, err + } + worker := &dsWorker{ address: address, proxy: p, stream: mss, tag: tag, dispatcher: h.mux, - sniffingConfig: receiverConfig.GetEffectiveSniffingSettings(), + sniffingConfig: sc, + sniffingMatcher: sm, uplinkCounter: uplinkCounter, downlinkCounter: downlinkCounter, ctx: ctx, @@ -110,6 +117,12 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig * if net.HasNetwork(nl, net.Network_TCP) { newError("creating stream worker on ", address, ":", port).AtDebug().WriteToLog() + sc := receiverConfig.GetEffectiveSniffingSettings() + sm, err := proxyman.NewSniffingMatcher(sc) + if err != nil { + return nil, err + } + worker := &tcpWorker{ address: address, port: net.Port(port), @@ -118,7 +131,8 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig * recvOrigDest: receiverConfig.ReceiveOriginalDestination, tag: tag, dispatcher: h.mux, - sniffingConfig: receiverConfig.GetEffectiveSniffingSettings(), + sniffingConfig: sc, + sniffingMatcher: sm, uplinkCounter: uplinkCounter, downlinkCounter: downlinkCounter, ctx: ctx, diff --git a/app/proxyman/inbound/worker.go b/app/proxyman/inbound/worker.go index 04094a4b00e2..7735c1330b59 100644 --- a/app/proxyman/inbound/worker.go +++ b/app/proxyman/inbound/worker.go @@ -39,6 +39,7 @@ type tcpWorker struct { tag string dispatcher routing.Dispatcher sniffingConfig *proxyman.SniffingConfig + sniffingMatcher *proxyman.SniffingMatcher uplinkCounter stats.Counter downlinkCounter stats.Counter @@ -97,7 +98,8 @@ func (w *tcpWorker) callback(conn internet.Connection) { if w.sniffingConfig != nil { content.SniffingRequest.Enabled = w.sniffingConfig.Enabled content.SniffingRequest.OverrideDestinationForProtocol = w.sniffingConfig.DestinationOverride - content.SniffingRequest.ExcludeForDomain = w.sniffingConfig.DomainsExcluded + content.SniffingRequest.ExcludedDomainMatcher = w.sniffingMatcher.ExDomain + content.SniffingRequest.ExcludedIPMatcher = w.sniffingMatcher.ExIP content.SniffingRequest.MetadataOnly = w.sniffingConfig.MetadataOnly } ctx = session.ContextWithContent(ctx, content) @@ -428,6 +430,7 @@ type dsWorker struct { tag string dispatcher routing.Dispatcher sniffingConfig *proxyman.SniffingConfig + sniffingMatcher *proxyman.SniffingMatcher uplinkCounter stats.Counter downlinkCounter stats.Counter @@ -459,7 +462,8 @@ func (w *dsWorker) callback(conn internet.Connection) { if w.sniffingConfig != nil { content.SniffingRequest.Enabled = w.sniffingConfig.Enabled content.SniffingRequest.OverrideDestinationForProtocol = w.sniffingConfig.DestinationOverride - content.SniffingRequest.ExcludeForDomain = w.sniffingConfig.DomainsExcluded + content.SniffingRequest.ExcludedDomainMatcher = w.sniffingMatcher.ExDomain + content.SniffingRequest.ExcludedIPMatcher = w.sniffingMatcher.ExIP content.SniffingRequest.MetadataOnly = w.sniffingConfig.MetadataOnly } ctx = session.ContextWithContent(ctx, content) diff --git a/app/router/condition.go b/app/router/condition.go index c6e344f10247..8236e8a76c94 100644 --- a/app/router/condition.go +++ b/app/router/condition.go @@ -6,8 +6,6 @@ import ( "go.starlark.net/starlark" "go.starlark.net/syntax" - dm "github.com/xtls/xray-core/common/matcher/domain" - "github.com/xtls/xray-core/common/matcher/str" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/features/routing" ) @@ -42,59 +40,6 @@ func (v *ConditionChan) Len() int { return len(*v) } -var matcherTypeMap = map[dm.MatchingType]str.Type{ - dm.MatchingType_Keyword: str.Substr, - dm.MatchingType_Regex: str.Regex, - dm.MatchingType_Subdomain: str.Domain, - dm.MatchingType_Full: str.Full, -} - -func domainToMatcher(domain *dm.Domain) (str.Matcher, error) { - matcherType, f := matcherTypeMap[domain.Type] - if !f { - return nil, newError("unsupported domain type", domain.Type) - } - - matcher, err := matcherType.New(domain.Value) - if err != nil { - return nil, newError("failed to create domain matcher").Base(err) - } - - return matcher, nil -} - -type DomainMatcher struct { - matchers str.IndexMatcher -} - -func NewDomainMatcher(domains []*dm.Domain) (*DomainMatcher, error) { - g := new(str.MatcherGroup) - for _, d := range domains { - m, err := domainToMatcher(d) - if err != nil { - return nil, err - } - g.Add(m) - } - - return &DomainMatcher{ - matchers: g, - }, nil -} - -func (m *DomainMatcher) ApplyDomain(domain string) bool { - return len(m.matchers.Match(domain)) > 0 -} - -// Apply implements Condition. -func (m *DomainMatcher) Apply(ctx routing.Context) bool { - domain := ctx.GetTargetDomain() - if len(domain) == 0 { - return false - } - return m.ApplyDomain(strings.ToLower(domain)) -} - type PortMatcher struct { port net.MemoryPortList onSource bool diff --git a/app/router/config.go b/app/router/config.go index 6fdfeda8b994..838e2296aa32 100644 --- a/app/router/config.go +++ b/app/router/config.go @@ -1,6 +1,7 @@ package router import ( + dm "github.com/xtls/xray-core/common/matcher/domain" "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/features/outbound" @@ -29,7 +30,7 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) { conds := NewConditionChan() if len(rr.Domain) > 0 { - matcher, err := NewDomainMatcher(rr.Domain) + matcher, err := dm.NewDomainMatcher(rr.Domain) if err != nil { return nil, newError("failed to build domain condition").Base(err) } diff --git a/common/matcher/domain/conf/domain.go b/common/matcher/domain/conf/domain.go index e71a9cc6f1c3..10a8cf57a25c 100644 --- a/common/matcher/domain/conf/domain.go +++ b/common/matcher/domain/conf/domain.go @@ -7,7 +7,7 @@ import ( "github.com/xtls/xray-core/common/matcher/geosite" ) -func ParaseDomainRule(domain string) ([]*dm.Domain, error) { +func ParseDomainRule(domain string) ([]*dm.Domain, error) { if strings.HasPrefix(domain, "geosite:") { country := strings.ToUpper(domain[8:]) domains, err := geosite.LoadGeositeWithAttr("geosite.dat", country) diff --git a/common/matcher/domain/matcher.go b/common/matcher/domain/matcher.go new file mode 100644 index 000000000000..474253439450 --- /dev/null +++ b/common/matcher/domain/matcher.go @@ -0,0 +1,60 @@ +package domain + +import ( + "github.com/xtls/xray-core/common/matcher/str" + "github.com/xtls/xray-core/features/routing" + "strings" +) + +var matcherTypeMap = map[MatchingType]str.Type{ + MatchingType_Keyword: str.Substr, + MatchingType_Regex: str.Regex, + MatchingType_Subdomain: str.Domain, + MatchingType_Full: str.Full, +} + +func domainToMatcher(domain *Domain) (str.Matcher, error) { + matcherType, f := matcherTypeMap[domain.Type] + if !f { + return nil, newError("unsupported domain type", domain.Type) + } + + matcher, err := matcherType.New(domain.Value) + if err != nil { + return nil, newError("failed to create domain matcher").Base(err) + } + + return matcher, nil +} + +type DomainMatcher struct { + matchers str.IndexMatcher +} + +func NewDomainMatcher(domains []*Domain) (*DomainMatcher, error) { + g := new(str.MatcherGroup) + for _, d := range domains { + m, err := domainToMatcher(d) + if err != nil { + return nil, err + } + g.Add(m) + } + + return &DomainMatcher{ + matchers: g, + }, nil +} + +func (m *DomainMatcher) ApplyDomain(domain string) bool { + return len(m.matchers.Match(domain)) > 0 +} + +// Apply implements Condition. +func (m *DomainMatcher) Apply(ctx routing.Context) bool { + domain := ctx.GetTargetDomain() + if len(domain) == 0 { + return false + } + return m.ApplyDomain(strings.ToLower(domain)) +} diff --git a/common/matcher/geoip/conf.go b/common/matcher/geoip/conf.go index d5be09cce17f..c2c9b8cb0abb 100644 --- a/common/matcher/geoip/conf.go +++ b/common/matcher/geoip/conf.go @@ -1,7 +1,11 @@ package geoip import ( + "github.com/xtls/xray-core/common/net" + "github.com/xtls/xray-core/infra/conf/common" "runtime" + "strconv" + "strings" "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/platform/filesystem" @@ -13,7 +17,7 @@ var ( ) func LoadGeoIP(code string) ([]*CIDR, error) { - return LoadIPFile("geoip.dat", code) + return LoadIPFile("dat", code) } func LoadIPFile(file, code string) ([]*CIDR, error) { @@ -88,3 +92,117 @@ func find(data, code []byte) []byte { data = data[bodyL:] } } + +func ParaseIPList(ips common.StringList) ([]*GeoIP, error) { + var geoipList []*GeoIP + var customCidrs []*CIDR + + for _, ip := range ips { + if strings.HasPrefix(ip, "geoip:") { + country := ip[6:] + geoipc, err := LoadGeoIP(strings.ToUpper(country)) + if err != nil { + return nil, newError("failed to load GeoIP: ", country).Base(err) + } + + geoipList = append(geoipList, &GeoIP{ + CountryCode: strings.ToUpper(country), + Cidr: geoipc, + }) + continue + } + var isExtDatFile = 0 + { + const prefix = "ext:" + if strings.HasPrefix(ip, prefix) { + isExtDatFile = len(prefix) + } + const prefixQualified = "ext-ip:" + if strings.HasPrefix(ip, prefixQualified) { + isExtDatFile = len(prefixQualified) + } + } + if isExtDatFile != 0 { + kv := strings.Split(ip[isExtDatFile:], ":") + if len(kv) != 2 { + return nil, newError("invalid external resource: ", ip) + } + + filename := kv[0] + country := kv[1] + geoipc, err := LoadIPFile(filename, strings.ToUpper(country)) + if err != nil { + return nil, newError("failed to load IPs: ", country, " from ", filename).Base(err) + } + + geoipList = append(geoipList, &GeoIP{ + CountryCode: strings.ToUpper(filename + "_" + country), + Cidr: geoipc, + }) + + continue + } + + ipRule, err := ParseIP(ip) + if err != nil { + return nil, newError("invalid IP: ", ip).Base(err) + } + customCidrs = append(customCidrs, ipRule) + } + + if len(customCidrs) > 0 { + geoipList = append(geoipList, &GeoIP{ + Cidr: customCidrs, + }) + } + + return geoipList, nil +} + +func ParseIP(s string) (*CIDR, error) { + var addr, mask string + i := strings.Index(s, "/") + if i < 0 { + addr = s + } else { + addr = s[:i] + mask = s[i+1:] + } + ip := net.ParseAddress(addr) + switch ip.Family() { + case net.AddressFamilyIPv4: + bits := uint32(32) + if len(mask) > 0 { + bits64, err := strconv.ParseUint(mask, 10, 32) + if err != nil { + return nil, newError("invalid network mask for router: ", mask).Base(err) + } + bits = uint32(bits64) + } + if bits > 32 { + return nil, newError("invalid network mask for router: ", bits) + } + return &CIDR{ + Ip: ip.IP(), + Prefix: bits, + }, nil + case net.AddressFamilyIPv6: + bits := uint32(128) + if len(mask) > 0 { + bits64, err := strconv.ParseUint(mask, 10, 32) + if err != nil { + return nil, newError("invalid network mask for router: ", mask).Base(err) + } + bits = uint32(bits64) + } + if bits > 128 { + return nil, newError("invalid network mask for router: ", bits) + } + return &CIDR{ + Ip: ip.IP(), + Prefix: bits, + }, nil + default: + return nil, newError("unsupported address for router: ", s) + } +} diff --git a/common/matcher/geoip/matcher.go b/common/matcher/geoip/matcher.go index c98ed115493d..e2f4e1888d96 100644 --- a/common/matcher/geoip/matcher.go +++ b/common/matcher/geoip/matcher.go @@ -45,3 +45,13 @@ func (m *MultiGeoIPMatcher) Apply(ctx routing.Context) bool { } return false } + +// MatchIP match given ip. +func (m *MultiGeoIPMatcher) MatchIP(ip net.IP) bool { + for _, matcher := range m.matchers { + if matcher.Match(ip) { + return true + } + } + return false +} diff --git a/common/session/session.go b/common/session/session.go index 24ac4631bcc8..7c7062aa68fe 100644 --- a/common/session/session.go +++ b/common/session/session.go @@ -3,6 +3,8 @@ package session // import "github.com/xtls/xray-core/common/session" import ( "context" + "github.com/xtls/xray-core/common/matcher/domain" + "github.com/xtls/xray-core/common/matcher/geoip" "math/rand" "github.com/xtls/xray-core/common/errors" @@ -60,7 +62,8 @@ type Outbound struct { // SniffingRequest controls the behavior of content sniffing. type SniffingRequest struct { - ExcludeForDomain []string + ExcludedDomainMatcher *domain.DomainMatcher + ExcludedIPMatcher *geoip.MultiGeoIPMatcher OverrideDestinationForProtocol []string Enabled bool MetadataOnly bool diff --git a/infra/conf/common.go b/infra/conf/common/common.go similarity index 98% rename from infra/conf/common.go rename to infra/conf/common/common.go index 0de30728f65c..a24543899e4d 100644 --- a/infra/conf/common.go +++ b/infra/conf/common/common.go @@ -1,4 +1,4 @@ -package conf +package common import ( "encoding/json" @@ -9,6 +9,8 @@ import ( "github.com/xtls/xray-core/common/protocol" ) +//go:generate go run github.com/xtls/xray-core/common/errors/errorgen + type StringList []string func NewStringList(raw []string) *StringList { diff --git a/infra/conf/common_test.go b/infra/conf/common/common_test.go similarity index 98% rename from infra/conf/common_test.go rename to infra/conf/common/common_test.go index 39e4cbeac3b6..6bc73c931435 100644 --- a/infra/conf/common_test.go +++ b/infra/conf/common/common_test.go @@ -1,4 +1,4 @@ -package conf_test +package common_test import ( "encoding/json" @@ -11,7 +11,7 @@ import ( "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/protocol" - . "github.com/xtls/xray-core/infra/conf" + . "github.com/xtls/xray-core/infra/conf/common" ) func TestStringListUnmarshalError(t *testing.T) { diff --git a/infra/conf/common/errors.generated.go b/infra/conf/common/errors.generated.go new file mode 100644 index 000000000000..28b9a625522c --- /dev/null +++ b/infra/conf/common/errors.generated.go @@ -0,0 +1,9 @@ +package common + +import "github.com/xtls/xray-core/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} diff --git a/infra/conf/dns.go b/infra/conf/dns.go index ce7bc24ea97e..807600ecf162 100644 --- a/infra/conf/dns.go +++ b/infra/conf/dns.go @@ -2,6 +2,8 @@ package conf import ( "encoding/json" + "github.com/xtls/xray-core/common/matcher/geoip" + "github.com/xtls/xray-core/infra/conf/common" "sort" "strings" @@ -13,24 +15,24 @@ import ( ) type NameServerConfig struct { - Address *Address + Address *common.Address Port uint16 Domains []string - ExpectIPs StringList + ExpectIPs common.StringList } func (c *NameServerConfig) UnmarshalJSON(data []byte) error { - var address Address + var address common.Address if err := json.Unmarshal(data, &address); err == nil { c.Address = &address return nil } var advanced struct { - Address *Address `json:"address"` - Port uint16 `json:"port"` - Domains []string `json:"domains"` - ExpectIPs StringList `json:"expectIps"` + Address *common.Address `json:"address"` + Port uint16 `json:"port"` + Domains []string `json:"domains"` + ExpectIPs common.StringList `json:"expectIps"` } if err := json.Unmarshal(data, &advanced); err == nil { c.Address = advanced.Address @@ -52,7 +54,7 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) { var originalRules []*dns.NameServer_OriginalRule for _, rule := range c.Domains { - parsedDomain, err := conf.ParaseDomainRule(rule) + parsedDomain, err := conf.ParseDomainRule(rule) if err != nil { return nil, newError("invalid domain rule: ", rule).Base(err) } @@ -69,7 +71,7 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) { }) } - geoipList, err := toCidrList(c.ExpectIPs) + geoipList, err := geoip.ParaseIPList(c.ExpectIPs) if err != nil { return nil, newError("invalid IP rule: ", c.ExpectIPs).Base(err) } @@ -88,15 +90,15 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) { // DNSConfig is a JSON serializable object for dns.Config. type DNSConfig struct { - Servers []*NameServerConfig `json:"servers"` - Hosts map[string]*Address `json:"hosts"` - ClientIP *Address `json:"clientIp"` - Tag string `json:"tag"` - QueryStrategy string `json:"queryStrategy"` - DisableCache bool `json:"disableCache"` + Servers []*NameServerConfig `json:"servers"` + Hosts map[string]*common.Address `json:"hosts"` + ClientIP *common.Address `json:"clientIp"` + Tag string `json:"tag"` + QueryStrategy string `json:"queryStrategy"` + DisableCache bool `json:"disableCache"` } -func getHostMapping(addr *Address) *dns.Config_HostMapping { +func getHostMapping(addr *common.Address) *dns.Config_HostMapping { if addr.Family().IsIP() { return &dns.Config_HostMapping{ Ip: [][]byte{[]byte(addr.IP())}, diff --git a/infra/conf/dns_proxy.go b/infra/conf/dns_proxy.go index 922d32bafcae..4b1f3b915401 100644 --- a/infra/conf/dns_proxy.go +++ b/infra/conf/dns_proxy.go @@ -3,13 +3,14 @@ package conf import ( "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/net" + "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/dns" ) type DNSOutboundConfig struct { - Network Network `json:"network"` - Address *Address `json:"address"` - Port uint16 `json:"port"` + Network common.Network `json:"network"` + Address *common.Address `json:"address"` + Port uint16 `json:"port"` } func (c *DNSOutboundConfig) Build() (proto.Message, error) { diff --git a/infra/conf/dokodemo.go b/infra/conf/dokodemo.go index 03a21d71192f..c5b42e657f0d 100644 --- a/infra/conf/dokodemo.go +++ b/infra/conf/dokodemo.go @@ -2,16 +2,17 @@ package conf import ( "github.com/golang/protobuf/proto" + "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/dokodemo" ) type DokodemoConfig struct { - Host *Address `json:"address"` - PortValue uint16 `json:"port"` - NetworkList *NetworkList `json:"network"` - TimeoutValue uint32 `json:"timeout"` - Redirect bool `json:"followRedirect"` - UserLevel uint32 `json:"userLevel"` + Host *common.Address `json:"address"` + PortValue uint16 `json:"port"` + NetworkList *common.NetworkList `json:"network"` + TimeoutValue uint32 `json:"timeout"` + Redirect bool `json:"followRedirect"` + UserLevel uint32 `json:"userLevel"` } func (v *DokodemoConfig) Build() (proto.Message, error) { diff --git a/infra/conf/http.go b/infra/conf/http.go index e6969582b7e6..7b9acaa771f9 100644 --- a/infra/conf/http.go +++ b/infra/conf/http.go @@ -2,6 +2,7 @@ package conf import ( "encoding/json" + "github.com/xtls/xray-core/infra/conf/common" "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/protocol" @@ -46,7 +47,7 @@ func (c *HTTPServerConfig) Build() (proto.Message, error) { } type HTTPRemoteConfig struct { - Address *Address `json:"address"` + Address *common.Address `json:"address"` Port uint16 `json:"port"` Users []json.RawMessage `json:"users"` } diff --git a/infra/conf/router.go b/infra/conf/router.go index 128096ab67e6..1f68e3049082 100644 --- a/infra/conf/router.go +++ b/infra/conf/router.go @@ -2,6 +2,7 @@ package conf import ( "encoding/json" + "github.com/xtls/xray-core/infra/conf/common" "strconv" "strings" @@ -10,7 +11,6 @@ import ( "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/matcher/geosite" "github.com/xtls/xray-core/common/net" - "github.com/xtls/xray-core/common/platform/filesystem" ) type RouterRulesConfig struct { @@ -19,8 +19,8 @@ type RouterRulesConfig struct { } type BalancingRule struct { - Tag string `json:"tag"` - Selectors StringList `json:"selector"` + Tag string `json:"tag"` + Selectors common.StringList `json:"selector"` } func (r *BalancingRule) Build() (*router.BalancingRule, error) { @@ -148,108 +148,20 @@ func ParseIP(s string) (*geoip.CIDR, error) { } } -var ( - FileCache = make(map[string][]byte) - IPCache = make(map[string]*geoip.GeoIP) -) - -func loadFile(file string) ([]byte, error) { - if FileCache[file] == nil { - bs, err := filesystem.ReadAsset(file) - if err != nil { - return nil, newError("failed to open file: ", file).Base(err) - } - if len(bs) == 0 { - return nil, newError("empty file: ", file) - } - // Do not cache file, may save RAM when there - // are many files, but consume CPU each time. - return bs, nil - FileCache[file] = bs - } - return FileCache[file], nil -} - -func toCidrList(ips StringList) ([]*geoip.GeoIP, error) { - var geoipList []*geoip.GeoIP - var customCidrs []*geoip.CIDR - - for _, ip := range ips { - if strings.HasPrefix(ip, "geoip:") { - country := ip[6:] - geoipc, err := geoip.LoadGeoIP(strings.ToUpper(country)) - if err != nil { - return nil, newError("failed to load GeoIP: ", country).Base(err) - } - - geoipList = append(geoipList, &geoip.GeoIP{ - CountryCode: strings.ToUpper(country), - Cidr: geoipc, - }) - continue - } - var isExtDatFile = 0 - { - const prefix = "ext:" - if strings.HasPrefix(ip, prefix) { - isExtDatFile = len(prefix) - } - const prefixQualified = "ext-ip:" - if strings.HasPrefix(ip, prefixQualified) { - isExtDatFile = len(prefixQualified) - } - } - if isExtDatFile != 0 { - kv := strings.Split(ip[isExtDatFile:], ":") - if len(kv) != 2 { - return nil, newError("invalid external resource: ", ip) - } - - filename := kv[0] - country := kv[1] - geoipc, err := geoip.LoadIPFile(filename, strings.ToUpper(country)) - if err != nil { - return nil, newError("failed to load IPs: ", country, " from ", filename).Base(err) - } - - geoipList = append(geoipList, &geoip.GeoIP{ - CountryCode: strings.ToUpper(filename + "_" + country), - Cidr: geoipc, - }) - - continue - } - - ipRule, err := ParseIP(ip) - if err != nil { - return nil, newError("invalid IP: ", ip).Base(err) - } - customCidrs = append(customCidrs, ipRule) - } - - if len(customCidrs) > 0 { - geoipList = append(geoipList, &geoip.GeoIP{ - Cidr: customCidrs, - }) - } - - return geoipList, nil -} - func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { type RawFieldRule struct { RouterRule - Domain *StringList `json:"domain"` - Domains *StringList `json:"domains"` - IP *StringList `json:"ip"` - Port *PortList `json:"port"` - Network *NetworkList `json:"network"` - SourceIP *StringList `json:"source"` - SourcePort *PortList `json:"sourcePort"` - User *StringList `json:"user"` - InboundTag *StringList `json:"inboundTag"` - Protocols *StringList `json:"protocol"` - Attributes string `json:"attrs"` + Domain *common.StringList `json:"domain"` + Domains *common.StringList `json:"domains"` + IP *common.StringList `json:"ip"` + Port *common.PortList `json:"port"` + Network *common.NetworkList `json:"network"` + SourceIP *common.StringList `json:"source"` + SourcePort *common.PortList `json:"sourcePort"` + User *common.StringList `json:"user"` + InboundTag *common.StringList `json:"inboundTag"` + Protocols *common.StringList `json:"protocol"` + Attributes string `json:"attrs"` } rawFieldRule := new(RawFieldRule) err := json.Unmarshal(msg, rawFieldRule) @@ -273,7 +185,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { if rawFieldRule.Domain != nil { for _, domain := range *rawFieldRule.Domain { - rules, err := conf.ParaseDomainRule(domain) + rules, err := conf.ParseDomainRule(domain) if err != nil { return nil, newError("failed to parse domain rule: ", domain).Base(err) } @@ -283,7 +195,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { if rawFieldRule.Domains != nil { for _, domain := range *rawFieldRule.Domains { - rules, err := conf.ParaseDomainRule(domain) + rules, err := conf.ParseDomainRule(domain) if err != nil { return nil, newError("failed to parse domain rule: ", domain).Base(err) } @@ -292,7 +204,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { } if rawFieldRule.IP != nil { - geoipList, err := toCidrList(*rawFieldRule.IP) + geoipList, err := geoip.ParaseIPList(*rawFieldRule.IP) if err != nil { return nil, err } @@ -308,7 +220,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { } if rawFieldRule.SourceIP != nil { - geoipList, err := toCidrList(*rawFieldRule.SourceIP) + geoipList, err := geoip.ParaseIPList(*rawFieldRule.SourceIP) if err != nil { return nil, err } diff --git a/infra/conf/shadowsocks.go b/infra/conf/shadowsocks.go index fbb2a79d583a..42b9f038815f 100644 --- a/infra/conf/shadowsocks.go +++ b/infra/conf/shadowsocks.go @@ -1,6 +1,7 @@ package conf import ( + "github.com/xtls/xray-core/infra/conf/common" "strings" "github.com/golang/protobuf/proto" @@ -46,7 +47,7 @@ type ShadowsocksServerConfig struct { Level byte `json:"level"` Email string `json:"email"` Users []*ShadowsocksUserConfig `json:"clients"` - NetworkList *NetworkList `json:"network"` + NetworkList *common.NetworkList `json:"network"` } func (v *ShadowsocksServerConfig) Build() (proto.Message, error) { @@ -93,12 +94,12 @@ func (v *ShadowsocksServerConfig) Build() (proto.Message, error) { } type ShadowsocksServerTarget struct { - Address *Address `json:"address"` - Port uint16 `json:"port"` - Cipher string `json:"method"` - Password string `json:"password"` - Email string `json:"email"` - Level byte `json:"level"` + Address *common.Address `json:"address"` + Port uint16 `json:"port"` + Cipher string `json:"method"` + Password string `json:"password"` + Email string `json:"email"` + Level byte `json:"level"` } type ShadowsocksClientConfig struct { diff --git a/infra/conf/socks.go b/infra/conf/socks.go index 05dad7bc18fb..ea2a41893888 100644 --- a/infra/conf/socks.go +++ b/infra/conf/socks.go @@ -2,6 +2,7 @@ package conf import ( "encoding/json" + "github.com/xtls/xray-core/infra/conf/common" "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/protocol" @@ -30,7 +31,7 @@ type SocksServerConfig struct { AuthMethod string `json:"auth"` Accounts []*SocksAccount `json:"accounts"` UDP bool `json:"udp"` - Host *Address `json:"ip"` + Host *common.Address `json:"ip"` Timeout uint32 `json:"timeout"` UserLevel uint32 `json:"userLevel"` } @@ -65,7 +66,7 @@ func (v *SocksServerConfig) Build() (proto.Message, error) { } type SocksRemoteConfig struct { - Address *Address `json:"address"` + Address *common.Address `json:"address"` Port uint16 `json:"port"` Users []json.RawMessage `json:"users"` } diff --git a/infra/conf/transport_authenticators.go b/infra/conf/transport_authenticators.go index c9e42605b10d..f000e8d4707e 100644 --- a/infra/conf/transport_authenticators.go +++ b/infra/conf/transport_authenticators.go @@ -1,6 +1,7 @@ package conf import ( + "github.com/xtls/xray-core/infra/conf/common" "sort" "github.com/golang/protobuf/proto" @@ -57,13 +58,13 @@ func (DTLSAuthenticator) Build() (proto.Message, error) { } type AuthenticatorRequest struct { - Version string `json:"version"` - Method string `json:"method"` - Path StringList `json:"path"` - Headers map[string]*StringList `json:"headers"` + Version string `json:"version"` + Method string `json:"method"` + Path common.StringList `json:"path"` + Headers map[string]*common.StringList `json:"headers"` } -func sortMapKeys(m map[string]*StringList) []string { +func sortMapKeys(m map[string]*common.StringList) []string { var keys []string for key := range m { keys = append(keys, key) @@ -133,10 +134,10 @@ func (v *AuthenticatorRequest) Build() (*http.RequestConfig, error) { } type AuthenticatorResponse struct { - Version string `json:"version"` - Status string `json:"status"` - Reason string `json:"reason"` - Headers map[string]*StringList `json:"headers"` + Version string `json:"version"` + Status string `json:"status"` + Reason string `json:"reason"` + Headers map[string]*common.StringList `json:"headers"` } func (v *AuthenticatorResponse) Build() (*http.ResponseConfig, error) { diff --git a/infra/conf/transport_internet.go b/infra/conf/transport_internet.go index 15d5dd3257d3..980a49a829de 100644 --- a/infra/conf/transport_internet.go +++ b/infra/conf/transport_internet.go @@ -2,6 +2,7 @@ package conf import ( "encoding/json" + "github.com/xtls/xray-core/infra/conf/common" "math" "net/url" "strconv" @@ -179,8 +180,8 @@ func (c *WebSocketConfig) Build() (proto.Message, error) { } type HTTPConfig struct { - Host *StringList `json:"host"` - Path string `json:"path"` + Host *common.StringList `json:"host"` + Path string `json:"path"` } // Build implements Buildable. @@ -311,16 +312,16 @@ func (c *TLSCertConfig) Build() (*tls.Certificate, error) { } type TLSConfig struct { - Insecure bool `json:"allowInsecure"` - Certs []*TLSCertConfig `json:"certificates"` - ServerName string `json:"serverName"` - ALPN *StringList `json:"alpn"` - EnableSessionResumption bool `json:"enableSessionResumption"` - DisableSystemRoot bool `json:"disableSystemRoot"` - MinVersion string `json:"minVersion"` - MaxVersion string `json:"maxVersion"` - CipherSuites string `json:"cipherSuites"` - PreferServerCipherSuites bool `json:"preferServerCipherSuites"` + Insecure bool `json:"allowInsecure"` + Certs []*TLSCertConfig `json:"certificates"` + ServerName string `json:"serverName"` + ALPN *common.StringList `json:"alpn"` + EnableSessionResumption bool `json:"enableSessionResumption"` + DisableSystemRoot bool `json:"disableSystemRoot"` + MinVersion string `json:"minVersion"` + MaxVersion string `json:"maxVersion"` + CipherSuites string `json:"cipherSuites"` + PreferServerCipherSuites bool `json:"preferServerCipherSuites"` } // Build implements Buildable. @@ -401,16 +402,16 @@ func (c *XTLSCertConfig) Build() (*xtls.Certificate, error) { } type XTLSConfig struct { - Insecure bool `json:"allowInsecure"` - Certs []*XTLSCertConfig `json:"certificates"` - ServerName string `json:"serverName"` - ALPN *StringList `json:"alpn"` - EnableSessionResumption bool `json:"enableSessionResumption"` - DisableSystemRoot bool `json:"disableSystemRoot"` - MinVersion string `json:"minVersion"` - MaxVersion string `json:"maxVersion"` - CipherSuites string `json:"cipherSuites"` - PreferServerCipherSuites bool `json:"preferServerCipherSuites"` + Insecure bool `json:"allowInsecure"` + Certs []*XTLSCertConfig `json:"certificates"` + ServerName string `json:"serverName"` + ALPN *common.StringList `json:"alpn"` + EnableSessionResumption bool `json:"enableSessionResumption"` + DisableSystemRoot bool `json:"disableSystemRoot"` + MinVersion string `json:"minVersion"` + MaxVersion string `json:"maxVersion"` + CipherSuites string `json:"cipherSuites"` + PreferServerCipherSuites bool `json:"preferServerCipherSuites"` } // Build implements Buildable. diff --git a/infra/conf/trojan.go b/infra/conf/trojan.go index 4fe96c071585..b59894cb16f7 100644 --- a/infra/conf/trojan.go +++ b/infra/conf/trojan.go @@ -2,6 +2,7 @@ package conf import ( "encoding/json" + "github.com/xtls/xray-core/infra/conf/common" "runtime" "strconv" "syscall" @@ -16,12 +17,12 @@ import ( // TrojanServerTarget is configuration of a single trojan server type TrojanServerTarget struct { - Address *Address `json:"address"` - Port uint16 `json:"port"` - Password string `json:"password"` - Email string `json:"email"` - Level byte `json:"level"` - Flow string `json:"flow"` + Address *common.Address `json:"address"` + Port uint16 `json:"port"` + Password string `json:"password"` + Email string `json:"email"` + Level byte `json:"level"` + Flow string `json:"flow"` } // TrojanClientConfig is configuration of trojan servers diff --git a/infra/conf/vless.go b/infra/conf/vless.go index f5ded7a00607..33a5c3b11ebc 100644 --- a/infra/conf/vless.go +++ b/infra/conf/vless.go @@ -2,6 +2,7 @@ package conf import ( "encoding/json" + "github.com/xtls/xray-core/infra/conf/common" "runtime" "strconv" "syscall" @@ -137,7 +138,7 @@ func (c *VLessInboundConfig) Build() (proto.Message, error) { } type VLessOutboundVnext struct { - Address *Address `json:"address"` + Address *common.Address `json:"address"` Port uint16 `json:"port"` Users []json.RawMessage `json:"users"` } diff --git a/infra/conf/vmess.go b/infra/conf/vmess.go index 1200be07047a..62084c092eff 100644 --- a/infra/conf/vmess.go +++ b/infra/conf/vmess.go @@ -2,6 +2,7 @@ package conf import ( "encoding/json" + "github.com/xtls/xray-core/infra/conf/common" "strings" "github.com/golang/protobuf/proto" @@ -123,7 +124,7 @@ func (c *VMessInboundConfig) Build() (proto.Message, error) { } type VMessOutboundTarget struct { - Address *Address `json:"address"` + Address *common.Address `json:"address"` Port uint16 `json:"port"` Users []json.RawMessage `json:"users"` } diff --git a/infra/conf/xray.go b/infra/conf/xray.go index 0b139792e5d8..f871222107a8 100644 --- a/infra/conf/xray.go +++ b/infra/conf/xray.go @@ -2,6 +2,10 @@ package conf import ( "encoding/json" + "github.com/xtls/xray-core/common/matcher/domain" + "github.com/xtls/xray-core/common/matcher/domain/conf" + "github.com/xtls/xray-core/common/matcher/geoip" + "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/transport/internet" "log" "os" @@ -59,10 +63,11 @@ func toProtocolList(s []string) ([]proxyman.KnownProtocols, error) { } type SniffingConfig struct { - Enabled bool `json:"enabled"` - DestOverride *StringList `json:"destOverride"` - DomainsExcluded *StringList `json:"domainsExcluded"` - MetadataOnly bool `json:"metadataOnly"` + Enabled bool `json:"enabled"` + DestOverride *common.StringList `json:"destOverride"` + DomainsExcluded *common.StringList `json:"domainsExcluded"` + IPsExcluded *common.StringList `json:"ipsExcluded"` + MetadataOnly bool `json:"metadataOnly"` } // Build implements Buildable. @@ -83,17 +88,31 @@ func (c *SniffingConfig) Build() (*proxyman.SniffingConfig, error) { } } - var d []string + var exDomain []*domain.Domain if c.DomainsExcluded != nil { - for _, domain := range *c.DomainsExcluded { - d = append(d, strings.ToLower(domain)) + for _, dmr := range *c.DomainsExcluded { + if dm, err := conf.ParseDomainRule(dmr); err == nil { + exDomain = append(exDomain, dm...) + } else { + return nil, newError("failed to parse excluded domain").Base(err) + } + } + } + + var exIP []*geoip.GeoIP + if c.IPsExcluded != nil { + exip, err := geoip.ParaseIPList(*c.IPsExcluded) + if err != nil { + return nil, newError("failed to parse excluded ip").Base(err) } + exIP = exip } return &proxyman.SniffingConfig{ Enabled: c.Enabled, DestinationOverride: p, - DomainsExcluded: d, + DomainsExcluded: exDomain, + IpsExcluded: exIP, MetadataOnly: c.MetadataOnly, }, nil } @@ -156,13 +175,13 @@ func (c *InboundDetourAllocationConfig) Build() (*proxyman.AllocationStrategy, e type InboundDetourConfig struct { Protocol string `json:"protocol"` - PortRange *PortRange `json:"port"` - ListenOn *Address `json:"listen"` + PortRange *common.PortRange `json:"port"` + ListenOn *common.Address `json:"listen"` Settings *json.RawMessage `json:"settings"` Tag string `json:"tag"` Allocation *InboundDetourAllocationConfig `json:"allocate"` StreamSetting *StreamConfig `json:"streamSettings"` - DomainOverride *StringList `json:"domainOverride"` + DomainOverride *common.StringList `json:"domainOverride"` SniffingConfig *SniffingConfig `json:"sniffing"` } @@ -264,7 +283,7 @@ func (c *InboundDetourConfig) Build() (*core.InboundHandlerConfig, error) { type OutboundDetourConfig struct { Protocol string `json:"protocol"` - SendThrough *Address `json:"sendThrough"` + SendThrough *common.Address `json:"sendThrough"` Tag string `json:"tag"` Settings *json.RawMessage `json:"settings"` StreamSetting *StreamConfig `json:"streamSettings"` @@ -622,7 +641,7 @@ func (c *Config) Build() (*core.Config, error) { // Backward compatibility. if len(inbounds) > 0 && inbounds[0].PortRange == nil && c.Port > 0 { - inbounds[0].PortRange = &PortRange{ + inbounds[0].PortRange = &common.PortRange{ From: uint32(c.Port), To: uint32(c.Port), } diff --git a/infra/conf/xray_test.go b/infra/conf/xray_test.go index 96df370ee514..bf7e2c519de9 100644 --- a/infra/conf/xray_test.go +++ b/infra/conf/xray_test.go @@ -2,6 +2,7 @@ package conf_test import ( "encoding/json" + "github.com/xtls/xray-core/common/matcher/domain" "reflect" "testing" @@ -372,6 +373,52 @@ func TestMuxConfig_Build(t *testing.T) { } } +func TestSniffingConfig_Build(t *testing.T) { + tests := []struct { + name string + fields string + want *proxyman.SniffingConfig + }{ + {"default", ` +{ + "enabled": true, + "destOverride": ["tls"], + "domainsExcluded": ["domain:google.com"], + "ipsExcluded": ["8.8.8.8"] +}`, &proxyman.SniffingConfig{ + Enabled: true, + DestinationOverride: []string{"tls"}, + DomainsExcluded: []*domain.Domain{ + { + Type: domain.MatchingType_Subdomain, + Value: "google.com", + }, + }, + IpsExcluded: []*geoip.GeoIP{ + { + Cidr: []*geoip.CIDR{{Ip: []byte{8, 8, 8, 8}, Prefix: 32}}, + }, + }, + }}, + {"empty def", `{}`, &proxyman.SniffingConfig{ + Enabled: false, + }}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + m := &SniffingConfig{} + common.Must(json.Unmarshal([]byte(tt.fields), m)) + got, err := m.Build() + if err != nil { + t.Errorf("%v", err) + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("SniffingConfig.Build() = %v, want %v", got, tt.want) + } + }) + } +} + func TestConfig_Override(t *testing.T) { tests := []struct { name string From fc8b58001754ec543f6738adc9efbea6f88c2d71 Mon Sep 17 00:00:00 2001 From: JimhHan <50871214+JimhHan@users.noreply.github.com> Date: Fri, 26 Mar 2021 17:19:09 +0800 Subject: [PATCH 04/20] Fix: tests --- app/proxyman/config.go | 4 ++++ app/router/condition_test.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/proxyman/config.go b/app/proxyman/config.go index 302d208f61de..16506627fa6c 100644 --- a/app/proxyman/config.go +++ b/app/proxyman/config.go @@ -53,6 +53,10 @@ type SniffingMatcher struct { func NewSniffingMatcher(sc *SniffingConfig) (*SniffingMatcher, error) { m := new(SniffingMatcher) + if sc == nil { + return m, nil + } + if sc.DomainsExcluded != nil { exDomain, err := domain.NewDomainMatcher(sc.DomainsExcluded) if err != nil { diff --git a/app/router/condition_test.go b/app/router/condition_test.go index 2ee1c0202cae..e4f203411932 100644 --- a/app/router/condition_test.go +++ b/app/router/condition_test.go @@ -359,7 +359,7 @@ func TestChinaSites(t *testing.T) { domains, err := loadGeoSite("CN") common.Must(err) - matcher, err := NewDomainMatcher(domains) + matcher, err := domain.NewDomainMatcher(domains) common.Must(err) type TestCase struct { From 4eb3acb4ddff44f964473440e336baed502c8643 Mon Sep 17 00:00:00 2001 From: JimhHan <50871214+JimhHan@users.noreply.github.com> Date: Fri, 26 Mar 2021 17:30:24 +0800 Subject: [PATCH 05/20] Fix: format --- common/matcher/domain/matcher.go | 3 ++- common/matcher/geoip/conf.go | 5 ++--- common/session/session.go | 4 ++-- infra/conf/dns.go | 5 +++-- infra/conf/http.go | 2 +- infra/conf/router.go | 2 +- infra/conf/shadowsocks.go | 2 +- infra/conf/socks.go | 2 +- infra/conf/transport_authenticators.go | 2 +- infra/conf/transport_internet.go | 2 +- infra/conf/trojan.go | 2 +- infra/conf/vless.go | 2 +- infra/conf/vmess.go | 2 +- infra/conf/xray.go | 11 ++++++----- 14 files changed, 24 insertions(+), 22 deletions(-) diff --git a/common/matcher/domain/matcher.go b/common/matcher/domain/matcher.go index 474253439450..1abad45ca712 100644 --- a/common/matcher/domain/matcher.go +++ b/common/matcher/domain/matcher.go @@ -1,9 +1,10 @@ package domain import ( + "strings" + "github.com/xtls/xray-core/common/matcher/str" "github.com/xtls/xray-core/features/routing" - "strings" ) var matcherTypeMap = map[MatchingType]str.Type{ diff --git a/common/matcher/geoip/conf.go b/common/matcher/geoip/conf.go index c2c9b8cb0abb..e7d89ac65179 100644 --- a/common/matcher/geoip/conf.go +++ b/common/matcher/geoip/conf.go @@ -1,13 +1,12 @@ package geoip import ( - "github.com/xtls/xray-core/common/net" - "github.com/xtls/xray-core/infra/conf/common" "runtime" "strconv" "strings" "github.com/golang/protobuf/proto" + "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/platform/filesystem" ) @@ -93,7 +92,7 @@ func find(data, code []byte) []byte { } } -func ParaseIPList(ips common.StringList) ([]*GeoIP, error) { +func ParaseIPList(ips []string) ([]*GeoIP, error) { var geoipList []*GeoIP var customCidrs []*CIDR diff --git a/common/session/session.go b/common/session/session.go index 7c7062aa68fe..9b32773f9437 100644 --- a/common/session/session.go +++ b/common/session/session.go @@ -3,11 +3,11 @@ package session // import "github.com/xtls/xray-core/common/session" import ( "context" - "github.com/xtls/xray-core/common/matcher/domain" - "github.com/xtls/xray-core/common/matcher/geoip" "math/rand" "github.com/xtls/xray-core/common/errors" + "github.com/xtls/xray-core/common/matcher/domain" + "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/signal" diff --git a/infra/conf/dns.go b/infra/conf/dns.go index 807600ecf162..9a70e3e82ec5 100644 --- a/infra/conf/dns.go +++ b/infra/conf/dns.go @@ -2,16 +2,17 @@ package conf import ( "encoding/json" - "github.com/xtls/xray-core/common/matcher/geoip" - "github.com/xtls/xray-core/infra/conf/common" + "sort" "strings" "github.com/xtls/xray-core/app/dns" dm "github.com/xtls/xray-core/common/matcher/domain" "github.com/xtls/xray-core/common/matcher/domain/conf" + "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/matcher/geosite" "github.com/xtls/xray-core/common/net" + "github.com/xtls/xray-core/infra/conf/common" ) type NameServerConfig struct { diff --git a/infra/conf/http.go b/infra/conf/http.go index 7b9acaa771f9..ebaaa7fdf723 100644 --- a/infra/conf/http.go +++ b/infra/conf/http.go @@ -2,11 +2,11 @@ package conf import ( "encoding/json" - "github.com/xtls/xray-core/infra/conf/common" "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" + "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/http" ) diff --git a/infra/conf/router.go b/infra/conf/router.go index 1f68e3049082..504632677115 100644 --- a/infra/conf/router.go +++ b/infra/conf/router.go @@ -2,7 +2,6 @@ package conf import ( "encoding/json" - "github.com/xtls/xray-core/infra/conf/common" "strconv" "strings" @@ -11,6 +10,7 @@ import ( "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/matcher/geosite" "github.com/xtls/xray-core/common/net" + "github.com/xtls/xray-core/infra/conf/common" ) type RouterRulesConfig struct { diff --git a/infra/conf/shadowsocks.go b/infra/conf/shadowsocks.go index 42b9f038815f..f5b4305d938a 100644 --- a/infra/conf/shadowsocks.go +++ b/infra/conf/shadowsocks.go @@ -1,13 +1,13 @@ package conf import ( - "github.com/xtls/xray-core/infra/conf/common" "strings" "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" + "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/shadowsocks" ) diff --git a/infra/conf/socks.go b/infra/conf/socks.go index ea2a41893888..61d8295e6bbe 100644 --- a/infra/conf/socks.go +++ b/infra/conf/socks.go @@ -2,11 +2,11 @@ package conf import ( "encoding/json" - "github.com/xtls/xray-core/infra/conf/common" "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" + "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/socks" ) diff --git a/infra/conf/transport_authenticators.go b/infra/conf/transport_authenticators.go index f000e8d4707e..f0ddffe3d3fd 100644 --- a/infra/conf/transport_authenticators.go +++ b/infra/conf/transport_authenticators.go @@ -1,11 +1,11 @@ package conf import ( - "github.com/xtls/xray-core/infra/conf/common" "sort" "github.com/golang/protobuf/proto" + "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/transport/internet/headers/http" "github.com/xtls/xray-core/transport/internet/headers/noop" "github.com/xtls/xray-core/transport/internet/headers/srtp" diff --git a/infra/conf/transport_internet.go b/infra/conf/transport_internet.go index 980a49a829de..9e929e97bddf 100644 --- a/infra/conf/transport_internet.go +++ b/infra/conf/transport_internet.go @@ -2,7 +2,6 @@ package conf import ( "encoding/json" - "github.com/xtls/xray-core/infra/conf/common" "math" "net/url" "strconv" @@ -12,6 +11,7 @@ import ( "github.com/xtls/xray-core/common/platform/filesystem" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" + "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/transport/internet" "github.com/xtls/xray-core/transport/internet/domainsocket" "github.com/xtls/xray-core/transport/internet/http" diff --git a/infra/conf/trojan.go b/infra/conf/trojan.go index b59894cb16f7..0a71e24388d6 100644 --- a/infra/conf/trojan.go +++ b/infra/conf/trojan.go @@ -2,7 +2,6 @@ package conf import ( "encoding/json" - "github.com/xtls/xray-core/infra/conf/common" "runtime" "strconv" "syscall" @@ -12,6 +11,7 @@ import ( "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" + "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/trojan" ) diff --git a/infra/conf/vless.go b/infra/conf/vless.go index 33a5c3b11ebc..c7a07fb29332 100644 --- a/infra/conf/vless.go +++ b/infra/conf/vless.go @@ -2,7 +2,6 @@ package conf import ( "encoding/json" - "github.com/xtls/xray-core/infra/conf/common" "runtime" "strconv" "syscall" @@ -13,6 +12,7 @@ import ( "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/common/uuid" + "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/vless" "github.com/xtls/xray-core/proxy/vless/inbound" "github.com/xtls/xray-core/proxy/vless/outbound" diff --git a/infra/conf/vmess.go b/infra/conf/vmess.go index 62084c092eff..9670dc299db3 100644 --- a/infra/conf/vmess.go +++ b/infra/conf/vmess.go @@ -2,7 +2,6 @@ package conf import ( "encoding/json" - "github.com/xtls/xray-core/infra/conf/common" "strings" "github.com/golang/protobuf/proto" @@ -10,6 +9,7 @@ import ( "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/common/uuid" + "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/vmess" "github.com/xtls/xray-core/proxy/vmess/inbound" "github.com/xtls/xray-core/proxy/vmess/outbound" diff --git a/infra/conf/xray.go b/infra/conf/xray.go index f871222107a8..02561c5eef37 100644 --- a/infra/conf/xray.go +++ b/infra/conf/xray.go @@ -2,11 +2,7 @@ package conf import ( "encoding/json" - "github.com/xtls/xray-core/common/matcher/domain" - "github.com/xtls/xray-core/common/matcher/domain/conf" - "github.com/xtls/xray-core/common/matcher/geoip" - "github.com/xtls/xray-core/infra/conf/common" - "github.com/xtls/xray-core/transport/internet" + "log" "os" "strings" @@ -14,8 +10,13 @@ import ( "github.com/xtls/xray-core/app/dispatcher" "github.com/xtls/xray-core/app/proxyman" "github.com/xtls/xray-core/app/stats" + "github.com/xtls/xray-core/common/matcher/domain" + "github.com/xtls/xray-core/common/matcher/domain/conf" + "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/serial" core "github.com/xtls/xray-core/core" + "github.com/xtls/xray-core/infra/conf/common" + "github.com/xtls/xray-core/transport/internet" "github.com/xtls/xray-core/transport/internet/xtls" ) From 58bca70dfbc8bfc0a0df2281e737d69672bd9e43 Mon Sep 17 00:00:00 2001 From: JimhHan <50871214+JimhHan@users.noreply.github.com> Date: Sat, 27 Mar 2021 15:33:20 +0800 Subject: [PATCH 06/20] Revert: move common.go to common --- infra/conf/{common => }/common.go | 2 +- infra/conf/common/errors.generated.go | 9 ----- infra/conf/{common => }/common_test.go | 50 +++++++++++++------------- infra/conf/dns.go | 29 ++++++++------- infra/conf/dns_proxy.go | 7 ++-- infra/conf/dokodemo.go | 13 ++++--- infra/conf/http.go | 3 +- infra/conf/router.go | 27 +++++++------- infra/conf/shadowsocks.go | 15 ++++---- infra/conf/socks.go | 5 ++- infra/conf/transport_authenticators.go | 19 +++++----- infra/conf/transport_internet.go | 45 ++++++++++++----------- infra/conf/trojan.go | 13 ++++--- infra/conf/vless.go | 3 +- infra/conf/vmess.go | 3 +- infra/conf/xray.go | 21 ++++++----- 16 files changed, 121 insertions(+), 143 deletions(-) rename infra/conf/{common => }/common.go (99%) delete mode 100644 infra/conf/common/errors.generated.go rename infra/conf/{common => }/common_test.go (85%) diff --git a/infra/conf/common/common.go b/infra/conf/common.go similarity index 99% rename from infra/conf/common/common.go rename to infra/conf/common.go index a24543899e4d..dea4e06b804c 100644 --- a/infra/conf/common/common.go +++ b/infra/conf/common.go @@ -1,4 +1,4 @@ -package common +package conf import ( "encoding/json" diff --git a/infra/conf/common/errors.generated.go b/infra/conf/common/errors.generated.go deleted file mode 100644 index 28b9a625522c..000000000000 --- a/infra/conf/common/errors.generated.go +++ /dev/null @@ -1,9 +0,0 @@ -package common - -import "github.com/xtls/xray-core/common/errors" - -type errPathObjHolder struct{} - -func newError(values ...interface{}) *errors.Error { - return errors.New(values...).WithPathObj(errPathObjHolder{}) -} diff --git a/infra/conf/common/common_test.go b/infra/conf/common_test.go similarity index 85% rename from infra/conf/common/common_test.go rename to infra/conf/common_test.go index 6bc73c931435..4a49de24d703 100644 --- a/infra/conf/common/common_test.go +++ b/infra/conf/common_test.go @@ -1,7 +1,8 @@ -package common_test +package conf_test import ( "encoding/json" + "github.com/xtls/xray-core/infra/conf" "os" "testing" @@ -11,12 +12,11 @@ import ( "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/protocol" - . "github.com/xtls/xray-core/infra/conf/common" ) func TestStringListUnmarshalError(t *testing.T) { rawJSON := `1234` - list := new(StringList) + list := new(conf.StringList) err := json.Unmarshal([]byte(rawJSON), list) if err == nil { t.Error("expected error, but got nil") @@ -25,7 +25,7 @@ func TestStringListUnmarshalError(t *testing.T) { func TestStringListLen(t *testing.T) { rawJSON := `"a, b, c, d"` - var list StringList + var list conf.StringList err := json.Unmarshal([]byte(rawJSON), &list) common.Must(err) if r := cmp.Diff([]string(list), []string{"a", " b", " c", " d"}); r != "" { @@ -35,7 +35,7 @@ func TestStringListLen(t *testing.T) { func TestIPParsing(t *testing.T) { rawJSON := "\"8.8.8.8\"" - var address Address + var address conf.Address err := json.Unmarshal([]byte(rawJSON), &address) common.Must(err) if r := cmp.Diff(address.IP(), net.IP{8, 8, 8, 8}); r != "" { @@ -45,7 +45,7 @@ func TestIPParsing(t *testing.T) { func TestDomainParsing(t *testing.T) { rawJSON := "\"example.com\"" - var address Address + var address conf.Address common.Must(json.Unmarshal([]byte(rawJSON), &address)) if address.Domain() != "example.com" { t.Error("domain: ", address.Domain()) @@ -55,7 +55,7 @@ func TestDomainParsing(t *testing.T) { func TestURLParsing(t *testing.T) { { rawJSON := "\"https://dns.google/dns-query\"" - var address Address + var address conf.Address common.Must(json.Unmarshal([]byte(rawJSON), &address)) if address.Domain() != "https://dns.google/dns-query" { t.Error("URL: ", address.Domain()) @@ -63,7 +63,7 @@ func TestURLParsing(t *testing.T) { } { rawJSON := "\"https+local://dns.google/dns-query\"" - var address Address + var address conf.Address common.Must(json.Unmarshal([]byte(rawJSON), &address)) if address.Domain() != "https+local://dns.google/dns-query" { t.Error("URL: ", address.Domain()) @@ -73,7 +73,7 @@ func TestURLParsing(t *testing.T) { func TestInvalidAddressJson(t *testing.T) { rawJSON := "1234" - var address Address + var address conf.Address err := json.Unmarshal([]byte(rawJSON), &address) if err == nil { t.Error("nil error") @@ -81,7 +81,7 @@ func TestInvalidAddressJson(t *testing.T) { } func TestStringNetwork(t *testing.T) { - var network Network + var network conf.Network common.Must(json.Unmarshal([]byte(`"tcp"`), &network)) if v := network.Build(); v != net.Network_TCP { t.Error("network: ", v) @@ -89,7 +89,7 @@ func TestStringNetwork(t *testing.T) { } func TestArrayNetworkList(t *testing.T) { - var list NetworkList + var list conf.NetworkList common.Must(json.Unmarshal([]byte("[\"Tcp\"]"), &list)) nlist := list.Build() @@ -102,7 +102,7 @@ func TestArrayNetworkList(t *testing.T) { } func TestStringNetworkList(t *testing.T) { - var list NetworkList + var list conf.NetworkList common.Must(json.Unmarshal([]byte("\"TCP, ip\""), &list)) nlist := list.Build() @@ -115,7 +115,7 @@ func TestStringNetworkList(t *testing.T) { } func TestInvalidNetworkJson(t *testing.T) { - var list NetworkList + var list conf.NetworkList err := json.Unmarshal([]byte("0"), &list) if err == nil { t.Error("nil error") @@ -123,10 +123,10 @@ func TestInvalidNetworkJson(t *testing.T) { } func TestIntPort(t *testing.T) { - var portRange PortRange + var portRange conf.PortRange common.Must(json.Unmarshal([]byte("1234"), &portRange)) - if r := cmp.Diff(portRange, PortRange{ + if r := cmp.Diff(portRange, conf.PortRange{ From: 1234, To: 1234, }); r != "" { t.Error(r) @@ -134,7 +134,7 @@ func TestIntPort(t *testing.T) { } func TestOverRangeIntPort(t *testing.T) { - var portRange PortRange + var portRange conf.PortRange err := json.Unmarshal([]byte("70000"), &portRange) if err == nil { t.Error("nil error") @@ -149,10 +149,10 @@ func TestOverRangeIntPort(t *testing.T) { func TestEnvPort(t *testing.T) { common.Must(os.Setenv("PORT", "1234")) - var portRange PortRange + var portRange conf.PortRange common.Must(json.Unmarshal([]byte("\"env:PORT\""), &portRange)) - if r := cmp.Diff(portRange, PortRange{ + if r := cmp.Diff(portRange, conf.PortRange{ From: 1234, To: 1234, }); r != "" { t.Error(r) @@ -160,10 +160,10 @@ func TestEnvPort(t *testing.T) { } func TestSingleStringPort(t *testing.T) { - var portRange PortRange + var portRange conf.PortRange common.Must(json.Unmarshal([]byte("\"1234\""), &portRange)) - if r := cmp.Diff(portRange, PortRange{ + if r := cmp.Diff(portRange, conf.PortRange{ From: 1234, To: 1234, }); r != "" { t.Error(r) @@ -171,10 +171,10 @@ func TestSingleStringPort(t *testing.T) { } func TestStringPairPort(t *testing.T) { - var portRange PortRange + var portRange conf.PortRange common.Must(json.Unmarshal([]byte("\"1234-5678\""), &portRange)) - if r := cmp.Diff(portRange, PortRange{ + if r := cmp.Diff(portRange, conf.PortRange{ From: 1234, To: 5678, }); r != "" { t.Error(r) @@ -182,7 +182,7 @@ func TestStringPairPort(t *testing.T) { } func TestOverRangeStringPort(t *testing.T) { - var portRange PortRange + var portRange conf.PortRange err := json.Unmarshal([]byte("\"65536\""), &portRange) if err == nil { t.Error("nil error") @@ -205,7 +205,7 @@ func TestOverRangeStringPort(t *testing.T) { } func TestUserParsing(t *testing.T) { - user := new(User) + user := new(conf.User) common.Must(json.Unmarshal([]byte(`{ "id": "96edb838-6d68-42ef-a933-25f7ac3a9d09", "email": "love@example.com", @@ -223,7 +223,7 @@ func TestUserParsing(t *testing.T) { } func TestInvalidUserJson(t *testing.T) { - user := new(User) + user := new(conf.User) err := json.Unmarshal([]byte(`{"email": 1234}`), user) if err == nil { t.Error("nil error") diff --git a/infra/conf/dns.go b/infra/conf/dns.go index 9a70e3e82ec5..b192c5e5f879 100644 --- a/infra/conf/dns.go +++ b/infra/conf/dns.go @@ -12,28 +12,27 @@ import ( "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/matcher/geosite" "github.com/xtls/xray-core/common/net" - "github.com/xtls/xray-core/infra/conf/common" ) type NameServerConfig struct { - Address *common.Address + Address *Address Port uint16 Domains []string - ExpectIPs common.StringList + ExpectIPs StringList } func (c *NameServerConfig) UnmarshalJSON(data []byte) error { - var address common.Address + var address Address if err := json.Unmarshal(data, &address); err == nil { c.Address = &address return nil } var advanced struct { - Address *common.Address `json:"address"` - Port uint16 `json:"port"` - Domains []string `json:"domains"` - ExpectIPs common.StringList `json:"expectIps"` + Address *Address `json:"address"` + Port uint16 `json:"port"` + Domains []string `json:"domains"` + ExpectIPs StringList `json:"expectIps"` } if err := json.Unmarshal(data, &advanced); err == nil { c.Address = advanced.Address @@ -91,15 +90,15 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) { // DNSConfig is a JSON serializable object for dns.Config. type DNSConfig struct { - Servers []*NameServerConfig `json:"servers"` - Hosts map[string]*common.Address `json:"hosts"` - ClientIP *common.Address `json:"clientIp"` - Tag string `json:"tag"` - QueryStrategy string `json:"queryStrategy"` - DisableCache bool `json:"disableCache"` + Servers []*NameServerConfig `json:"servers"` + Hosts map[string]*Address `json:"hosts"` + ClientIP *Address `json:"clientIp"` + Tag string `json:"tag"` + QueryStrategy string `json:"queryStrategy"` + DisableCache bool `json:"disableCache"` } -func getHostMapping(addr *common.Address) *dns.Config_HostMapping { +func getHostMapping(addr *Address) *dns.Config_HostMapping { if addr.Family().IsIP() { return &dns.Config_HostMapping{ Ip: [][]byte{[]byte(addr.IP())}, diff --git a/infra/conf/dns_proxy.go b/infra/conf/dns_proxy.go index 4b1f3b915401..922d32bafcae 100644 --- a/infra/conf/dns_proxy.go +++ b/infra/conf/dns_proxy.go @@ -3,14 +3,13 @@ package conf import ( "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/net" - "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/dns" ) type DNSOutboundConfig struct { - Network common.Network `json:"network"` - Address *common.Address `json:"address"` - Port uint16 `json:"port"` + Network Network `json:"network"` + Address *Address `json:"address"` + Port uint16 `json:"port"` } func (c *DNSOutboundConfig) Build() (proto.Message, error) { diff --git a/infra/conf/dokodemo.go b/infra/conf/dokodemo.go index c5b42e657f0d..03a21d71192f 100644 --- a/infra/conf/dokodemo.go +++ b/infra/conf/dokodemo.go @@ -2,17 +2,16 @@ package conf import ( "github.com/golang/protobuf/proto" - "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/dokodemo" ) type DokodemoConfig struct { - Host *common.Address `json:"address"` - PortValue uint16 `json:"port"` - NetworkList *common.NetworkList `json:"network"` - TimeoutValue uint32 `json:"timeout"` - Redirect bool `json:"followRedirect"` - UserLevel uint32 `json:"userLevel"` + Host *Address `json:"address"` + PortValue uint16 `json:"port"` + NetworkList *NetworkList `json:"network"` + TimeoutValue uint32 `json:"timeout"` + Redirect bool `json:"followRedirect"` + UserLevel uint32 `json:"userLevel"` } func (v *DokodemoConfig) Build() (proto.Message, error) { diff --git a/infra/conf/http.go b/infra/conf/http.go index ebaaa7fdf723..e6969582b7e6 100644 --- a/infra/conf/http.go +++ b/infra/conf/http.go @@ -6,7 +6,6 @@ import ( "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" - "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/http" ) @@ -47,7 +46,7 @@ func (c *HTTPServerConfig) Build() (proto.Message, error) { } type HTTPRemoteConfig struct { - Address *common.Address `json:"address"` + Address *Address `json:"address"` Port uint16 `json:"port"` Users []json.RawMessage `json:"users"` } diff --git a/infra/conf/router.go b/infra/conf/router.go index 504632677115..ae2ffd50e47a 100644 --- a/infra/conf/router.go +++ b/infra/conf/router.go @@ -10,7 +10,6 @@ import ( "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/matcher/geosite" "github.com/xtls/xray-core/common/net" - "github.com/xtls/xray-core/infra/conf/common" ) type RouterRulesConfig struct { @@ -19,8 +18,8 @@ type RouterRulesConfig struct { } type BalancingRule struct { - Tag string `json:"tag"` - Selectors common.StringList `json:"selector"` + Tag string `json:"tag"` + Selectors StringList `json:"selector"` } func (r *BalancingRule) Build() (*router.BalancingRule, error) { @@ -151,17 +150,17 @@ func ParseIP(s string) (*geoip.CIDR, error) { func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { type RawFieldRule struct { RouterRule - Domain *common.StringList `json:"domain"` - Domains *common.StringList `json:"domains"` - IP *common.StringList `json:"ip"` - Port *common.PortList `json:"port"` - Network *common.NetworkList `json:"network"` - SourceIP *common.StringList `json:"source"` - SourcePort *common.PortList `json:"sourcePort"` - User *common.StringList `json:"user"` - InboundTag *common.StringList `json:"inboundTag"` - Protocols *common.StringList `json:"protocol"` - Attributes string `json:"attrs"` + Domain *StringList `json:"domain"` + Domains *StringList `json:"domains"` + IP *StringList `json:"ip"` + Port *PortList `json:"port"` + Network *NetworkList `json:"network"` + SourceIP *StringList `json:"source"` + SourcePort *PortList `json:"sourcePort"` + User *StringList `json:"user"` + InboundTag *StringList `json:"inboundTag"` + Protocols *StringList `json:"protocol"` + Attributes string `json:"attrs"` } rawFieldRule := new(RawFieldRule) err := json.Unmarshal(msg, rawFieldRule) diff --git a/infra/conf/shadowsocks.go b/infra/conf/shadowsocks.go index f5b4305d938a..fbb2a79d583a 100644 --- a/infra/conf/shadowsocks.go +++ b/infra/conf/shadowsocks.go @@ -7,7 +7,6 @@ import ( "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" - "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/shadowsocks" ) @@ -47,7 +46,7 @@ type ShadowsocksServerConfig struct { Level byte `json:"level"` Email string `json:"email"` Users []*ShadowsocksUserConfig `json:"clients"` - NetworkList *common.NetworkList `json:"network"` + NetworkList *NetworkList `json:"network"` } func (v *ShadowsocksServerConfig) Build() (proto.Message, error) { @@ -94,12 +93,12 @@ func (v *ShadowsocksServerConfig) Build() (proto.Message, error) { } type ShadowsocksServerTarget struct { - Address *common.Address `json:"address"` - Port uint16 `json:"port"` - Cipher string `json:"method"` - Password string `json:"password"` - Email string `json:"email"` - Level byte `json:"level"` + Address *Address `json:"address"` + Port uint16 `json:"port"` + Cipher string `json:"method"` + Password string `json:"password"` + Email string `json:"email"` + Level byte `json:"level"` } type ShadowsocksClientConfig struct { diff --git a/infra/conf/socks.go b/infra/conf/socks.go index 61d8295e6bbe..05dad7bc18fb 100644 --- a/infra/conf/socks.go +++ b/infra/conf/socks.go @@ -6,7 +6,6 @@ import ( "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" - "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/socks" ) @@ -31,7 +30,7 @@ type SocksServerConfig struct { AuthMethod string `json:"auth"` Accounts []*SocksAccount `json:"accounts"` UDP bool `json:"udp"` - Host *common.Address `json:"ip"` + Host *Address `json:"ip"` Timeout uint32 `json:"timeout"` UserLevel uint32 `json:"userLevel"` } @@ -66,7 +65,7 @@ func (v *SocksServerConfig) Build() (proto.Message, error) { } type SocksRemoteConfig struct { - Address *common.Address `json:"address"` + Address *Address `json:"address"` Port uint16 `json:"port"` Users []json.RawMessage `json:"users"` } diff --git a/infra/conf/transport_authenticators.go b/infra/conf/transport_authenticators.go index f0ddffe3d3fd..c9e42605b10d 100644 --- a/infra/conf/transport_authenticators.go +++ b/infra/conf/transport_authenticators.go @@ -5,7 +5,6 @@ import ( "github.com/golang/protobuf/proto" - "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/transport/internet/headers/http" "github.com/xtls/xray-core/transport/internet/headers/noop" "github.com/xtls/xray-core/transport/internet/headers/srtp" @@ -58,13 +57,13 @@ func (DTLSAuthenticator) Build() (proto.Message, error) { } type AuthenticatorRequest struct { - Version string `json:"version"` - Method string `json:"method"` - Path common.StringList `json:"path"` - Headers map[string]*common.StringList `json:"headers"` + Version string `json:"version"` + Method string `json:"method"` + Path StringList `json:"path"` + Headers map[string]*StringList `json:"headers"` } -func sortMapKeys(m map[string]*common.StringList) []string { +func sortMapKeys(m map[string]*StringList) []string { var keys []string for key := range m { keys = append(keys, key) @@ -134,10 +133,10 @@ func (v *AuthenticatorRequest) Build() (*http.RequestConfig, error) { } type AuthenticatorResponse struct { - Version string `json:"version"` - Status string `json:"status"` - Reason string `json:"reason"` - Headers map[string]*common.StringList `json:"headers"` + Version string `json:"version"` + Status string `json:"status"` + Reason string `json:"reason"` + Headers map[string]*StringList `json:"headers"` } func (v *AuthenticatorResponse) Build() (*http.ResponseConfig, error) { diff --git a/infra/conf/transport_internet.go b/infra/conf/transport_internet.go index 9e929e97bddf..15d5dd3257d3 100644 --- a/infra/conf/transport_internet.go +++ b/infra/conf/transport_internet.go @@ -11,7 +11,6 @@ import ( "github.com/xtls/xray-core/common/platform/filesystem" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" - "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/transport/internet" "github.com/xtls/xray-core/transport/internet/domainsocket" "github.com/xtls/xray-core/transport/internet/http" @@ -180,8 +179,8 @@ func (c *WebSocketConfig) Build() (proto.Message, error) { } type HTTPConfig struct { - Host *common.StringList `json:"host"` - Path string `json:"path"` + Host *StringList `json:"host"` + Path string `json:"path"` } // Build implements Buildable. @@ -312,16 +311,16 @@ func (c *TLSCertConfig) Build() (*tls.Certificate, error) { } type TLSConfig struct { - Insecure bool `json:"allowInsecure"` - Certs []*TLSCertConfig `json:"certificates"` - ServerName string `json:"serverName"` - ALPN *common.StringList `json:"alpn"` - EnableSessionResumption bool `json:"enableSessionResumption"` - DisableSystemRoot bool `json:"disableSystemRoot"` - MinVersion string `json:"minVersion"` - MaxVersion string `json:"maxVersion"` - CipherSuites string `json:"cipherSuites"` - PreferServerCipherSuites bool `json:"preferServerCipherSuites"` + Insecure bool `json:"allowInsecure"` + Certs []*TLSCertConfig `json:"certificates"` + ServerName string `json:"serverName"` + ALPN *StringList `json:"alpn"` + EnableSessionResumption bool `json:"enableSessionResumption"` + DisableSystemRoot bool `json:"disableSystemRoot"` + MinVersion string `json:"minVersion"` + MaxVersion string `json:"maxVersion"` + CipherSuites string `json:"cipherSuites"` + PreferServerCipherSuites bool `json:"preferServerCipherSuites"` } // Build implements Buildable. @@ -402,16 +401,16 @@ func (c *XTLSCertConfig) Build() (*xtls.Certificate, error) { } type XTLSConfig struct { - Insecure bool `json:"allowInsecure"` - Certs []*XTLSCertConfig `json:"certificates"` - ServerName string `json:"serverName"` - ALPN *common.StringList `json:"alpn"` - EnableSessionResumption bool `json:"enableSessionResumption"` - DisableSystemRoot bool `json:"disableSystemRoot"` - MinVersion string `json:"minVersion"` - MaxVersion string `json:"maxVersion"` - CipherSuites string `json:"cipherSuites"` - PreferServerCipherSuites bool `json:"preferServerCipherSuites"` + Insecure bool `json:"allowInsecure"` + Certs []*XTLSCertConfig `json:"certificates"` + ServerName string `json:"serverName"` + ALPN *StringList `json:"alpn"` + EnableSessionResumption bool `json:"enableSessionResumption"` + DisableSystemRoot bool `json:"disableSystemRoot"` + MinVersion string `json:"minVersion"` + MaxVersion string `json:"maxVersion"` + CipherSuites string `json:"cipherSuites"` + PreferServerCipherSuites bool `json:"preferServerCipherSuites"` } // Build implements Buildable. diff --git a/infra/conf/trojan.go b/infra/conf/trojan.go index 0a71e24388d6..4fe96c071585 100644 --- a/infra/conf/trojan.go +++ b/infra/conf/trojan.go @@ -11,18 +11,17 @@ import ( "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" - "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/trojan" ) // TrojanServerTarget is configuration of a single trojan server type TrojanServerTarget struct { - Address *common.Address `json:"address"` - Port uint16 `json:"port"` - Password string `json:"password"` - Email string `json:"email"` - Level byte `json:"level"` - Flow string `json:"flow"` + Address *Address `json:"address"` + Port uint16 `json:"port"` + Password string `json:"password"` + Email string `json:"email"` + Level byte `json:"level"` + Flow string `json:"flow"` } // TrojanClientConfig is configuration of trojan servers diff --git a/infra/conf/vless.go b/infra/conf/vless.go index c7a07fb29332..f5ded7a00607 100644 --- a/infra/conf/vless.go +++ b/infra/conf/vless.go @@ -12,7 +12,6 @@ import ( "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/common/uuid" - "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/vless" "github.com/xtls/xray-core/proxy/vless/inbound" "github.com/xtls/xray-core/proxy/vless/outbound" @@ -138,7 +137,7 @@ func (c *VLessInboundConfig) Build() (proto.Message, error) { } type VLessOutboundVnext struct { - Address *common.Address `json:"address"` + Address *Address `json:"address"` Port uint16 `json:"port"` Users []json.RawMessage `json:"users"` } diff --git a/infra/conf/vmess.go b/infra/conf/vmess.go index 9670dc299db3..1200be07047a 100644 --- a/infra/conf/vmess.go +++ b/infra/conf/vmess.go @@ -9,7 +9,6 @@ import ( "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/common/uuid" - "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/proxy/vmess" "github.com/xtls/xray-core/proxy/vmess/inbound" "github.com/xtls/xray-core/proxy/vmess/outbound" @@ -124,7 +123,7 @@ func (c *VMessInboundConfig) Build() (proto.Message, error) { } type VMessOutboundTarget struct { - Address *common.Address `json:"address"` + Address *Address `json:"address"` Port uint16 `json:"port"` Users []json.RawMessage `json:"users"` } diff --git a/infra/conf/xray.go b/infra/conf/xray.go index 02561c5eef37..1f89ebad209e 100644 --- a/infra/conf/xray.go +++ b/infra/conf/xray.go @@ -15,7 +15,6 @@ import ( "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/serial" core "github.com/xtls/xray-core/core" - "github.com/xtls/xray-core/infra/conf/common" "github.com/xtls/xray-core/transport/internet" "github.com/xtls/xray-core/transport/internet/xtls" ) @@ -64,11 +63,11 @@ func toProtocolList(s []string) ([]proxyman.KnownProtocols, error) { } type SniffingConfig struct { - Enabled bool `json:"enabled"` - DestOverride *common.StringList `json:"destOverride"` - DomainsExcluded *common.StringList `json:"domainsExcluded"` - IPsExcluded *common.StringList `json:"ipsExcluded"` - MetadataOnly bool `json:"metadataOnly"` + Enabled bool `json:"enabled"` + DestOverride *StringList `json:"destOverride"` + DomainsExcluded *StringList `json:"domainsExcluded"` + IPsExcluded *StringList `json:"ipsExcluded"` + MetadataOnly bool `json:"metadataOnly"` } // Build implements Buildable. @@ -176,13 +175,13 @@ func (c *InboundDetourAllocationConfig) Build() (*proxyman.AllocationStrategy, e type InboundDetourConfig struct { Protocol string `json:"protocol"` - PortRange *common.PortRange `json:"port"` - ListenOn *common.Address `json:"listen"` + PortRange *PortRange `json:"port"` + ListenOn *Address `json:"listen"` Settings *json.RawMessage `json:"settings"` Tag string `json:"tag"` Allocation *InboundDetourAllocationConfig `json:"allocate"` StreamSetting *StreamConfig `json:"streamSettings"` - DomainOverride *common.StringList `json:"domainOverride"` + DomainOverride *StringList `json:"domainOverride"` SniffingConfig *SniffingConfig `json:"sniffing"` } @@ -284,7 +283,7 @@ func (c *InboundDetourConfig) Build() (*core.InboundHandlerConfig, error) { type OutboundDetourConfig struct { Protocol string `json:"protocol"` - SendThrough *common.Address `json:"sendThrough"` + SendThrough *Address `json:"sendThrough"` Tag string `json:"tag"` Settings *json.RawMessage `json:"settings"` StreamSetting *StreamConfig `json:"streamSettings"` @@ -642,7 +641,7 @@ func (c *Config) Build() (*core.Config, error) { // Backward compatibility. if len(inbounds) > 0 && inbounds[0].PortRange == nil && c.Port > 0 { - inbounds[0].PortRange = &common.PortRange{ + inbounds[0].PortRange = &PortRange{ From: uint32(c.Port), To: uint32(c.Port), } From 6471cfd290f97e37a62af793f59036c212beec80 Mon Sep 17 00:00:00 2001 From: JimhHan <50871214+JimhHan@users.noreply.github.com> Date: Sat, 27 Mar 2021 16:54:42 +0800 Subject: [PATCH 07/20] Fix: typo --- common/matcher/geoip/conf.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/matcher/geoip/conf.go b/common/matcher/geoip/conf.go index e7d89ac65179..9c5fa42b7eea 100644 --- a/common/matcher/geoip/conf.go +++ b/common/matcher/geoip/conf.go @@ -16,7 +16,7 @@ var ( ) func LoadGeoIP(code string) ([]*CIDR, error) { - return LoadIPFile("dat", code) + return LoadIPFile("geoip.dat", code) } func LoadIPFile(file, code string) ([]*CIDR, error) { From b8196a22a0ebdd3e66da846d019014c9b468e698 Mon Sep 17 00:00:00 2001 From: JimhHan <50871214+JimhHan@users.noreply.github.com> Date: Sat, 27 Mar 2021 17:41:46 +0800 Subject: [PATCH 08/20] Fix: matching type mismatch --- common/matcher/geosite/geosite.go | 16 +++- common/matcher/geosite/geosite.pb.go | 128 +++++++++++++++++++-------- common/matcher/geosite/geosite.proto | 14 ++- 3 files changed, 119 insertions(+), 39 deletions(-) diff --git a/common/matcher/geosite/geosite.go b/common/matcher/geosite/geosite.go index 47480e5c89d5..4693f56bce4d 100644 --- a/common/matcher/geosite/geosite.go +++ b/common/matcher/geosite/geosite.go @@ -15,5 +15,19 @@ func ToDomains(dms []*Domain) []*domain.Domain { } func (d *Domain) ToDomain() *domain.Domain { - return &domain.Domain{Type: d.Type, Value: d.Value} + return &domain.Domain{Type: d.Type.ToMatchingType(), Value: d.Value} +} + +func (t Domain_Type) ToMatchingType() domain.MatchingType { + switch t { + case Domain_Plain: + return domain.MatchingType_Keyword + case Domain_Regex: + return domain.MatchingType_Regex + case Domain_Domain: + return domain.MatchingType_Subdomain + case Domain_Full: + return domain.MatchingType_Full + } + panic("impossible") } diff --git a/common/matcher/geosite/geosite.pb.go b/common/matcher/geosite/geosite.pb.go index d8d166980c81..a0cd2ff5fb4c 100644 --- a/common/matcher/geosite/geosite.pb.go +++ b/common/matcher/geosite/geosite.pb.go @@ -8,7 +8,6 @@ package geosite import ( proto "github.com/golang/protobuf/proto" - domain "github.com/xtls/xray-core/common/matcher/domain" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -26,13 +25,69 @@ const ( // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 +type Domain_Type int32 + +const ( + // The value is used as is. + Domain_Plain Domain_Type = 0 + // The value is used as a regular expression. + Domain_Regex Domain_Type = 1 + // The value is a root domain. + Domain_Domain Domain_Type = 2 + // The value is a domain. + Domain_Full Domain_Type = 3 +) + +// Enum value maps for Domain_Type. +var ( + Domain_Type_name = map[int32]string{ + 0: "Plain", + 1: "Regex", + 2: "Domain", + 3: "Full", + } + Domain_Type_value = map[string]int32{ + "Plain": 0, + "Regex": 1, + "Domain": 2, + "Full": 3, + } +) + +func (x Domain_Type) Enum() *Domain_Type { + p := new(Domain_Type) + *p = x + return p +} + +func (x Domain_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Domain_Type) Descriptor() protoreflect.EnumDescriptor { + return file_common_matcher_geosite_geosite_proto_enumTypes[0].Descriptor() +} + +func (Domain_Type) Type() protoreflect.EnumType { + return &file_common_matcher_geosite_geosite_proto_enumTypes[0] +} + +func (x Domain_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Domain_Type.Descriptor instead. +func (Domain_Type) EnumDescriptor() ([]byte, []int) { + return file_common_matcher_geosite_geosite_proto_rawDescGZIP(), []int{0, 0} +} + type Domain struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Domain matching type. - Type domain.MatchingType `protobuf:"varint,1,opt,name=type,proto3,enum=xray.common.matcher.domain.MatchingType" json:"type,omitempty"` + Type Domain_Type `protobuf:"varint,1,opt,name=type,proto3,enum=xray.common.matcher.geosite.Domain_Type" json:"type,omitempty"` // Domain value. Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` // Attributes of this domain. May be used for filtering. @@ -71,11 +126,11 @@ func (*Domain) Descriptor() ([]byte, []int) { return file_common_matcher_geosite_geosite_proto_rawDescGZIP(), []int{0} } -func (x *Domain) GetType() domain.MatchingType { +func (x *Domain) GetType() Domain_Type { if x != nil { return x.Type } - return domain.MatchingType_Full + return Domain_Plain } func (x *Domain) GetValue() string { @@ -289,27 +344,28 @@ var file_common_matcher_geosite_geosite_proto_rawDesc = []byte{ 0x2f, 0x67, 0x65, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x2f, 0x67, 0x65, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x73, - 0x69, 0x74, 0x65, 0x1a, 0x22, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x74, 0x63, - 0x68, 0x65, 0x72, 0x2f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x64, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x97, 0x02, 0x0a, 0x06, 0x44, 0x6f, 0x6d, 0x61, - 0x69, 0x6e, 0x12, 0x3c, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x28, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, - 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4b, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x78, 0x72, 0x61, 0x79, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, - 0x67, 0x65, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x1a, 0x6c, 0x0a, 0x09, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x1d, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x42, 0x0d, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x22, 0x69, 0x0a, 0x07, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x69, 0x74, 0x65, 0x22, 0xcb, 0x02, 0x0a, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3c, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x78, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x4b, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x73, + 0x69, 0x74, 0x65, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x1a, + 0x6c, 0x0a, 0x09, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1f, + 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x1d, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0d, + 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x32, 0x0a, + 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x10, 0x00, + 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, + 0x03, 0x22, 0x69, 0x0a, 0x07, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, @@ -343,19 +399,20 @@ func file_common_matcher_geosite_geosite_proto_rawDescGZIP() []byte { return file_common_matcher_geosite_geosite_proto_rawDescData } +var file_common_matcher_geosite_geosite_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_common_matcher_geosite_geosite_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_common_matcher_geosite_geosite_proto_goTypes = []interface{}{ - (*Domain)(nil), // 0: xray.common.matcher.geosite.Domain - (*GeoSite)(nil), // 1: xray.common.matcher.geosite.GeoSite - (*GeoSiteList)(nil), // 2: xray.common.matcher.geosite.GeoSiteList - (*Domain_Attribute)(nil), // 3: xray.common.matcher.geosite.Domain.Attribute - (domain.MatchingType)(0), // 4: xray.common.matcher.domain.MatchingType + (Domain_Type)(0), // 0: xray.common.matcher.geosite.Domain.Type + (*Domain)(nil), // 1: xray.common.matcher.geosite.Domain + (*GeoSite)(nil), // 2: xray.common.matcher.geosite.GeoSite + (*GeoSiteList)(nil), // 3: xray.common.matcher.geosite.GeoSiteList + (*Domain_Attribute)(nil), // 4: xray.common.matcher.geosite.Domain.Attribute } var file_common_matcher_geosite_geosite_proto_depIdxs = []int32{ - 4, // 0: xray.common.matcher.geosite.Domain.type:type_name -> xray.common.matcher.domain.MatchingType - 3, // 1: xray.common.matcher.geosite.Domain.attribute:type_name -> xray.common.matcher.geosite.Domain.Attribute - 0, // 2: xray.common.matcher.geosite.GeoSite.domain:type_name -> xray.common.matcher.geosite.Domain - 1, // 3: xray.common.matcher.geosite.GeoSiteList.entry:type_name -> xray.common.matcher.geosite.GeoSite + 0, // 0: xray.common.matcher.geosite.Domain.type:type_name -> xray.common.matcher.geosite.Domain.Type + 4, // 1: xray.common.matcher.geosite.Domain.attribute:type_name -> xray.common.matcher.geosite.Domain.Attribute + 1, // 2: xray.common.matcher.geosite.GeoSite.domain:type_name -> xray.common.matcher.geosite.Domain + 2, // 3: xray.common.matcher.geosite.GeoSiteList.entry:type_name -> xray.common.matcher.geosite.GeoSite 4, // [4:4] is the sub-list for method output_type 4, // [4:4] is the sub-list for method input_type 4, // [4:4] is the sub-list for extension type_name @@ -427,13 +484,14 @@ func file_common_matcher_geosite_geosite_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_common_matcher_geosite_geosite_proto_rawDesc, - NumEnums: 0, + NumEnums: 1, NumMessages: 4, NumExtensions: 0, NumServices: 0, }, GoTypes: file_common_matcher_geosite_geosite_proto_goTypes, DependencyIndexes: file_common_matcher_geosite_geosite_proto_depIdxs, + EnumInfos: file_common_matcher_geosite_geosite_proto_enumTypes, MessageInfos: file_common_matcher_geosite_geosite_proto_msgTypes, }.Build() File_common_matcher_geosite_geosite_proto = out.File diff --git a/common/matcher/geosite/geosite.proto b/common/matcher/geosite/geosite.proto index 3a5816567b68..8a8e055f63f4 100644 --- a/common/matcher/geosite/geosite.proto +++ b/common/matcher/geosite/geosite.proto @@ -6,11 +6,19 @@ option go_package = "github.com/xtls/xray-core/common/matcher/geosite"; option java_package = "com.xray.common.matcher.geosite"; option java_multiple_files = true; -import "common/matcher/domain/domain.proto"; - message Domain { + enum Type { + // The value is used as is. + Plain = 0; + // The value is used as a regular expression. + Regex = 1; + // The value is a root domain. + Domain = 2; + // The value is a domain. + Full = 3; + } // Domain matching type. - xray.common.matcher.domain.MatchingType type = 1; + Type type = 1; // Domain value. string value = 2; From b9c5de96e71a0f109c8adb05de83c4f155a3645e Mon Sep 17 00:00:00 2001 From: JimhHan <50871214+JimhHan@users.noreply.github.com> Date: Sat, 27 Mar 2021 17:52:15 +0800 Subject: [PATCH 09/20] Fix: test --- infra/conf/dns_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/conf/dns_test.go b/infra/conf/dns_test.go index cc1779afa9f2..aeb1df39629b 100644 --- a/infra/conf/dns_test.go +++ b/infra/conf/dns_test.go @@ -36,7 +36,7 @@ func init() { { CountryCode: "TEST", Domain: []*geosite.Domain{ - {Type: domain.MatchingType_Full, Value: "example.com"}, + {Type: geosite.Domain_Full, Value: "example.com"}, }, }, }, From 946a7a2647d93acd88a472f1b1ab2f67992e803b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E3=81=AE=E3=81=8B=E3=81=88=E3=81=A7?= <autmaple@protonmail.com> Date: Wed, 7 Apr 2021 22:53:21 +0800 Subject: [PATCH 10/20] Refine DomainStrategy config --- infra/conf/router.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/infra/conf/router.go b/infra/conf/router.go index ae2ffd50e47a..1e005bf257ca 100644 --- a/infra/conf/router.go +++ b/infra/conf/router.go @@ -52,11 +52,11 @@ func (c *RouterConfig) getDomainStrategy() router.Config_DomainStrategy { } switch strings.ToLower(ds) { - case "alwaysip": + case "alwaysip", "always_ip", "always-ip": return router.Config_UseIp - case "ipifnonmatch": + case "ipifnonmatch", "ip_if_non_match", "ip-if-non-match": return router.Config_IpIfNonMatch - case "ipondemand": + case "ipondemand", "ip_on_demand", "ip-on-demand": return router.Config_IpOnDemand default: return router.Config_AsIs From 68201a88983099fee500e1d4acc7cff4bde36136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E3=81=AE=E3=81=8B=E3=81=88=E3=81=A7?= <autmaple@protonmail.com> Date: Thu, 8 Apr 2021 13:07:53 +0800 Subject: [PATCH 11/20] Feat: add reverse match for GeoIP --- common/matcher/geoip/conf.go | 20 +++++++++--- common/matcher/geoip/geoip.go | 29 +++++++++++++---- common/matcher/geoip/geoip.pb.go | 52 ++++++++++++++++++------------ common/matcher/geoip/geoip.proto | 1 + common/matcher/geoip/geoip_test.go | 36 +++++++++++++++++++++ 5 files changed, 106 insertions(+), 32 deletions(-) diff --git a/common/matcher/geoip/conf.go b/common/matcher/geoip/conf.go index 9c5fa42b7eea..e159534045da 100644 --- a/common/matcher/geoip/conf.go +++ b/common/matcher/geoip/conf.go @@ -99,14 +99,16 @@ func ParaseIPList(ips []string) ([]*GeoIP, error) { for _, ip := range ips { if strings.HasPrefix(ip, "geoip:") { country := ip[6:] + isReverseMatch := false geoipc, err := LoadGeoIP(strings.ToUpper(country)) if err != nil { return nil, newError("failed to load GeoIP: ", country).Base(err) } geoipList = append(geoipList, &GeoIP{ - CountryCode: strings.ToUpper(country), - Cidr: geoipc, + CountryCode: strings.ToUpper(country), + Cidr: geoipc, + ReverseMatch: isReverseMatch, }) continue } @@ -129,14 +131,24 @@ func ParaseIPList(ips []string) ([]*GeoIP, error) { filename := kv[0] country := kv[1] + if len(filename) == 0 || len(country) == 0 { + return nil, newError("empty filename or empty country in rule") + } + + isReverseMatch := false + if strings.HasPrefix(country, "!") { + country = country[1:] + isReverseMatch = true + } geoipc, err := LoadIPFile(filename, strings.ToUpper(country)) if err != nil { return nil, newError("failed to load IPs: ", country, " from ", filename).Base(err) } geoipList = append(geoipList, &GeoIP{ - CountryCode: strings.ToUpper(filename + "_" + country), - Cidr: geoipc, + CountryCode: strings.ToUpper(filename + "_" + country), + Cidr: geoipc, + ReverseMatch: isReverseMatch, }) continue diff --git a/common/matcher/geoip/geoip.go b/common/matcher/geoip/geoip.go index 08eaf26ac538..f702c6824ecb 100644 --- a/common/matcher/geoip/geoip.go +++ b/common/matcher/geoip/geoip.go @@ -15,11 +15,16 @@ type ipv6 struct { } type GeoIPMatcher struct { - countryCode string - ip4 []uint32 - prefix4 []uint8 - ip6 []ipv6 - prefix6 []uint8 + countryCode string + reverseMatch bool + ip4 []uint32 + prefix4 []uint8 + ip6 []ipv6 + prefix6 []uint8 +} + +func (m *GeoIPMatcher) SetReverseMatch(isReverseMatch bool) { + m.reverseMatch = isReverseMatch } func normalize4(ip uint32, prefix uint8) uint32 { @@ -149,8 +154,17 @@ func (m *GeoIPMatcher) match6(ip ipv6) bool { func (m *GeoIPMatcher) Match(ip net.IP) bool { switch len(ip) { case 4: + if m.reverseMatch { + return !m.match4(binary.BigEndian.Uint32(ip)) + } return m.match4(binary.BigEndian.Uint32(ip)) case 16: + if m.reverseMatch { + return !m.match6(ipv6{ + a: binary.BigEndian.Uint64(ip[0:8]), + b: binary.BigEndian.Uint64(ip[8:16]), + }) + } return m.match6(ipv6{ a: binary.BigEndian.Uint64(ip[0:8]), b: binary.BigEndian.Uint64(ip[8:16]), @@ -170,14 +184,15 @@ type GeoIPMatcherContainer struct { func (c *GeoIPMatcherContainer) Add(geoip *GeoIP) (*GeoIPMatcher, error) { if len(geoip.CountryCode) > 0 { for _, m := range c.matchers { - if m.countryCode == geoip.CountryCode { + if m.countryCode == geoip.CountryCode && m.reverseMatch == geoip.ReverseMatch { return m, nil } } } m := &GeoIPMatcher{ - countryCode: geoip.CountryCode, + countryCode: geoip.CountryCode, + reverseMatch: geoip.ReverseMatch, } if err := m.Init(geoip.Cidr); err != nil { return nil, err diff --git a/common/matcher/geoip/geoip.pb.go b/common/matcher/geoip/geoip.pb.go index 4176127ff102..589ccd49214e 100644 --- a/common/matcher/geoip/geoip.pb.go +++ b/common/matcher/geoip/geoip.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 -// protoc v3.15.6 +// protoc v3.15.7 // source: common/matcher/geoip/geoip.proto package geoip @@ -88,8 +88,9 @@ type GeoIP struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - CountryCode string `protobuf:"bytes,1,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"` - Cidr []*CIDR `protobuf:"bytes,2,rep,name=cidr,proto3" json:"cidr,omitempty"` + CountryCode string `protobuf:"bytes,1,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"` + Cidr []*CIDR `protobuf:"bytes,2,rep,name=cidr,proto3" json:"cidr,omitempty"` + ReverseMatch bool `protobuf:"varint,3,opt,name=reverse_match,json=reverseMatch,proto3" json:"reverse_match,omitempty"` } func (x *GeoIP) Reset() { @@ -138,6 +139,13 @@ func (x *GeoIP) GetCidr() []*CIDR { return nil } +func (x *GeoIP) GetReverseMatch() bool { + if x != nil { + return x.ReverseMatch + } + return false +} + type GeoIPList struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -194,25 +202,27 @@ var file_common_matcher_geoip_geoip_proto_rawDesc = []byte{ 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x22, 0x2e, 0x0a, 0x04, 0x43, 0x49, 0x44, 0x52, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0x5f, 0x0a, - 0x05, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, - 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x63, 0x69, 0x64, - 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, - 0x6f, 0x69, 0x70, 0x2e, 0x43, 0x49, 0x44, 0x52, 0x52, 0x04, 0x63, 0x69, 0x64, 0x72, 0x22, 0x43, - 0x0a, 0x09, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x05, 0x65, - 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, - 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, - 0x2e, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x65, 0x6e, - 0x74, 0x72, 0x79, 0x42, 0x6d, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0x84, 0x01, + 0x0a, 0x05, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x63, 0x69, + 0x64, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, - 0x65, 0x6f, 0x69, 0x70, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, - 0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, - 0x2f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0xaa, 0x02, 0x19, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x43, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, - 0x49, 0x50, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x6f, 0x69, 0x70, 0x2e, 0x43, 0x49, 0x44, 0x52, 0x52, 0x04, 0x63, 0x69, 0x64, 0x72, 0x12, + 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x4d, + 0x61, 0x74, 0x63, 0x68, 0x22, 0x43, 0x0a, 0x09, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x4c, 0x69, 0x73, + 0x74, 0x12, 0x36, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x2e, 0x47, 0x65, 0x6f, + 0x49, 0x50, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x6d, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, + 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x72, 0x2e, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, + 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0xaa, 0x02, 0x19, 0x58, + 0x72, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/common/matcher/geoip/geoip.proto b/common/matcher/geoip/geoip.proto index a781ff09504f..d8a28398013b 100644 --- a/common/matcher/geoip/geoip.proto +++ b/common/matcher/geoip/geoip.proto @@ -18,6 +18,7 @@ message CIDR { message GeoIP { string country_code = 1; repeated CIDR cidr = 2; + bool reverse_match =3; } message GeoIPList { diff --git a/common/matcher/geoip/geoip_test.go b/common/matcher/geoip/geoip_test.go index f959b9447809..0e583ff35d31 100644 --- a/common/matcher/geoip/geoip_test.go +++ b/common/matcher/geoip/geoip_test.go @@ -135,6 +135,42 @@ func TestGeoIPMatcher4CN(t *testing.T) { } } +func TestGeoIPReverseMatcher(t *testing.T) { + cidrList := CIDRList{ + {Ip: []byte{8, 8, 8, 8}, Prefix: 32}, + {Ip: []byte{91, 108, 4, 0}, Prefix: 16}, + } + matcher := &GeoIPMatcher{} + matcher.SetReverseMatch(true) // Reverse match + common.Must(matcher.Init(cidrList)) + + testCases := []struct { + Input string + Output bool + }{ + { + Input: "8.8.8.8", + Output: false, + }, + { + Input: "2001:cdba::3257:9652", + Output: true, + }, + { + Input: "91.108.255.254", + Output: false, + }, + } + + for _, testCase := range testCases { + ip := net.ParseAddress(testCase.Input).IP() + actual := matcher.Match(ip) + if actual != testCase.Output { + t.Error("expect input", testCase.Input, "to be", testCase.Output, ", but actually", actual) + } + } +} + func TestGeoIPMatcher6US(t *testing.T) { ips, err := loadGeoIP("US") common.Must(err) From 44317bd657eb1d4beab5fbc9f0f64fd842cce6af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E3=81=AE=E3=81=8B=E3=81=88=E3=81=A7?= <autmaple@protonmail.com> Date: Thu, 8 Apr 2021 13:19:25 +0800 Subject: [PATCH 12/20] Refine router config parse --- common/matcher/domain/conf/domain.go | 24 ++++++++++++++++++++---- common/matcher/geosite/attribute.go | 4 +++- infra/conf/router.go | 6 +++--- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/common/matcher/domain/conf/domain.go b/common/matcher/domain/conf/domain.go index 10a8cf57a25c..524b39bd8799 100644 --- a/common/matcher/domain/conf/domain.go +++ b/common/matcher/domain/conf/domain.go @@ -44,20 +44,36 @@ func ParseDomainRule(domain string) ([]*dm.Domain, error) { domainRule := new(dm.Domain) switch { case strings.HasPrefix(domain, "regexp:"): + regexpVal := domain[7:] + if len(regexpVal) == 0 { + return nil, newError("empty regexp type of rule: ", domain) + } domainRule.Type = dm.MatchingType_Regex - domainRule.Value = domain[7:] + domainRule.Value = regexpVal case strings.HasPrefix(domain, "domain:"): + domainName := domain[7:] + if len(domainName) == 0 { + return nil, newError("empty domain type of rule: ", domain) + } domainRule.Type = dm.MatchingType_Subdomain - domainRule.Value = domain[7:] + domainRule.Value = domainName case strings.HasPrefix(domain, "full:"): + fullVal := domain[5:] + if len(fullVal) == 0 { + return nil, newError("empty full domain type of rule: ", domain) + } domainRule.Type = dm.MatchingType_Full - domainRule.Value = domain[5:] + domainRule.Value = fullVal case strings.HasPrefix(domain, "keyword:"): + keywordVal := domain[8:] + if len(keywordVal) == 0 { + return nil, newError("empty keyword type of rule: ", domain) + } domainRule.Type = dm.MatchingType_Keyword - domainRule.Value = domain[8:] + domainRule.Value = keywordVal case strings.HasPrefix(domain, "dotless:"): domainRule.Type = dm.MatchingType_Regex diff --git a/common/matcher/geosite/attribute.go b/common/matcher/geosite/attribute.go index a16361c169e2..c2fc0b30de12 100644 --- a/common/matcher/geosite/attribute.go +++ b/common/matcher/geosite/attribute.go @@ -1,5 +1,7 @@ package geosite +import "strings" + type AttributeList struct { matcher []AttributeMatcher } @@ -25,7 +27,7 @@ type BooleanMatcher string func (m BooleanMatcher) Match(domain *Domain) bool { for _, attr := range domain.Attribute { - if attr.Key == string(m) { + if strings.EqualFold(attr.GetKey(), string(m)) { return true } } diff --git a/infra/conf/router.go b/infra/conf/router.go index 1e005bf257ca..e905b67232a0 100644 --- a/infra/conf/router.go +++ b/infra/conf/router.go @@ -261,21 +261,21 @@ func ParseRule(msg json.RawMessage) (*router.RoutingRule, error) { if err != nil { return nil, newError("invalid router rule").Base(err) } - if rawRule.Type == "field" { + if strings.EqualFold(rawRule.Type, "field") { fieldrule, err := parseFieldRule(msg) if err != nil { return nil, newError("invalid field rule").Base(err) } return fieldrule, nil } - if rawRule.Type == "chinaip" { + if strings.EqualFold(rawRule.Type, "chinaip") { chinaiprule, err := parseChinaIPRule(msg) if err != nil { return nil, newError("invalid chinaip rule").Base(err) } return chinaiprule, nil } - if rawRule.Type == "chinasites" { + if strings.EqualFold(rawRule.Type, "chinasites") { chinasitesrule, err := parseChinaSitesRule(msg) if err != nil { return nil, newError("invalid chinasites rule").Base(err) From 5d5beb2028b9848c3c1d208b1a058d6c6db6d866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E3=81=AE=E3=81=8B=E3=81=88=E3=81=A7?= <autmaple@protonmail.com> Date: Thu, 8 Apr 2021 13:25:22 +0800 Subject: [PATCH 13/20] Add test to ParaseIPList --- common/matcher/geoip/geoip_test.go | 45 ++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/common/matcher/geoip/geoip_test.go b/common/matcher/geoip/geoip_test.go index 0e583ff35d31..602957823c7f 100644 --- a/common/matcher/geoip/geoip_test.go +++ b/common/matcher/geoip/geoip_test.go @@ -25,6 +25,27 @@ func init() { } } +func TestParaseIPList(t *testing.T) { + t.Log(os.Getenv("xray.location.asset")) + + common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoiptestrouter.dat"), platform.GetAssetLocation("geoip.dat"))) + + ips := []string{ + "geoip:us", + "geoip:cn", + "geoip:!cn", + "ext:geoiptestrouter.dat:!cn", + "ext:geoiptestrouter.dat:ca", + "ext-ip:geoiptestrouter.dat:!cn", + "ext-ip:geoiptestrouter.dat:!ca", + } + + _, err := ParaseIPList(ips) + if err != nil { + t.Fatalf("Failed to parse geoip list, got %s", err) + } +} + func TestGeoIPMatcherContainer(t *testing.T) { container := &GeoIPMatcherContainer{} @@ -123,18 +144,6 @@ func TestGeoIPMatcher(t *testing.T) { } } -func TestGeoIPMatcher4CN(t *testing.T) { - ips, err := loadGeoIP("CN") - common.Must(err) - - matcher := &GeoIPMatcher{} - common.Must(matcher.Init(ips)) - - if matcher.Match([]byte{8, 8, 8, 8}) { - t.Error("expect CN geoip doesn't contain 8.8.8.8, but actually does") - } -} - func TestGeoIPReverseMatcher(t *testing.T) { cidrList := CIDRList{ {Ip: []byte{8, 8, 8, 8}, Prefix: 32}, @@ -171,6 +180,18 @@ func TestGeoIPReverseMatcher(t *testing.T) { } } +func TestGeoIPMatcher4CN(t *testing.T) { + ips, err := loadGeoIP("CN") + common.Must(err) + + matcher := &GeoIPMatcher{} + common.Must(matcher.Init(ips)) + + if matcher.Match([]byte{8, 8, 8, 8}) { + t.Error("expect CN geoip doesn't contain 8.8.8.8, but actually does") + } +} + func TestGeoIPMatcher6US(t *testing.T) { ips, err := loadGeoIP("US") common.Must(err) From 1c3abb2ec3ad72495d61763cbcad87fa6c99e1d7 Mon Sep 17 00:00:00 2001 From: JimhHan <50871214+JimhHan@users.noreply.github.com> Date: Thu, 8 Apr 2021 19:18:23 +0800 Subject: [PATCH 14/20] Fix: config loader --- common/matcher/geoip/conf.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/common/matcher/geoip/conf.go b/common/matcher/geoip/conf.go index e159534045da..5760409ab854 100644 --- a/common/matcher/geoip/conf.go +++ b/common/matcher/geoip/conf.go @@ -100,6 +100,11 @@ func ParaseIPList(ips []string) ([]*GeoIP, error) { if strings.HasPrefix(ip, "geoip:") { country := ip[6:] isReverseMatch := false + if strings.HasPrefix(country, "!") { + country = country[1:] + isReverseMatch = true + } + geoipc, err := LoadGeoIP(strings.ToUpper(country)) if err != nil { return nil, newError("failed to load GeoIP: ", country).Base(err) From 095b17da6208793903d0e51409569b3013804623 Mon Sep 17 00:00:00 2001 From: JimhHan <50871214+JimhHan@users.noreply.github.com> Date: Thu, 8 Apr 2021 19:19:53 +0800 Subject: [PATCH 15/20] Fix typo --- common/matcher/geoip/conf.go | 2 +- common/matcher/geoip/geoip_test.go | 4 ++-- infra/conf/dns.go | 2 +- infra/conf/router.go | 4 ++-- infra/conf/xray.go | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/common/matcher/geoip/conf.go b/common/matcher/geoip/conf.go index 5760409ab854..4a997148e7d9 100644 --- a/common/matcher/geoip/conf.go +++ b/common/matcher/geoip/conf.go @@ -92,7 +92,7 @@ func find(data, code []byte) []byte { } } -func ParaseIPList(ips []string) ([]*GeoIP, error) { +func ParseIPList(ips []string) ([]*GeoIP, error) { var geoipList []*GeoIP var customCidrs []*CIDR diff --git a/common/matcher/geoip/geoip_test.go b/common/matcher/geoip/geoip_test.go index 602957823c7f..b2bee0c4eb16 100644 --- a/common/matcher/geoip/geoip_test.go +++ b/common/matcher/geoip/geoip_test.go @@ -25,7 +25,7 @@ func init() { } } -func TestParaseIPList(t *testing.T) { +func TestParseIPList(t *testing.T) { t.Log(os.Getenv("xray.location.asset")) common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoiptestrouter.dat"), platform.GetAssetLocation("geoip.dat"))) @@ -40,7 +40,7 @@ func TestParaseIPList(t *testing.T) { "ext-ip:geoiptestrouter.dat:!ca", } - _, err := ParaseIPList(ips) + _, err := ParseIPList(ips) if err != nil { t.Fatalf("Failed to parse geoip list, got %s", err) } diff --git a/infra/conf/dns.go b/infra/conf/dns.go index 0cb3b7663754..0e685dc55783 100644 --- a/infra/conf/dns.go +++ b/infra/conf/dns.go @@ -74,7 +74,7 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) { }) } - geoipList, err := geoip.ParaseIPList(c.ExpectIPs) + geoipList, err := geoip.ParseIPList(c.ExpectIPs) if err != nil { return nil, newError("invalid IP rule: ", c.ExpectIPs).Base(err) } diff --git a/infra/conf/router.go b/infra/conf/router.go index e905b67232a0..8a59bddf7949 100644 --- a/infra/conf/router.go +++ b/infra/conf/router.go @@ -203,7 +203,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { } if rawFieldRule.IP != nil { - geoipList, err := geoip.ParaseIPList(*rawFieldRule.IP) + geoipList, err := geoip.ParseIPList(*rawFieldRule.IP) if err != nil { return nil, err } @@ -219,7 +219,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) { } if rawFieldRule.SourceIP != nil { - geoipList, err := geoip.ParaseIPList(*rawFieldRule.SourceIP) + geoipList, err := geoip.ParseIPList(*rawFieldRule.SourceIP) if err != nil { return nil, err } diff --git a/infra/conf/xray.go b/infra/conf/xray.go index 1f89ebad209e..b8b1ba8a96ac 100644 --- a/infra/conf/xray.go +++ b/infra/conf/xray.go @@ -101,7 +101,7 @@ func (c *SniffingConfig) Build() (*proxyman.SniffingConfig, error) { var exIP []*geoip.GeoIP if c.IPsExcluded != nil { - exip, err := geoip.ParaseIPList(*c.IPsExcluded) + exip, err := geoip.ParseIPList(*c.IPsExcluded) if err != nil { return nil, newError("failed to parse excluded ip").Base(err) } From eeb40c9ce2df5390eef75c67cb08507dc1cdb1cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E3=81=AE=E3=81=8B=E3=81=88=E3=81=A7?= <autmaple@protonmail.com> Date: Thu, 8 Apr 2021 22:51:55 +0800 Subject: [PATCH 16/20] Refine tests --- common/matcher/geoip/geoip_test.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/common/matcher/geoip/geoip_test.go b/common/matcher/geoip/geoip_test.go index b2bee0c4eb16..48bc52867ad6 100644 --- a/common/matcher/geoip/geoip_test.go +++ b/common/matcher/geoip/geoip_test.go @@ -5,12 +5,12 @@ import ( "path/filepath" "testing" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common" . "github.com/xtls/xray-core/common/matcher/geoip" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/platform" "github.com/xtls/xray-core/common/platform/filesystem" + "google.golang.org/protobuf/proto" ) func init() { @@ -20,16 +20,15 @@ func init() { if _, err := os.Stat(platform.GetAssetLocation("geoip.dat")); err != nil && os.IsNotExist(err) { common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoip.dat"), filepath.Join(wd, "..", "..", "..", "resources", "geoip.dat"))) } + if _, err := os.Stat(platform.GetAssetLocation("geoiptestrouter.dat")); err != nil && os.IsNotExist(err) { + common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoiptestrouter.dat"), filepath.Join(wd, "..", "..", "..", "resources", "geoip.dat"))) + } if _, err := os.Stat(platform.GetAssetLocation("geosite.dat")); err != nil && os.IsNotExist(err) { common.Must(filesystem.CopyFile(platform.GetAssetLocation("geosite.dat"), filepath.Join(wd, "..", "..", "..", "resources", "geosite.dat"))) } } func TestParseIPList(t *testing.T) { - t.Log(os.Getenv("xray.location.asset")) - - common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoiptestrouter.dat"), platform.GetAssetLocation("geoip.dat"))) - ips := []string{ "geoip:us", "geoip:cn", From 9721ff7a569a4a1c26f9a197cf76379f85f837f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E3=81=AE=E3=81=8B=E3=81=88=E3=81=A7?= <autmaple@protonmail.com> Date: Thu, 8 Apr 2021 23:19:43 +0800 Subject: [PATCH 17/20] Style: comment unused code --- common/matcher/geoip/conf.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/matcher/geoip/conf.go b/common/matcher/geoip/conf.go index 9c5fa42b7eea..5f46e3a4cc28 100644 --- a/common/matcher/geoip/conf.go +++ b/common/matcher/geoip/conf.go @@ -36,7 +36,7 @@ func LoadIPFile(file, code string) ([]*CIDR, error) { } defer runtime.GC() // or debug.FreeOSMemory() return geoipdat.Cidr, nil // do not cache geoip - IPCache[index] = &geoipdat + // IPCache[index] = &geoipdat } return IPCache[index].Cidr, nil } @@ -53,7 +53,7 @@ func loadFile(file string) ([]byte, error) { // Do not cache file, may save RAM when there // are many files, but consume CPU each time. return bs, nil - FileCache[file] = bs + // FileCache[file] = bs } return FileCache[file], nil } From ec9f19039e22e57d2b4dd7597ac98c6c28f87eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E3=81=AE=E3=81=8B=E3=81=88=E3=81=A7?= <autmaple@protonmail.com> Date: Sat, 1 May 2021 08:55:27 +0800 Subject: [PATCH 18/20] remove v2ray.com --- common/matcher/str/benchmark_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/matcher/str/benchmark_test.go b/common/matcher/str/benchmark_test.go index e7420ee4e815..f52317b92f64 100644 --- a/common/matcher/str/benchmark_test.go +++ b/common/matcher/str/benchmark_test.go @@ -11,13 +11,13 @@ import ( func BenchmarkACAutomaton(b *testing.B) { ac := NewACAutomaton() for i := 1; i <= 1024; i++ { - ac.Add(strconv.Itoa(i)+".v2ray.com", Domain) + ac.Add(strconv.Itoa(i)+".xray.com", Domain) } ac.Build() b.ResetTimer() for i := 0; i < b.N; i++ { - _ = ac.Match("0.v2ray.com") + _ = ac.Match("0.xray.com") } } From a3e63e6928c11d174cdb29857b0a585241a35381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E3=81=AE=E3=81=8B=E3=81=88=E3=81=A7?= <autmaple@protonmail.com> Date: Sat, 1 May 2021 10:44:29 +0800 Subject: [PATCH 19/20] style: refine style --- infra/conf/router.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/infra/conf/router.go b/infra/conf/router.go index accb2c4b9f48..99064543750e 100644 --- a/infra/conf/router.go +++ b/infra/conf/router.go @@ -94,10 +94,9 @@ func (c *RouterConfig) Build() (*router.Config, error) { } type RouterRule struct { - Type string `json:"type"` - OutboundTag string `json:"outboundTag"` - BalancerTag string `json:"balancerTag"` - + Type string `json:"type"` + OutboundTag string `json:"outboundTag"` + BalancerTag string `json:"balancerTag"` DomainMatcher string `json:"domainMatcher"` } From 1ced7985d59f89673f7e17409180c93ac1885afd Mon Sep 17 00:00:00 2001 From: hmol233 <82594500+hmol233@users.noreply.github.com> Date: Sun, 11 Jul 2021 22:02:55 +0800 Subject: [PATCH 20/20] Refine `PrioritizedDomain`, should fix https://github.com/XTLS/Xray-core/issues/638 --- app/dns/dns.go | 50 ++++++++++------------------- app/dns/nameserver.go | 74 ++++++++++++++++++++----------------------- 2 files changed, 52 insertions(+), 72 deletions(-) diff --git a/app/dns/dns.go b/app/dns/dns.go index c638735dd405..68cb29b09bdd 100644 --- a/app/dns/dns.go +++ b/app/dns/dns.go @@ -12,7 +12,6 @@ import ( "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/matcher/geoip" - "github.com/xtls/xray-core/common/matcher/str" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/features" @@ -29,8 +28,6 @@ type DNS struct { hosts *StaticHosts clients []*Client ctx context.Context - domainMatcher str.IndexMatcher - matcherInfos []DomainMatcherInfo } // DomainMatcherInfo contains information attached to index returned by Server.domainMatcher @@ -89,9 +86,6 @@ func New(ctx context.Context, config *Config) (*DNS, error) { domainRuleCount += len(ns.PrioritizedDomain) } - // MatcherInfos is ensured to cover the maximum index domainMatcher could return, where matcher's index starts from 1 - matcherInfos := make([]DomainMatcherInfo, domainRuleCount+1) - domainMatcher := &str.MatcherGroup{} geoipContainer := geoip.GeoIPMatcherContainer{} for _, endpoint := range config.NameServers { @@ -104,22 +98,13 @@ func New(ctx context.Context, config *Config) (*DNS, error) { } for _, ns := range config.NameServer { - clientIdx := len(clients) - updateDomain := func(domainRule str.Matcher, originalRuleIdx int, matcherInfos []DomainMatcherInfo) error { - midx := domainMatcher.Add(domainRule) - matcherInfos[midx] = DomainMatcherInfo{ - clientIdx: uint16(clientIdx), - domainRuleIdx: uint16(originalRuleIdx), - } - return nil - } myClientIP := clientIP switch len(ns.ClientIp) { case net.IPv4len, net.IPv6len: - myClientIP = net.IP(ns.ClientIp) + myClientIP = ns.ClientIp } - client, err := NewClient(ctx, ns, myClientIP, geoipContainer, &matcherInfos, updateDomain) + client, err := NewClient(ctx, ns, myClientIP, geoipContainer) if err != nil { return nil, newError("failed to create client").Base(err) } @@ -137,8 +122,6 @@ func New(ctx context.Context, config *Config) (*DNS, error) { ipOption: ipOption, clients: clients, ctx: ctx, - domainMatcher: domainMatcher, - matcherInfos: matcherInfos, cacheStrategy: config.CacheStrategy, disableFallback: config.DisableFallback, }, nil @@ -268,21 +251,22 @@ func (s *DNS) sortClients(domain string, option *dns.IPOption) []*Client { }() // Priority domain matching - for _, match := range s.domainMatcher.Match(domain) { - info := s.matcherInfos[match] - client := s.clients[info.clientIdx] - domainRule := client.domains[info.domainRuleIdx] - if !canQueryOnClient(option, client) { - newError("skipping the client " + client.Name()).AtDebug().WriteToLog() - continue - } - domainRules = append(domainRules, fmt.Sprintf("%s(DNS idx:%d)", domainRule, info.clientIdx)) - if clientUsed[info.clientIdx] { - continue + for clientIdx, client := range s.clients { + if ids := client.domainMatcher.Match(domain); len(ids) > 0 { + if !canQueryOnClient(option, client) { + newError("skipping the client " + client.Name()).AtDebug().WriteToLog() + continue + } + for _, id := range ids { + rule := client.findRule(id) + domainRules = append(domainRules, fmt.Sprintf("%s(DNS idx:%d)", rule, clientIdx)) + } + if clientUsed[clientIdx] { + continue + } + clients = append(clients, client) + clientNames = append(clientNames, client.Name()) } - clientUsed[info.clientIdx] = true - clients = append(clients, client) - clientNames = append(clientNames, client.Name()) } if !s.disableFallback { diff --git a/app/dns/nameserver.go b/app/dns/nameserver.go index ac0e405aca13..acc842b36171 100644 --- a/app/dns/nameserver.go +++ b/app/dns/nameserver.go @@ -25,11 +25,23 @@ type Server interface { // Client is the interface for DNS client. type Client struct { - server Server - clientIP net.IP - skipFallback bool - domains []string - expectIPs []*geoip.GeoIPMatcher + server Server + clientIP net.IP + skipFallback bool + expectIPs []*geoip.GeoIPMatcher + domainMatcher str.MatcherGroup + originRules []*NameServer_OriginalRule +} + +func (c Client) findRule(idx uint32) string { + for _, r := range c.originRules { + if idx <= r.Size { + return r.Rule + } + idx -= r.Size + } + + return "unknown rule" } var errExpectedIPNonMatch = errors.New("expectIPs not match") @@ -64,7 +76,7 @@ func NewServer(dest net.Destination, dispatcher routing.Dispatcher) (Server, err } // NewClient creates a DNS client managing a name server with client IP, domain rules and expected IPs. -func NewClient(ctx context.Context, ns *NameServer, clientIP net.IP, container geoip.GeoIPMatcherContainer, matcherInfos *[]DomainMatcherInfo, updateDomainRule func(str.Matcher, int, []DomainMatcherInfo) error) (*Client, error) { +func NewClient(ctx context.Context, ns *NameServer, clientIP net.IP, container geoip.GeoIPMatcherContainer) (*Client, error) { client := &Client{} err := core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error { @@ -79,55 +91,38 @@ func NewClient(ctx context.Context, ns *NameServer, clientIP net.IP, container g ns.PrioritizedDomain = append(ns.PrioritizedDomain, localTLDsAndDotlessDomains...) ns.OriginalRules = append(ns.OriginalRules, localTLDsAndDotlessDomainsRule) // The following lines is a solution to avoid core panics(rule index out of range) when setting `localhost` DNS client in config. - // Because the `localhost` DNS client will apend len(localTLDsAndDotlessDomains) rules into matcherInfos to match `geosite:private` default rule. + // Because the `localhost` DNS client will append len(localTLDsAndDotlessDomains) rules into matcherInfos to match `geosite:private` default rule. // But `matcherInfos` has no enough length to add rules, which leads to core panics (rule index out of range). // To avoid this, the length of `matcherInfos` must be equal to the expected, so manually append it with Golang default zero value first for later modification. - for i := 0; i < len(localTLDsAndDotlessDomains); i++ { - *matcherInfos = append(*matcherInfos, DomainMatcherInfo{ - clientIdx: uint16(0), - domainRuleIdx: uint16(0), - }) - } + // ;) + /* + for i := 0; i < len(localTLDsAndDotlessDomains); i++ { + *matcherInfos = append(*matcherInfos, DomainMatcherInfo{ + clientIdx: uint16(0), + domainRuleIdx: uint16(0), + }) + } + */ } // Establish domain rules - var rules []string - ruleCurr := 0 - ruleIter := 0 + var domainMatcher = str.MatcherGroup{} for _, domain := range ns.PrioritizedDomain { domainRule, err := toStrMatcher(domain.Type, domain.Value) if err != nil { return newError("failed to create prioritized domain").Base(err).AtWarning() } - originalRuleIdx := ruleCurr - if ruleCurr < len(ns.OriginalRules) { - rule := ns.OriginalRules[ruleCurr] - if ruleCurr >= len(rules) { - rules = append(rules, rule.Rule) - } - ruleIter++ - if ruleIter >= int(rule.Size) { - ruleIter = 0 - ruleCurr++ - } - } else { // No original rule, generate one according to current domain matcher (majorly for compatibility with tests) - rules = append(rules, domainRule.String()) - ruleCurr++ - } - err = updateDomainRule(domainRule, originalRuleIdx, *matcherInfos) - if err != nil { - return newError("failed to create prioritized domain").Base(err).AtWarning() - } + domainMatcher.Add(domainRule) } // Establish expected IPs - var matchers []*geoip.GeoIPMatcher + var ipMatchers []*geoip.GeoIPMatcher for _, geoip := range ns.Geoip { matcher, err := container.Add(geoip) if err != nil { return newError("failed to create ip matcher").Base(err).AtWarning() } - matchers = append(matchers, matcher) + ipMatchers = append(ipMatchers, matcher) } if len(clientIP) > 0 { @@ -141,8 +136,9 @@ func NewClient(ctx context.Context, ns *NameServer, clientIP net.IP, container g client.server = server client.clientIP = clientIP - client.domains = rules - client.expectIPs = matchers + client.expectIPs = ipMatchers + client.originRules = ns.OriginalRules + client.domainMatcher = domainMatcher return nil }) return client, err