From dfeaef75e7cc0224ced70dda9a1fc4c7987602f6 Mon Sep 17 00:00:00 2001 From: Vigilans Date: Sat, 15 Aug 2020 21:22:32 +0800 Subject: [PATCH 1/2] Refactor DNS Server to record original rule of domain matchers --- app/dns/config.pb.go | 247 ++++++++++++++++++++++---------- app/dns/config.proto | 6 + app/dns/server.go | 88 ++++++++---- common/strmatcher/matchers.go | 16 +++ common/strmatcher/strmatcher.go | 1 + infra/conf/dns.go | 12 +- infra/conf/dns_test.go | 6 + 7 files changed, 271 insertions(+), 105 deletions(-) diff --git a/app/dns/config.pb.go b/app/dns/config.pb.go index ca393d910..468d5eaee 100644 --- a/app/dns/config.pb.go +++ b/app/dns/config.pb.go @@ -1,3 +1,9 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0 +// protoc (unknown) +// source: v2ray.com/core/app/dns/config.proto + package dns import ( @@ -81,6 +87,7 @@ type NameServer struct { Address *net.Endpoint `protobuf:"bytes,1,opt,name=address,proto3" json:"address,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"` } func (x *NameServer) Reset() { @@ -136,6 +143,13 @@ func (x *NameServer) GetGeoip() []*router.GeoIP { return nil } +func (x *NameServer) GetOriginalRules() []*NameServer_OriginalRule { + if x != nil { + return x.OriginalRules + } + return nil +} + type Config struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -145,14 +159,14 @@ type Config struct { // A special value 'localhost' as a domain address can be set to use DNS on local system. // // Deprecated: Do not use. - NameServers []*net.Endpoint `protobuf:"bytes,1,rep,name=NameServers,proto3" json:"NameServers,omitempty"` + NameServers []*net.Endpoint `protobuf:"bytes,1,rep,name=NameServers,json=nameServers,proto3" json:"NameServers,omitempty"` // NameServer list used by this DNS client. NameServer []*NameServer `protobuf:"bytes,5,rep,name=name_server,json=nameServer,proto3" json:"name_server,omitempty"` // Static hosts. Domain to IP. // Deprecated. Use static_hosts. // // Deprecated: Do not use. - Hosts map[string]*net.IPOrDomain `protobuf:"bytes,2,rep,name=Hosts,proto3" json:"Hosts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Hosts map[string]*net.IPOrDomain `protobuf:"bytes,2,rep,name=Hosts,json=hosts,proto3" json:"Hosts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Client IP for EDNS client subnet. Must be 4 bytes (IPv4) or 16 bytes (IPv6). ClientIp []byte `protobuf:"bytes,3,opt,name=client_ip,json=clientIp,proto3" json:"client_ip,omitempty"` StaticHosts []*Config_HostMapping `protobuf:"bytes,4,rep,name=static_hosts,json=staticHosts,proto3" json:"static_hosts,omitempty"` @@ -291,6 +305,61 @@ func (x *NameServer_PriorityDomain) GetDomain() string { return "" } +type NameServer_OriginalRule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Rule string `protobuf:"bytes,1,opt,name=rule,proto3" json:"rule,omitempty"` + Size uint32 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` +} + +func (x *NameServer_OriginalRule) Reset() { + *x = NameServer_OriginalRule{} + if protoimpl.UnsafeEnabled { + mi := &file_v2ray_com_core_app_dns_config_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NameServer_OriginalRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NameServer_OriginalRule) ProtoMessage() {} + +func (x *NameServer_OriginalRule) ProtoReflect() protoreflect.Message { + mi := &file_v2ray_com_core_app_dns_config_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NameServer_OriginalRule.ProtoReflect.Descriptor instead. +func (*NameServer_OriginalRule) Descriptor() ([]byte, []int) { + return file_v2ray_com_core_app_dns_config_proto_rawDescGZIP(), []int{0, 1} +} + +func (x *NameServer_OriginalRule) GetRule() string { + if x != nil { + return x.Rule + } + return "" +} + +func (x *NameServer_OriginalRule) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + type Config_HostMapping struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -307,7 +376,7 @@ type Config_HostMapping struct { func (x *Config_HostMapping) Reset() { *x = Config_HostMapping{} if protoimpl.UnsafeEnabled { - mi := &file_v2ray_com_core_app_dns_config_proto_msgTypes[4] + mi := &file_v2ray_com_core_app_dns_config_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -320,7 +389,7 @@ func (x *Config_HostMapping) String() string { func (*Config_HostMapping) ProtoMessage() {} func (x *Config_HostMapping) ProtoReflect() protoreflect.Message { - mi := &file_v2ray_com_core_app_dns_config_proto_msgTypes[4] + mi := &file_v2ray_com_core_app_dns_config_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -378,7 +447,7 @@ var file_v2ray_com_core_app_dns_config_proto_rawDesc = []byte{ 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x26, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbf, 0x02, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, + 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xcb, 0x03, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, @@ -392,58 +461,66 @@ var file_v2ray_com_core_app_dns_config_proto_rawDesc = []byte{ 0x32, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, - 0x6f, 0x69, 0x70, 0x1a, 0x64, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, - 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, - 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, 0x22, 0xc3, 0x04, 0x0a, 0x06, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x45, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, - 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 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, 0x3f, 0x0a, 0x0b, 0x6e, - 0x61, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 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, 0x3f, 0x0a, 0x05, - 0x48, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x76, 0x32, + 0x6f, 0x69, 0x70, 0x12, 0x52, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, + 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 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, 0x49, 0x0a, 0x0c, 0x73, 0x74, - 0x61, 0x74, 0x69, 0x63, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 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, 0x1a, 0x5b, 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, 0x37, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, - 0x6f, 0x72, 0x65, 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, 0x98, 0x01, 0x0a, 0x0b, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, - 0x70, 0x69, 0x6e, 0x67, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 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, 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, 0x42, 0x34, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, - 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, - 0x50, 0x01, 0x5a, 0x03, 0x64, 0x6e, 0x73, 0xaa, 0x02, 0x12, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, - 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 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, 0x64, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, + 0x63, 0x6f, 0x72, 0x65, 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, 0xc3, 0x04, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x45, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 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, 0x6e, 0x61, 0x6d, 0x65, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x3f, 0x0a, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x5f, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x76, + 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 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, 0x3f, 0x0a, 0x05, 0x48, 0x6f, 0x73, 0x74, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, + 0x63, 0x6f, 0x72, 0x65, 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, 0x68, 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, 0x49, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x76, + 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 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, 0x1a, 0x5b, 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, 0x37, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 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, 0x98, 0x01, 0x0a, 0x0b, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 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, 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, 0x42, 0x34, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, + 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x50, 0x01, 0x5a, 0x03, + 0x64, 0x6e, 0x73, 0xaa, 0x02, 0x12, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, + 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -459,34 +536,36 @@ func file_v2ray_com_core_app_dns_config_proto_rawDescGZIP() []byte { } var file_v2ray_com_core_app_dns_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_v2ray_com_core_app_dns_config_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_v2ray_com_core_app_dns_config_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_v2ray_com_core_app_dns_config_proto_goTypes = []interface{}{ (DomainMatchingType)(0), // 0: v2ray.core.app.dns.DomainMatchingType (*NameServer)(nil), // 1: v2ray.core.app.dns.NameServer (*Config)(nil), // 2: v2ray.core.app.dns.Config (*NameServer_PriorityDomain)(nil), // 3: v2ray.core.app.dns.NameServer.PriorityDomain - nil, // 4: v2ray.core.app.dns.Config.HostsEntry - (*Config_HostMapping)(nil), // 5: v2ray.core.app.dns.Config.HostMapping - (*net.Endpoint)(nil), // 6: v2ray.core.common.net.Endpoint - (*router.GeoIP)(nil), // 7: v2ray.core.app.router.GeoIP - (*net.IPOrDomain)(nil), // 8: v2ray.core.common.net.IPOrDomain + (*NameServer_OriginalRule)(nil), // 4: v2ray.core.app.dns.NameServer.OriginalRule + nil, // 5: v2ray.core.app.dns.Config.HostsEntry + (*Config_HostMapping)(nil), // 6: v2ray.core.app.dns.Config.HostMapping + (*net.Endpoint)(nil), // 7: v2ray.core.common.net.Endpoint + (*router.GeoIP)(nil), // 8: v2ray.core.app.router.GeoIP + (*net.IPOrDomain)(nil), // 9: v2ray.core.common.net.IPOrDomain } var file_v2ray_com_core_app_dns_config_proto_depIdxs = []int32{ - 6, // 0: v2ray.core.app.dns.NameServer.address:type_name -> v2ray.core.common.net.Endpoint + 7, // 0: v2ray.core.app.dns.NameServer.address:type_name -> v2ray.core.common.net.Endpoint 3, // 1: v2ray.core.app.dns.NameServer.prioritized_domain:type_name -> v2ray.core.app.dns.NameServer.PriorityDomain - 7, // 2: v2ray.core.app.dns.NameServer.geoip:type_name -> v2ray.core.app.router.GeoIP - 6, // 3: v2ray.core.app.dns.Config.NameServers:type_name -> v2ray.core.common.net.Endpoint - 1, // 4: v2ray.core.app.dns.Config.name_server:type_name -> v2ray.core.app.dns.NameServer - 4, // 5: v2ray.core.app.dns.Config.Hosts:type_name -> v2ray.core.app.dns.Config.HostsEntry - 5, // 6: v2ray.core.app.dns.Config.static_hosts:type_name -> v2ray.core.app.dns.Config.HostMapping - 0, // 7: v2ray.core.app.dns.NameServer.PriorityDomain.type:type_name -> v2ray.core.app.dns.DomainMatchingType - 8, // 8: v2ray.core.app.dns.Config.HostsEntry.value:type_name -> v2ray.core.common.net.IPOrDomain - 0, // 9: v2ray.core.app.dns.Config.HostMapping.type:type_name -> v2ray.core.app.dns.DomainMatchingType - 10, // [10:10] is the sub-list for method output_type - 10, // [10:10] is the sub-list for method input_type - 10, // [10:10] is the sub-list for extension type_name - 10, // [10:10] is the sub-list for extension extendee - 0, // [0:10] is the sub-list for field type_name + 8, // 2: v2ray.core.app.dns.NameServer.geoip:type_name -> v2ray.core.app.router.GeoIP + 4, // 3: v2ray.core.app.dns.NameServer.original_rules:type_name -> v2ray.core.app.dns.NameServer.OriginalRule + 7, // 4: v2ray.core.app.dns.Config.NameServers:type_name -> v2ray.core.common.net.Endpoint + 1, // 5: v2ray.core.app.dns.Config.name_server:type_name -> v2ray.core.app.dns.NameServer + 5, // 6: v2ray.core.app.dns.Config.Hosts:type_name -> v2ray.core.app.dns.Config.HostsEntry + 6, // 7: v2ray.core.app.dns.Config.static_hosts:type_name -> v2ray.core.app.dns.Config.HostMapping + 0, // 8: v2ray.core.app.dns.NameServer.PriorityDomain.type:type_name -> v2ray.core.app.dns.DomainMatchingType + 9, // 9: v2ray.core.app.dns.Config.HostsEntry.value:type_name -> v2ray.core.common.net.IPOrDomain + 0, // 10: v2ray.core.app.dns.Config.HostMapping.type:type_name -> v2ray.core.app.dns.DomainMatchingType + 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_v2ray_com_core_app_dns_config_proto_init() } @@ -531,7 +610,19 @@ func file_v2ray_com_core_app_dns_config_proto_init() { return nil } } - file_v2ray_com_core_app_dns_config_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_v2ray_com_core_app_dns_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NameServer_OriginalRule); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_v2ray_com_core_app_dns_config_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Config_HostMapping); i { case 0: return &v.state @@ -550,7 +641,7 @@ func file_v2ray_com_core_app_dns_config_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_v2ray_com_core_app_dns_config_proto_rawDesc, NumEnums: 1, - NumMessages: 5, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, diff --git a/app/dns/config.proto b/app/dns/config.proto index 0678b275d..aed1aab90 100644 --- a/app/dns/config.proto +++ b/app/dns/config.proto @@ -18,8 +18,14 @@ message NameServer { string domain = 2; } + message OriginalRule { + string rule = 1; + uint32 size = 2; + } + repeated PriorityDomain prioritized_domain = 2; repeated v2ray.core.app.router.GeoIP geoip = 3; + repeated OriginalRule original_rules = 4; } enum DomainMatchingType { diff --git a/app/dns/server.go b/app/dns/server.go index 551af9ceb..0a86f5c07 100644 --- a/app/dns/server.go +++ b/app/dns/server.go @@ -28,13 +28,20 @@ import ( // Server is a DNS rely server. type Server struct { sync.Mutex - hosts *StaticHosts - clients []Client - clientIP net.IP - domainMatcher strmatcher.IndexMatcher - domainIndexMap map[uint32]uint32 - ipIndexMap map[uint32]*MultiGeoIPMatcher - tag string + hosts *StaticHosts + clientIP net.IP + clients []Client // clientIdx -> Client + ipIndexMap []*MultiGeoIPMatcher // clientIdx -> *MultiGeoIPMatcher + domainRules [][]string // clientIdx -> domainRuleIdx -> DomainRule + domainMatcher strmatcher.IndexMatcher + matcherInfos []DomainMatcherInfo // matcherIdx -> DomainMatcherInfo + tag string +} + +// DomainMatcherInfo contains information attached to index returned by Server.domainMatcher +type DomainMatcherInfo struct { + clientIdx uint16 + domainRuleIdx uint16 } // MultiGeoIPMatcher for match @@ -139,6 +146,7 @@ func New(ctx context.Context, config *Config) (*Server, error) { })) } } + server.ipIndexMap = append(server.ipIndexMap, nil) return len(server.clients) - 1 } @@ -150,22 +158,54 @@ func New(ctx context.Context, config *Config) (*Server, error) { } if len(config.NameServer) > 0 { - domainMatcher := &strmatcher.MatcherGroup{} - domainIndexMap := make(map[uint32]uint32) - ipIndexMap := make(map[uint32]*MultiGeoIPMatcher) - var geoIPMatcherContainer router.GeoIPMatcherContainer - + clientIndices := []int{} + domainRuleCount := 0 for _, ns := range config.NameServer { idx := addNameServer(ns) + clientIndices = append(clientIndices, idx) + domainRuleCount += len(ns.PrioritizedDomain) + } + domainRules := make([][]string, len(server.clients)) + domainMatcher := &strmatcher.MatcherGroup{} + matcherInfos := make([]DomainMatcherInfo, domainRuleCount+1) // matcher index starts from 1 + var geoIPMatcherContainer router.GeoIPMatcherContainer + for nidx, ns := range config.NameServer { + idx := clientIndices[nidx] + + // Establish domain rule matcher + rules := []string{} + ruleCurr := 0 + ruleIter := 0 for _, domain := range ns.PrioritizedDomain { matcher, err := toStrMatcher(domain.Type, domain.Domain) if err != nil { return nil, newError("failed to create prioritized domain").Base(err).AtWarning() } midx := domainMatcher.Add(matcher) - domainIndexMap[midx] = uint32(idx) + if midx >= uint32(len(matcherInfos)) { // This rarely happens according to current matcher's implementation + newError("expanding domain matcher info array to size ", midx, " when adding ", matcher).AtDebug().WriteToLog() + matcherInfos = append(matcherInfos, make([]DomainMatcherInfo, midx-uint32(len(matcherInfos))+1)...) + } + info := &matcherInfos[midx] + info.clientIdx = uint16(idx) + if ruleCurr < len(ns.OriginalRules) { + info.domainRuleIdx = uint16(ruleCurr) + rule := ns.OriginalRules[ruleCurr] + if ruleCurr >= len(rules) { + rules = append(rules, rule.Rule) + } + ruleIter++ + if ruleIter >= int(rule.Size) { + ruleIter = 0 + ruleCurr++ + } + } else { // No original rule, generate one according to current domain matcher (majorly for compability with tests) + info.domainRuleIdx = uint16(len(rules)) + rules = append(rules, matcher.String()) + } } + domainRules[idx] = rules // only add to ipIndexMap if GeoIP is configured if len(ns.Geoip) > 0 { @@ -178,13 +218,12 @@ func New(ctx context.Context, config *Config) (*Server, error) { matchers = append(matchers, matcher) } matcher := &MultiGeoIPMatcher{matchers: matchers} - ipIndexMap[uint32(idx)] = matcher + server.ipIndexMap[idx] = matcher } } - + server.domainRules = domainRules server.domainMatcher = domainMatcher - server.domainIndexMap = domainIndexMap - server.ipIndexMap = ipIndexMap + server.matcherInfos = matcherInfos } if len(server.clients) == 0 { @@ -215,9 +254,9 @@ func (s *Server) IsOwnLink(ctx context.Context) bool { } // Match check dns ip match geoip -func (s *Server) Match(idx uint32, client Client, domain string, ips []net.IP) ([]net.IP, error) { - matcher, exist := s.ipIndexMap[idx] - if !exist { +func (s *Server) Match(idx int, client Client, domain string, ips []net.IP) ([]net.IP, error) { + matcher := s.ipIndexMap[idx] + if matcher == nil { return ips, nil } @@ -239,7 +278,7 @@ func (s *Server) Match(idx uint32, client Client, domain string, ips []net.IP) ( return newIps, nil } -func (s *Server) queryIPTimeout(idx uint32, client Client, domain string, option IPOption) ([]net.IP, error) { +func (s *Server) queryIPTimeout(idx int, client Client, domain string, option IPOption) ([]net.IP, error) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*4) if len(s.tag) > 0 { ctx = session.ContextWithInbound(ctx, &session.Inbound{ @@ -332,8 +371,9 @@ func (s *Server) lookupIPInternal(domain string, option IPOption) ([]net.IP, err if s.domainMatcher != nil { indices := s.domainMatcher.Match(domain) for _, idx := range indices { - matchedClient = s.clients[s.domainIndexMap[idx]] - ips, err := s.queryIPTimeout(s.domainIndexMap[idx], matchedClient, domain, option) + clientIdx := int(s.matcherInfos[idx].clientIdx) + matchedClient = s.clients[clientIdx] + ips, err := s.queryIPTimeout(clientIdx, matchedClient, domain, option) if len(ips) > 0 { return ips, nil } @@ -353,7 +393,7 @@ func (s *Server) lookupIPInternal(domain string, option IPOption) ([]net.IP, err continue } - ips, err := s.queryIPTimeout(uint32(idx), client, domain, option) + ips, err := s.queryIPTimeout(idx, client, domain, option) if len(ips) > 0 { return ips, nil } diff --git a/common/strmatcher/matchers.go b/common/strmatcher/matchers.go index 73d9e7b83..b5ab09c4c 100644 --- a/common/strmatcher/matchers.go +++ b/common/strmatcher/matchers.go @@ -11,12 +11,20 @@ func (m fullMatcher) Match(s string) bool { return string(m) == s } +func (m fullMatcher) String() string { + return "full:" + string(m) +} + type substrMatcher string func (m substrMatcher) Match(s string) bool { return strings.Contains(s, string(m)) } +func (m substrMatcher) String() string { + return "keyword:" + string(m) +} + type domainMatcher string func (m domainMatcher) Match(s string) bool { @@ -27,6 +35,10 @@ func (m domainMatcher) Match(s string) bool { return len(s) == len(pattern) || s[len(s)-len(pattern)-1] == '.' } +func (m domainMatcher) String() string { + return "domain:" + string(m) +} + type regexMatcher struct { pattern *regexp.Regexp } @@ -34,3 +46,7 @@ type regexMatcher struct { func (m *regexMatcher) Match(s string) bool { return m.pattern.MatchString(s) } + +func (m *regexMatcher) String() string { + return "regexp:" + m.pattern.String() +} diff --git a/common/strmatcher/strmatcher.go b/common/strmatcher/strmatcher.go index 6486d8369..7c2e366a1 100644 --- a/common/strmatcher/strmatcher.go +++ b/common/strmatcher/strmatcher.go @@ -8,6 +8,7 @@ import ( type Matcher interface { // Match returns true if the given string matches a predefined pattern. Match(string) bool + String() string } // Type is the type of the matcher. diff --git a/infra/conf/dns.go b/infra/conf/dns.go index 0a9eb50a8..9e3713752 100644 --- a/infra/conf/dns.go +++ b/infra/conf/dns.go @@ -62,11 +62,12 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) { } var domains []*dns.NameServer_PriorityDomain + var originalRules []*dns.NameServer_OriginalRule - for _, d := range c.Domains { - parsedDomain, err := parseDomainRule(d) + for _, rule := range c.Domains { + parsedDomain, err := parseDomainRule(rule) if err != nil { - return nil, newError("invalid domain rule: ", d).Base(err) + return nil, newError("invalid domain rule: ", rule).Base(err) } for _, pd := range parsedDomain { @@ -75,6 +76,10 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) { Domain: pd.Value, }) } + originalRules = append(originalRules, &dns.NameServer_OriginalRule{ + Rule: rule, + Size: uint32(len(parsedDomain)), + }) } geoipList, err := toCidrList(c.ExpectIPs) @@ -90,6 +95,7 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) { }, PrioritizedDomain: domains, Geoip: geoipList, + OriginalRules: originalRules, }, nil } diff --git a/infra/conf/dns_test.go b/infra/conf/dns_test.go index fc3a4ba13..1725af7c5 100644 --- a/infra/conf/dns_test.go +++ b/infra/conf/dns_test.go @@ -94,6 +94,12 @@ func TestDnsConfigParsing(t *testing.T) { Domain: "v2ray.com", }, }, + OriginalRules: []*dns.NameServer_OriginalRule{ + { + Rule: "domain:v2ray.com", + Size: 1, + }, + }, }, }, StaticHosts: []*dns.Config_HostMapping{ From 22b4e68a2ddf42b3942415b0ca1aea7b63441847 Mon Sep 17 00:00:00 2001 From: Vigilans Date: Sat, 15 Aug 2020 23:42:04 +0800 Subject: [PATCH 2/2] Log matched rules and DNS to use during priority matching 2. Dotless domain support in static host & modify first letter's captial in log --- app/dns/server.go | 11 +++++++++++ infra/conf/dns.go | 13 +++++++++++++ infra/conf/router.go | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/dns/server.go b/app/dns/server.go index 0a86f5c07..7a0ba8e9d 100644 --- a/app/dns/server.go +++ b/app/dns/server.go @@ -6,6 +6,7 @@ package dns import ( "context" + "fmt" "log" "net/url" "strings" @@ -370,6 +371,16 @@ func (s *Server) lookupIPInternal(domain string, option IPOption) ([]net.IP, err var matchedClient Client if s.domainMatcher != nil { indices := s.domainMatcher.Match(domain) + domainRules := []string{} + matchingDNS := []string{} + for _, idx := range indices { + info := s.matcherInfos[idx] + rule := s.domainRules[info.clientIdx][info.domainRuleIdx] + domainRules = append(domainRules, fmt.Sprintf("%s(DNS idx:%d)", rule, info.clientIdx)) + matchingDNS = append(matchingDNS, s.clients[info.clientIdx].Name()) + } + newError("domain ", domain, " matching following rules: ", domainRules).AtDebug().WriteToLog() + newError("domain ", domain, " uses following DNS first: ", matchingDNS).AtDebug().WriteToLog() for _, idx := range indices { clientIdx := int(s.matcherInfos[idx].clientIdx) matchedClient = s.clients[clientIdx] diff --git a/infra/conf/dns.go b/infra/conf/dns.go index 9e3713752..e9222a4c0 100644 --- a/infra/conf/dns.go +++ b/infra/conf/dns.go @@ -191,6 +191,19 @@ func (c *DnsConfig) Build() (*dns.Config, error) { mapping.Type = dns.DomainMatchingType_Full mapping.Domain = domain[5:] + mappings = append(mappings, mapping) + } else if strings.HasPrefix(domain, "dotless:") { + mapping := getHostMapping(addr) + mapping.Type = dns.DomainMatchingType_Regex + switch substr := domain[8:]; { + case substr == "": + mapping.Domain = "^[^.]*$" + case !strings.Contains(substr, "."): + mapping.Domain = "^[^.]*" + substr + "[^.]*$" + default: + return nil, newError("substr in dotless rule should not contain a dot: ", substr) + } + mappings = append(mappings, mapping) } else if strings.HasPrefix(domain, "ext:") { kv := strings.Split(domain[4:], ":") diff --git a/infra/conf/router.go b/infra/conf/router.go index 77549481e..e25077855 100644 --- a/infra/conf/router.go +++ b/infra/conf/router.go @@ -307,7 +307,7 @@ func parseDomainRule(domain string) ([]*router.Domain, error) { case !strings.Contains(substr, "."): domainRule.Value = "^[^.]*" + substr + "[^.]*$" default: - return nil, newError("Substr in dotless rule should not contain a dot: ", substr) + return nil, newError("substr in dotless rule should not contain a dot: ", substr) } default: domainRule.Type = router.Domain_Plain