mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-12-22 19:33:32 +02:00
Refactor: GeoSite & GeoIP
This commit is contained in:
parent
8382b29922
commit
b11429eaee
54 changed files with 2110 additions and 1633 deletions
|
@ -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()
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)})
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
3
common/matcher/conf/conf.go
Normal file
3
common/matcher/conf/conf.go
Normal file
|
@ -0,0 +1,3 @@
|
|||
package conf
|
||||
|
||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
78
common/matcher/conf/domain.go
Normal file
78
common/matcher/conf/domain.go
Normal file
|
@ -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
|
||||
}
|
9
common/matcher/conf/errors.generated.go
Normal file
9
common/matcher/conf/errors.generated.go
Normal file
|
@ -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{})
|
||||
}
|
3
common/matcher/domain/domain.go
Normal file
3
common/matcher/domain/domain.go
Normal file
|
@ -0,0 +1,3 @@
|
|||
package domain
|
||||
|
||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
229
common/matcher/domain/domain.pb.go
Normal file
229
common/matcher/domain/domain.pb.go
Normal file
|
@ -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
|
||||
}
|
39
common/matcher/domain/domain.proto
Normal file
39
common/matcher/domain/domain.proto
Normal file
|
@ -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")
|
||||
}
|
||||
}
|
||||
*/
|
9
common/matcher/domain/errors.generated.go
Normal file
9
common/matcher/domain/errors.generated.go
Normal file
|
@ -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{})
|
||||
}
|
90
common/matcher/geoip/conf.go
Normal file
90
common/matcher/geoip/conf.go
Normal file
|
@ -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:]
|
||||
}
|
||||
}
|
40
common/matcher/geoip/crid.go
Normal file
40
common/matcher/geoip/crid.go
Normal file
|
@ -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]
|
||||
}
|
9
common/matcher/geoip/errors.generated.go
Normal file
9
common/matcher/geoip/errors.generated.go
Normal file
|
@ -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{})
|
||||
}
|
|
@ -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
|
||||
)
|
307
common/matcher/geoip/geoip.pb.go
Normal file
307
common/matcher/geoip/geoip.pb.go
Normal file
|
@ -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
|
||||
}
|
25
common/matcher/geoip/geoip.proto
Normal file
25
common/matcher/geoip/geoip.proto
Normal file
|
@ -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;
|
||||
}
|
|
@ -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()
|
47
common/matcher/geoip/matcher.go
Normal file
47
common/matcher/geoip/matcher.go
Normal file
|
@ -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
|
||||
}
|
33
common/matcher/geosite/attribute.go
Normal file
33
common/matcher/geosite/attribute.go
Normal file
|
@ -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
|
||||
}
|
42
common/matcher/geosite/conf.go
Normal file
42
common/matcher/geosite/conf.go
Normal file
|
@ -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
|
||||
}
|
9
common/matcher/geosite/errors.generated.go
Normal file
9
common/matcher/geosite/errors.generated.go
Normal file
|
@ -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{})
|
||||
}
|
86
common/matcher/geosite/file.go
Normal file
86
common/matcher/geosite/file.go
Normal file
|
@ -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:]
|
||||
}
|
||||
}
|
19
common/matcher/geosite/geosite.go
Normal file
19
common/matcher/geosite/geosite.go
Normal file
|
@ -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}
|
||||
}
|
443
common/matcher/geosite/geosite.pb.go
Normal file
443
common/matcher/geosite/geosite.pb.go
Normal file
|
@ -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
|
||||
}
|
38
common/matcher/geosite/geosite.proto
Normal file
38
common/matcher/geosite/geosite.proto
Normal file
|
@ -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;
|
||||
}
|
|
@ -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) {
|
|
@ -1,4 +1,4 @@
|
|||
package strmatcher
|
||||
package str
|
||||
|
||||
import "strings"
|
||||
|
|
@ -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) {
|
|
@ -1,4 +1,4 @@
|
|||
package strmatcher
|
||||
package str
|
||||
|
||||
type FullMatcherGroup struct {
|
||||
matchers map[string][]uint32
|
|
@ -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) {
|
|
@ -1,4 +1,4 @@
|
|||
package strmatcher
|
||||
package str
|
||||
|
||||
import (
|
||||
"regexp"
|
|
@ -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) {
|
|
@ -1,4 +1,4 @@
|
|||
package strmatcher
|
||||
package str
|
||||
|
||||
import (
|
||||
"regexp"
|
|
@ -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) {
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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}},
|
||||
},
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue