From 643698564379c9efef52d2755b0920433dc6adec Mon Sep 17 00:00:00 2001 From: patterniha Date: Tue, 29 Apr 2025 14:15:43 +0330 Subject: [PATCH] DNS: New Features --- app/dns/config.pb.go | 249 ++++++++++++++++++++-------------- app/dns/config.proto | 8 +- app/dns/dns.go | 5 +- app/dns/dns_test.go | 14 +- app/dns/nameserver.go | 118 +++++++++++----- app/router/condition_geoip.go | 26 ++++ infra/conf/dns.go | 96 ++++++++----- 7 files changed, 336 insertions(+), 180 deletions(-) diff --git a/app/dns/config.pb.go b/app/dns/config.pb.go index 67fbd84e..c653d691 100644 --- a/app/dns/config.pb.go +++ b/app/dns/config.pb.go @@ -128,16 +128,20 @@ 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"` - SkipFallback bool `protobuf:"varint,6,opt,name=skipFallback,proto3" json:"skipFallback,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"` - QueryStrategy QueryStrategy `protobuf:"varint,7,opt,name=query_strategy,json=queryStrategy,proto3,enum=xray.app.dns.QueryStrategy" json:"query_strategy,omitempty"` - AllowUnexpectedIPs bool `protobuf:"varint,8,opt,name=allowUnexpectedIPs,proto3" json:"allowUnexpectedIPs,omitempty"` - Tag string `protobuf:"bytes,9,opt,name=tag,proto3" json:"tag,omitempty"` - TimeoutMs uint64 `protobuf:"varint,10,opt,name=timeoutMs,proto3" json:"timeoutMs,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"` + SkipFallback bool `protobuf:"varint,6,opt,name=skipFallback,proto3" json:"skipFallback,omitempty"` + PrioritizedDomain []*NameServer_PriorityDomain `protobuf:"bytes,2,rep,name=prioritized_domain,json=prioritizedDomain,proto3" json:"prioritized_domain,omitempty"` + ExpectedGeoip []*router.GeoIP `protobuf:"bytes,3,rep,name=expected_geoip,json=expectedGeoip,proto3" json:"expected_geoip,omitempty"` + OriginalRules []*NameServer_OriginalRule `protobuf:"bytes,4,rep,name=original_rules,json=originalRules,proto3" json:"original_rules,omitempty"` + QueryStrategy QueryStrategy `protobuf:"varint,7,opt,name=query_strategy,json=queryStrategy,proto3,enum=xray.app.dns.QueryStrategy" json:"query_strategy,omitempty"` + PriorGeoip []*router.GeoIP `protobuf:"bytes,8,rep,name=prior_geoip,json=priorGeoip,proto3" json:"prior_geoip,omitempty"` + Tag string `protobuf:"bytes,9,opt,name=tag,proto3" json:"tag,omitempty"` + TimeoutMs uint64 `protobuf:"varint,10,opt,name=timeoutMs,proto3" json:"timeoutMs,omitempty"` + DisableCache bool `protobuf:"varint,11,opt,name=disableCache,proto3" json:"disableCache,omitempty"` + FinalQuery bool `protobuf:"varint,12,opt,name=finalQuery,proto3" json:"finalQuery,omitempty"` + UnexpectedGeoip []*router.GeoIP `protobuf:"bytes,13,rep,name=unexpected_geoip,json=unexpectedGeoip,proto3" json:"unexpected_geoip,omitempty"` + UnpriorGeoip []*router.GeoIP `protobuf:"bytes,14,rep,name=unprior_geoip,json=unpriorGeoip,proto3" json:"unprior_geoip,omitempty"` } func (x *NameServer) Reset() { @@ -198,9 +202,9 @@ func (x *NameServer) GetPrioritizedDomain() []*NameServer_PriorityDomain { return nil } -func (x *NameServer) GetGeoip() []*router.GeoIP { +func (x *NameServer) GetExpectedGeoip() []*router.GeoIP { if x != nil { - return x.Geoip + return x.ExpectedGeoip } return nil } @@ -219,11 +223,11 @@ func (x *NameServer) GetQueryStrategy() QueryStrategy { return QueryStrategy_USE_IP } -func (x *NameServer) GetAllowUnexpectedIPs() bool { +func (x *NameServer) GetPriorGeoip() []*router.GeoIP { if x != nil { - return x.AllowUnexpectedIPs + return x.PriorGeoip } - return false + return nil } func (x *NameServer) GetTag() string { @@ -240,6 +244,34 @@ func (x *NameServer) GetTimeoutMs() uint64 { return 0 } +func (x *NameServer) GetDisableCache() bool { + if x != nil { + return x.DisableCache + } + return false +} + +func (x *NameServer) GetFinalQuery() bool { + if x != nil { + return x.FinalQuery + } + return false +} + +func (x *NameServer) GetUnexpectedGeoip() []*router.GeoIP { + if x != nil { + return x.UnexpectedGeoip + } + return nil +} + +func (x *NameServer) GetUnpriorGeoip() []*router.GeoIP { + if x != nil { + return x.UnpriorGeoip + } + return nil +} + type Config struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -532,7 +564,7 @@ var file_app_dns_config_proto_rawDesc = []byte{ 0x2e, 0x64, 0x6e, 0x73, 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, 0x92, 0x05, 0x0a, 0x0a, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf0, 0x06, 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, @@ -546,81 +578,95 @@ var file_app_dns_config_proto_rawDesc = []byte{ 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, + 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3d, 0x0a, 0x0e, 0x65, 0x78, 0x70, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x5f, 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, 0x0d, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x47, 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, 0x12, 0x42, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, + 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x07, 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, 0x12, 0x37, 0x0a, 0x0b, 0x70, 0x72, 0x69, + 0x6f, 0x72, 0x5f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x08, 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, 0x0a, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x47, 0x65, 0x6f, + 0x69, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x74, 0x61, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, + 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x4d, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, + 0x68, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x66, 0x69, 0x6e, 0x61, + 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x41, 0x0a, 0x10, 0x75, 0x6e, 0x65, 0x78, 0x70, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x5f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0d, 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, 0x0f, 0x75, 0x6e, 0x65, 0x78, 0x70, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x47, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x3b, 0x0a, 0x0d, 0x75, 0x6e, 0x70, + 0x72, 0x69, 0x6f, 0x72, 0x5f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0e, 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, 0x0c, 0x75, 0x6e, 0x70, 0x72, 0x69, 0x6f, + 0x72, 0x47, 0x65, 0x6f, 0x69, 0x70, 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, 0x9c, + 0x04, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, 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, 0x12, 0x42, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, - 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x07, 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, 0x12, 0x2e, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x6f, - 0x77, 0x55, 0x6e, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x49, 0x50, 0x73, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x55, 0x6e, 0x65, 0x78, 0x70, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x49, 0x50, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, - 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, - 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 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, 0x9c, 0x04, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, 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, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, - 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x36, 0x0a, 0x16, - 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x49, - 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x64, 0x69, + 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 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, + 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, + 0x61, 0x63, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x36, 0x0a, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x49, 0x66, 0x4d, - 0x61, 0x74, 0x63, 0x68, 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, + 0x61, 0x74, 0x63, 0x68, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x64, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x49, 0x66, 0x4d, 0x61, 0x74, + 0x63, 0x68, 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, } var ( @@ -651,19 +697,22 @@ var file_app_dns_config_proto_goTypes = []any{ var file_app_dns_config_proto_depIdxs = []int32{ 7, // 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 - 8, // 2: xray.app.dns.NameServer.geoip:type_name -> xray.app.router.GeoIP + 8, // 2: xray.app.dns.NameServer.expected_geoip:type_name -> xray.app.router.GeoIP 5, // 3: xray.app.dns.NameServer.original_rules:type_name -> xray.app.dns.NameServer.OriginalRule 1, // 4: xray.app.dns.NameServer.query_strategy:type_name -> xray.app.dns.QueryStrategy - 2, // 5: xray.app.dns.Config.name_server:type_name -> xray.app.dns.NameServer - 6, // 6: xray.app.dns.Config.static_hosts:type_name -> xray.app.dns.Config.HostMapping - 1, // 7: xray.app.dns.Config.query_strategy:type_name -> xray.app.dns.QueryStrategy - 0, // 8: xray.app.dns.NameServer.PriorityDomain.type:type_name -> xray.app.dns.DomainMatchingType - 0, // 9: xray.app.dns.Config.HostMapping.type:type_name -> xray.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, // 5: xray.app.dns.NameServer.prior_geoip:type_name -> xray.app.router.GeoIP + 8, // 6: xray.app.dns.NameServer.unexpected_geoip:type_name -> xray.app.router.GeoIP + 8, // 7: xray.app.dns.NameServer.unprior_geoip:type_name -> xray.app.router.GeoIP + 2, // 8: xray.app.dns.Config.name_server:type_name -> xray.app.dns.NameServer + 6, // 9: xray.app.dns.Config.static_hosts:type_name -> xray.app.dns.Config.HostMapping + 1, // 10: xray.app.dns.Config.query_strategy:type_name -> xray.app.dns.QueryStrategy + 0, // 11: xray.app.dns.NameServer.PriorityDomain.type:type_name -> xray.app.dns.DomainMatchingType + 0, // 12: xray.app.dns.Config.HostMapping.type:type_name -> xray.app.dns.DomainMatchingType + 13, // [13:13] is the sub-list for method output_type + 13, // [13:13] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name } func init() { file_app_dns_config_proto_init() } diff --git a/app/dns/config.proto b/app/dns/config.proto index 8935ffa8..82600235 100644 --- a/app/dns/config.proto +++ b/app/dns/config.proto @@ -25,12 +25,16 @@ message NameServer { } repeated PriorityDomain prioritized_domain = 2; - repeated xray.app.router.GeoIP geoip = 3; + repeated xray.app.router.GeoIP expected_geoip = 3; repeated OriginalRule original_rules = 4; QueryStrategy query_strategy = 7; - bool allowUnexpectedIPs = 8; + repeated xray.app.router.GeoIP prior_geoip = 8; string tag = 9; uint64 timeoutMs = 10; + bool disableCache = 11; + bool finalQuery = 12; + repeated xray.app.router.GeoIP unexpected_geoip = 13; + repeated xray.app.router.GeoIP unprior_geoip = 14; } enum DomainMatchingType { diff --git a/app/dns/dns.go b/app/dns/dns.go index 3b9cfbcb..29960817 100644 --- a/app/dns/dns.go +++ b/app/dns/dns.go @@ -108,7 +108,7 @@ func New(ctx context.Context, config *Config) (*DNS, error) { myClientIP = net.IP(ns.ClientIp) } - disableCache := config.DisableCache + disableCache := config.DisableCache || ns.DisableCache var tag = defaultTag if len(ns.Tag) > 0 { @@ -227,6 +227,9 @@ func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, uint32, er } errs = append(errs, err) + if client.IsFinalQuery() { + break + } } if len(errs) > 0 { diff --git a/app/dns/dns_test.go b/app/dns/dns_test.go index 7ea6fcf8..cb70b0b3 100644 --- a/app/dns/dns_test.go +++ b/app/dns/dns_test.go @@ -539,7 +539,7 @@ func TestIPMatch(t *testing.T) { }, Port: uint32(port), }, - Geoip: []*router.GeoIP{ + ExpectedGeoip: []*router.GeoIP{ { CountryCode: "local", Cidr: []*router.CIDR{ @@ -563,7 +563,7 @@ func TestIPMatch(t *testing.T) { }, Port: uint32(port), }, - Geoip: []*router.GeoIP{ + ExpectedGeoip: []*router.GeoIP{ { CountryCode: "test", Cidr: []*router.CIDR{ @@ -667,7 +667,7 @@ func TestLocalDomain(t *testing.T) { // Equivalent of dotless:localhost {Type: DomainMatchingType_Regex, Domain: "^[^.]*localhost[^.]*$"}, }, - Geoip: []*router.GeoIP{ + ExpectedGeoip: []*router.GeoIP{ { // Will match localhost, localhost-a and localhost-b, CountryCode: "local", Cidr: []*router.CIDR{ @@ -897,7 +897,7 @@ func TestMultiMatchPrioritizedDomain(t *testing.T) { Domain: "google.com", }, }, - Geoip: []*router.GeoIP{ + ExpectedGeoip: []*router.GeoIP{ { // Will only match 8.8.8.8 and 8.8.4.4 Cidr: []*router.CIDR{ {Ip: []byte{8, 8, 8, 8}, Prefix: 32}, @@ -922,7 +922,7 @@ func TestMultiMatchPrioritizedDomain(t *testing.T) { Domain: "google.com", }, }, - Geoip: []*router.GeoIP{ + ExpectedGeoip: []*router.GeoIP{ { // Will match 8.8.8.8 and 8.8.8.7, etc Cidr: []*router.CIDR{ {Ip: []byte{8, 8, 8, 7}, Prefix: 24}, @@ -946,7 +946,7 @@ func TestMultiMatchPrioritizedDomain(t *testing.T) { Domain: "api.google.com", }, }, - Geoip: []*router.GeoIP{ + ExpectedGeoip: []*router.GeoIP{ { // Will only match 8.8.7.7 (api.google.com) Cidr: []*router.CIDR{ {Ip: []byte{8, 8, 7, 7}, Prefix: 32}, @@ -970,7 +970,7 @@ func TestMultiMatchPrioritizedDomain(t *testing.T) { Domain: "v2.api.google.com", }, }, - Geoip: []*router.GeoIP{ + ExpectedGeoip: []*router.GeoIP{ { // Will only match 8.8.7.8 (v2.api.google.com) Cidr: []*router.CIDR{ {Ip: []byte{8, 8, 7, 8}, Prefix: 32}, diff --git a/app/dns/nameserver.go b/app/dns/nameserver.go index 31681c4a..2ee875e8 100644 --- a/app/dns/nameserver.go +++ b/app/dns/nameserver.go @@ -26,14 +26,17 @@ type Server interface { // Client is the interface for DNS client. type Client struct { - server Server - skipFallback bool - domains []string - expectedIPs []*router.GeoIPMatcher - allowUnexpectedIPs bool - tag string - timeoutMs time.Duration - ipOption *dns.IPOption + server Server + skipFallback bool + domains []string + expectedIPs []*router.GeoIPMatcher + unexpectedIPs []*router.GeoIPMatcher + priorIPs []*router.GeoIPMatcher + unpriorIPs []*router.GeoIPMatcher + tag string + timeoutMs time.Duration + finalQuery bool + ipOption *dns.IPOption } // NewServer creates a name server object according to the network destination url. @@ -150,13 +153,43 @@ func NewClient( } // Establish expected IPs - var matchers []*router.GeoIPMatcher - for _, geoip := range ns.Geoip { + var expectedMatchers []*router.GeoIPMatcher + for _, geoip := range ns.ExpectedGeoip { matcher, err := router.GlobalGeoIPContainer.Add(geoip) if err != nil { - return errors.New("failed to create ip matcher").Base(err).AtWarning() + return errors.New("failed to create expected ip matcher").Base(err).AtWarning() } - matchers = append(matchers, matcher) + expectedMatchers = append(expectedMatchers, matcher) + } + + // Establish unexpected IPs + var unexpectedMatchers []*router.GeoIPMatcher + for _, geoip := range ns.UnexpectedGeoip { + matcher, err := router.GlobalGeoIPContainer.Add(geoip) + if err != nil { + return errors.New("failed to create unexpected ip matcher").Base(err).AtWarning() + } + unexpectedMatchers = append(unexpectedMatchers, matcher) + } + + // Establish prior IPs + var priorMatchers []*router.GeoIPMatcher + for _, geoip := range ns.PriorGeoip { + matcher, err := router.GlobalGeoIPContainer.Add(geoip) + if err != nil { + return errors.New("failed to create prior ip matcher").Base(err).AtWarning() + } + priorMatchers = append(priorMatchers, matcher) + } + + // Establish unprior IPs + var unpriorMatchers []*router.GeoIPMatcher + for _, geoip := range ns.UnpriorGeoip { + matcher, err := router.GlobalGeoIPContainer.Add(geoip) + if err != nil { + return errors.New("failed to create unprior ip matcher").Base(err).AtWarning() + } + unpriorMatchers = append(unpriorMatchers, matcher) } if len(clientIP) > 0 { @@ -176,10 +209,13 @@ func NewClient( client.server = server client.skipFallback = ns.SkipFallback client.domains = rules - client.expectedIPs = matchers - client.allowUnexpectedIPs = ns.AllowUnexpectedIPs + client.expectedIPs = expectedMatchers + client.unexpectedIPs = unexpectedMatchers + client.priorIPs = priorMatchers + client.unpriorIPs = unpriorMatchers client.tag = tag client.timeoutMs = timeoutMs + client.finalQuery = ns.FinalQuery client.ipOption = &ipOption return nil }) @@ -191,6 +227,10 @@ func (c *Client) Name() string { return c.server.Name() } +func (c *Client) IsFinalQuery() bool { + return c.finalQuery +} + // QueryIP sends DNS query to the name server with the client's IP. func (c *Client) QueryIP(ctx context.Context, domain string, option dns.IPOption) ([]net.IP, uint32, error) { option.IPv4Enable = option.IPv4Enable && c.ipOption.IPv4Enable @@ -213,34 +253,40 @@ func (c *Client) QueryIP(ctx context.Context, domain string, option dns.IPOption } if len(c.expectedIPs) > 0 { - newIps := c.MatchExpectedIPs(domain, ips) - if len(newIps) == 0 { - if !c.allowUnexpectedIPs { - return nil, 0, dns.ErrEmptyResponse - } - } else { - ips = newIps + ips = router.MatchIPs(c.expectedIPs, ips, false) + errors.LogDebug(context.Background(), "domain ", domain, " expectedIPs ", ips, " matched at server ", c.Name()) + if len(ips) == 0 { + return nil, 0, dns.ErrEmptyResponse + } + } + + if len(c.unexpectedIPs) > 0 { + ips = router.MatchIPs(c.unexpectedIPs, ips, true) + errors.LogDebug(context.Background(), "domain ", domain, " unexpectedIPs ", ips, " matched at server ", c.Name()) + if len(ips) == 0 { + return nil, 0, dns.ErrEmptyResponse + } + } + + if len(c.priorIPs) > 0 { + ipsNew := router.MatchIPs(c.priorIPs, ips, false) + if len(ipsNew) > 0 { + ips = ipsNew + errors.LogDebug(context.Background(), "domain ", domain, " priorIPs ", ips, " matched at server ", c.Name()) + } + } + + if len(c.unpriorIPs) > 0 { + ipsNew := router.MatchIPs(c.unpriorIPs, ips, true) + if len(ipsNew) > 0 { + ips = ipsNew + errors.LogDebug(context.Background(), "domain ", domain, " unpriorIPs ", ips, " matched at server ", c.Name()) } } return ips, ttl, nil } -// MatchExpectedIPs matches queried domain IPs with expected IPs and returns matched ones. -func (c *Client) MatchExpectedIPs(domain string, ips []net.IP) []net.IP { - var newIps []net.IP - for _, ip := range ips { - for _, matcher := range c.expectedIPs { - if matcher.Match(ip) { - newIps = append(newIps, ip) - break - } - } - } - errors.LogDebug(context.Background(), "domain ", domain, " expectedIPs ", newIps, " matched at server ", c.Name()) - return newIps -} - func ResolveIpOptionOverride(queryStrategy QueryStrategy, ipOption dns.IPOption) dns.IPOption { switch queryStrategy { case QueryStrategy_USE_IP: diff --git a/app/router/condition_geoip.go b/app/router/condition_geoip.go index 0140cdfb..38f7f0ce 100644 --- a/app/router/condition_geoip.go +++ b/app/router/condition_geoip.go @@ -116,3 +116,29 @@ func (c *GeoIPMatcherContainer) Add(geoip *GeoIP) (*GeoIPMatcher, error) { } var GlobalGeoIPContainer GeoIPMatcherContainer + +func MatchIPs(matchers []*GeoIPMatcher, ips []net.IP, reverse bool) []net.IP { + if len(matchers) == 0 { + panic("GeoIP matchers should not be empty to avoid ambiguity") + } + newIPs := make([]net.IP, 0, len(ips)) + var isFound bool + for _, ip := range ips { + isFound = false + for _, matcher := range matchers { + if matcher.Match(ip) { + isFound = true + break + } + } + if isFound && !reverse { + newIPs = append(newIPs, ip) + continue + } + if !isFound && reverse { + newIPs = append(newIPs, ip) + continue + } + } + return newIPs +} diff --git a/infra/conf/dns.go b/infra/conf/dns.go index 7baeda87..930f1a73 100644 --- a/infra/conf/dns.go +++ b/infra/conf/dns.go @@ -12,17 +12,21 @@ import ( ) type NameServerConfig struct { - Address *Address `json:"address"` - ClientIP *Address `json:"clientIp"` - Port uint16 `json:"port"` - SkipFallback bool `json:"skipFallback"` - Domains []string `json:"domains"` - ExpectedIPs StringList `json:"expectedIPs"` - ExpectIPs StringList `json:"expectIPs"` - QueryStrategy string `json:"queryStrategy"` - AllowUnexpectedIPs bool `json:"allowUnexpectedIps"` - Tag string `json:"tag"` - TimeoutMs uint64 `json:"timeoutMs"` + Address *Address `json:"address"` + ClientIP *Address `json:"clientIp"` + Port uint16 `json:"port"` + SkipFallback bool `json:"skipFallback"` + Domains []string `json:"domains"` + ExpectedIPs StringList `json:"expectedIPs"` + ExpectIPs StringList `json:"expectIPs"` + QueryStrategy string `json:"queryStrategy"` + PriorIPs StringList `json:"priorIPs"` + Tag string `json:"tag"` + TimeoutMs uint64 `json:"timeoutMs"` + DisableCache bool `json:"disableCache"` + FinalQuery bool `json:"finalQuery"` + UnexpectedIPs StringList `json:"unexpectedIPs"` + UnpriorIPs StringList `json:"unpriorIPs"` } // UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON @@ -34,17 +38,21 @@ func (c *NameServerConfig) UnmarshalJSON(data []byte) error { } var advanced struct { - Address *Address `json:"address"` - ClientIP *Address `json:"clientIp"` - Port uint16 `json:"port"` - SkipFallback bool `json:"skipFallback"` - Domains []string `json:"domains"` - ExpectedIPs StringList `json:"expectedIPs"` - ExpectIPs StringList `json:"expectIPs"` - QueryStrategy string `json:"queryStrategy"` - AllowUnexpectedIPs bool `json:"allowUnexpectedIps"` - Tag string `json:"tag"` - TimeoutMs uint64 `json:"timeoutMs"` + Address *Address `json:"address"` + ClientIP *Address `json:"clientIp"` + Port uint16 `json:"port"` + SkipFallback bool `json:"skipFallback"` + Domains []string `json:"domains"` + ExpectedIPs StringList `json:"expectedIPs"` + ExpectIPs StringList `json:"expectIPs"` + QueryStrategy string `json:"queryStrategy"` + PriorIPs StringList `json:"priorIPs"` + Tag string `json:"tag"` + TimeoutMs uint64 `json:"timeoutMs"` + DisableCache bool `json:"disableCache"` + FinalQuery bool `json:"finalQuery"` + UnexpectedIPs StringList `json:"unexpectedIPs"` + UnpriorIPs StringList `json:"unpriorIPs"` } if err := json.Unmarshal(data, &advanced); err == nil { c.Address = advanced.Address @@ -55,9 +63,13 @@ func (c *NameServerConfig) UnmarshalJSON(data []byte) error { c.ExpectedIPs = advanced.ExpectedIPs c.ExpectIPs = advanced.ExpectIPs c.QueryStrategy = advanced.QueryStrategy - c.AllowUnexpectedIPs = advanced.AllowUnexpectedIPs + c.PriorIPs = advanced.PriorIPs c.Tag = advanced.Tag c.TimeoutMs = advanced.TimeoutMs + c.DisableCache = advanced.DisableCache + c.FinalQuery = advanced.FinalQuery + c.UnexpectedIPs = advanced.UnexpectedIPs + c.UnpriorIPs = advanced.UnpriorIPs return nil } @@ -109,9 +121,21 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) { if len(expectedIPs) == 0 { expectedIPs = c.ExpectIPs } - geoipList, err := ToCidrList(expectedIPs) + expectedGeoipList, err := ToCidrList(expectedIPs) if err != nil { - return nil, errors.New("invalid IP rule: ", expectedIPs).Base(err) + return nil, errors.New("invalid expected IP rule: ", expectedIPs).Base(err) + } + priorGeoipList, err := ToCidrList(c.PriorIPs) + if err != nil { + return nil, errors.New("invalid prior IP rule: ", c.PriorIPs).Base(err) + } + unexpectedGeoipList, err := ToCidrList(c.UnexpectedIPs) + if err != nil { + return nil, errors.New("invalid unexpected IP rule: ", c.UnexpectedIPs).Base(err) + } + unpriorGeoipList, err := ToCidrList(c.UnpriorIPs) + if err != nil { + return nil, errors.New("invalid unprior IP rule: ", c.UnpriorIPs).Base(err) } var myClientIP []byte @@ -128,15 +152,19 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) { Address: c.Address.Build(), Port: uint32(c.Port), }, - ClientIp: myClientIP, - SkipFallback: c.SkipFallback, - PrioritizedDomain: domains, - Geoip: geoipList, - OriginalRules: originalRules, - QueryStrategy: resolveQueryStrategy(c.QueryStrategy), - AllowUnexpectedIPs: c.AllowUnexpectedIPs, - Tag: c.Tag, - TimeoutMs: c.TimeoutMs, + ClientIp: myClientIP, + SkipFallback: c.SkipFallback, + PrioritizedDomain: domains, + ExpectedGeoip: expectedGeoipList, + OriginalRules: originalRules, + QueryStrategy: resolveQueryStrategy(c.QueryStrategy), + PriorGeoip: priorGeoipList, + Tag: c.Tag, + TimeoutMs: c.TimeoutMs, + DisableCache: c.DisableCache, + FinalQuery: c.FinalQuery, + UnexpectedGeoip: unexpectedGeoipList, + UnpriorGeoip: unpriorGeoipList, }, nil }