1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-22 01:57:12 -05:00

[app/dns] Support per-client configuration for fakedns (#2212)

* Move `filterIP` from `hosts.go` to `dnscommon.go`

* Implement adding pools for fakedns.HolderMulti

* Implement per-client fakedns for DNS app

* Remove `dns.ClientWithIPOption` and replace with new programming model

* Implement JSON config support for new fakedns config

* Fix lint and tests

* Fix some codacy analysis
This commit is contained in:
Vigilans 2022-12-15 10:38:28 +08:00 committed by GitHub
parent 32475d9239
commit f8ac919d66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 1341 additions and 586 deletions

View File

@ -1,6 +1,7 @@
package dns package dns
import ( import (
fakedns "github.com/v2fly/v2ray-core/v5/app/dns/fakedns"
routercommon "github.com/v2fly/v2ray-core/v5/app/router/routercommon" routercommon "github.com/v2fly/v2ray-core/v5/app/router/routercommon"
net "github.com/v2fly/v2ray-core/v5/common/net" net "github.com/v2fly/v2ray-core/v5/common/net"
_ "github.com/v2fly/v2ray-core/v5/common/protoext" _ "github.com/v2fly/v2ray-core/v5/common/protoext"
@ -224,6 +225,7 @@ type NameServer struct {
PrioritizedDomain []*NameServer_PriorityDomain `protobuf:"bytes,2,rep,name=prioritized_domain,json=prioritizedDomain,proto3" json:"prioritized_domain,omitempty"` PrioritizedDomain []*NameServer_PriorityDomain `protobuf:"bytes,2,rep,name=prioritized_domain,json=prioritizedDomain,proto3" json:"prioritized_domain,omitempty"`
Geoip []*routercommon.GeoIP `protobuf:"bytes,3,rep,name=geoip,proto3" json:"geoip,omitempty"` Geoip []*routercommon.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"` OriginalRules []*NameServer_OriginalRule `protobuf:"bytes,4,rep,name=original_rules,json=originalRules,proto3" json:"original_rules,omitempty"`
FakeDns *fakedns.FakeDnsPoolMulti `protobuf:"bytes,11,opt,name=fake_dns,json=fakeDns,proto3" json:"fake_dns,omitempty"`
// Deprecated. Use fallback_strategy. // Deprecated. Use fallback_strategy.
// //
// Deprecated: Do not use. // Deprecated: Do not use.
@ -307,6 +309,13 @@ func (x *NameServer) GetOriginalRules() []*NameServer_OriginalRule {
return nil return nil
} }
func (x *NameServer) GetFakeDns() *fakedns.FakeDnsPoolMulti {
if x != nil {
return x.FakeDns
}
return nil
}
// Deprecated: Do not use. // Deprecated: Do not use.
func (x *NameServer) GetSkipFallback() bool { func (x *NameServer) GetSkipFallback() bool {
if x != nil { if x != nil {
@ -429,8 +438,11 @@ type Config struct {
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,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 // Client IP for EDNS client subnet. Must be 4 bytes (IPv4) or 16 bytes
// (IPv6). // (IPv6).
ClientIp []byte `protobuf:"bytes,3,opt,name=client_ip,json=clientIp,proto3" json:"client_ip,omitempty"` ClientIp []byte `protobuf:"bytes,3,opt,name=client_ip,json=clientIp,proto3" json:"client_ip,omitempty"`
// Static domain-ip mapping in DNS server.
StaticHosts []*HostMapping `protobuf:"bytes,4,rep,name=static_hosts,json=staticHosts,proto3" json:"static_hosts,omitempty"` StaticHosts []*HostMapping `protobuf:"bytes,4,rep,name=static_hosts,json=staticHosts,proto3" json:"static_hosts,omitempty"`
// Global fakedns object.
FakeDns *fakedns.FakeDnsPoolMulti `protobuf:"bytes,16,opt,name=fake_dns,json=fakeDns,proto3" json:"fake_dns,omitempty"`
// Tag is the inbound tag of DNS client. // Tag is the inbound tag of DNS client.
Tag string `protobuf:"bytes,6,opt,name=tag,proto3" json:"tag,omitempty"` Tag string `protobuf:"bytes,6,opt,name=tag,proto3" json:"tag,omitempty"`
// Domain matcher to use // Domain matcher to use
@ -525,6 +537,13 @@ func (x *Config) GetStaticHosts() []*HostMapping {
return nil return nil
} }
func (x *Config) GetFakeDns() *fakedns.FakeDnsPoolMulti {
if x != nil {
return x.FakeDns
}
return nil
}
func (x *Config) GetTag() string { func (x *Config) GetTag() string {
if x != nil { if x != nil {
return x.Tag return x.Tag
@ -593,8 +612,11 @@ type SimplifiedConfig struct {
NameServer []*SimplifiedNameServer `protobuf:"bytes,5,rep,name=name_server,json=nameServer,proto3" json:"name_server,omitempty"` NameServer []*SimplifiedNameServer `protobuf:"bytes,5,rep,name=name_server,json=nameServer,proto3" json:"name_server,omitempty"`
// Client IP for EDNS client subnet. Must be 4 bytes (IPv4) or 16 bytes // Client IP for EDNS client subnet. Must be 4 bytes (IPv4) or 16 bytes
// (IPv6). // (IPv6).
ClientIp string `protobuf:"bytes,3,opt,name=client_ip,json=clientIp,proto3" json:"client_ip,omitempty"` ClientIp string `protobuf:"bytes,3,opt,name=client_ip,json=clientIp,proto3" json:"client_ip,omitempty"`
// Static domain-ip mapping in DNS server.
StaticHosts []*HostMapping `protobuf:"bytes,4,rep,name=static_hosts,json=staticHosts,proto3" json:"static_hosts,omitempty"` StaticHosts []*HostMapping `protobuf:"bytes,4,rep,name=static_hosts,json=staticHosts,proto3" json:"static_hosts,omitempty"`
// Global fakedns object.
FakeDns *fakedns.FakeDnsPoolMulti `protobuf:"bytes,16,opt,name=fake_dns,json=fakeDns,proto3" json:"fake_dns,omitempty"`
// Tag is the inbound tag of DNS client. // Tag is the inbound tag of DNS client.
Tag string `protobuf:"bytes,6,opt,name=tag,proto3" json:"tag,omitempty"` Tag string `protobuf:"bytes,6,opt,name=tag,proto3" json:"tag,omitempty"`
// Domain matcher to use // Domain matcher to use
@ -673,6 +695,13 @@ func (x *SimplifiedConfig) GetStaticHosts() []*HostMapping {
return nil return nil
} }
func (x *SimplifiedConfig) GetFakeDns() *fakedns.FakeDnsPoolMulti {
if x != nil {
return x.FakeDns
}
return nil
}
func (x *SimplifiedConfig) GetTag() string { func (x *SimplifiedConfig) GetTag() string {
if x != nil { if x != nil {
return x.Tag return x.Tag
@ -816,6 +845,7 @@ type SimplifiedNameServer struct {
PrioritizedDomain []*SimplifiedNameServer_PriorityDomain `protobuf:"bytes,2,rep,name=prioritized_domain,json=prioritizedDomain,proto3" json:"prioritized_domain,omitempty"` PrioritizedDomain []*SimplifiedNameServer_PriorityDomain `protobuf:"bytes,2,rep,name=prioritized_domain,json=prioritizedDomain,proto3" json:"prioritized_domain,omitempty"`
Geoip []*routercommon.GeoIP `protobuf:"bytes,3,rep,name=geoip,proto3" json:"geoip,omitempty"` Geoip []*routercommon.GeoIP `protobuf:"bytes,3,rep,name=geoip,proto3" json:"geoip,omitempty"`
OriginalRules []*SimplifiedNameServer_OriginalRule `protobuf:"bytes,4,rep,name=original_rules,json=originalRules,proto3" json:"original_rules,omitempty"` OriginalRules []*SimplifiedNameServer_OriginalRule `protobuf:"bytes,4,rep,name=original_rules,json=originalRules,proto3" json:"original_rules,omitempty"`
FakeDns *fakedns.FakeDnsPoolMulti `protobuf:"bytes,11,opt,name=fake_dns,json=fakeDns,proto3" json:"fake_dns,omitempty"`
// Deprecated. Use fallback_strategy. // Deprecated. Use fallback_strategy.
// //
// Deprecated: Do not use. // Deprecated: Do not use.
@ -899,6 +929,13 @@ func (x *SimplifiedNameServer) GetOriginalRules() []*SimplifiedNameServer_Origin
return nil return nil
} }
func (x *SimplifiedNameServer) GetFakeDns() *fakedns.FakeDnsPoolMulti {
if x != nil {
return x.FakeDns
}
return nil
}
// Deprecated: Do not use. // Deprecated: Do not use.
func (x *SimplifiedNameServer) GetSkipFallback() bool { func (x *SimplifiedNameServer) GetSkipFallback() bool {
if x != nil { if x != nil {
@ -1159,92 +1196,153 @@ var file_app_dns_config_proto_rawDesc = []byte{
0x2f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x2f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x1a, 0x24, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x72, 0x74, 0x6f, 0x1a, 0x24, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x72,
0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d,
0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x6e,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x73, 0x2f, 0x66, 0x61, 0x6b, 0x65, 0x64, 0x6e, 0x73, 0x2f, 0x66, 0x61, 0x6b, 0x65, 0x64, 0x6e,
0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe1, 0x06, 0x0a, 0x0a, 0x4e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f,
0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,
0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xaa, 0x07, 0x0a, 0x0a, 0x4e, 0x61,
0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72,
0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x64, 0x64, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61,
0x72, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65,
0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72,
0x70, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70,
0x74, 0x61, 0x67, 0x12, 0x5c, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70,
0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74,
0x2d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x61, 0x67, 0x12, 0x5c, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65,
0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d,
0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x11, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e,
0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50,
0x6e, 0x12, 0x3f, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x11, 0x70,
0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x12, 0x3f, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70,
0x69, 0x70, 0x12, 0x52, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f,
0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76, 0x32, 0x72, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69,
0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x70, 0x12, 0x52, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x72, 0x75,
0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76, 0x32, 0x72, 0x61,
0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e,
0x6c, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e,
0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c,
0x52, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x4d, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x47, 0x0a, 0x08, 0x66, 0x61, 0x6b, 0x65, 0x5f, 0x64, 0x6e,
0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e,
0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x66, 0x61, 0x6b,
0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x65, 0x64, 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x50, 0x6f, 0x6f, 0x6c,
0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x48, 0x00, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, 0x07, 0x66, 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x12, 0x26,
0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x88, 0x01, 0x01, 0x12, 0x4d, 0x0a, 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x06,
0x0e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61,
0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x4d, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f,
0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21,
0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x48, 0x01, 0x52, 0x0d, 0x63, 0x61, 0x63, 0x68, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e,
0x65, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x88, 0x01, 0x01, 0x12, 0x56, 0x0a, 0x11, 0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x48, 0x00, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65,
0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x67, 0x79, 0x88, 0x01, 0x01, 0x12, 0x4d, 0x0a, 0x0e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x73,
0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x6c, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e,
0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x48, 0x02, 0x52, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64,
0x10, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x6e, 0x73, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79,
0x79, 0x88, 0x01, 0x01, 0x1a, 0x64, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x48, 0x01, 0x52, 0x0d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x79, 0x88, 0x01, 0x01, 0x12, 0x56, 0x0a, 0x11, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70,
0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72,
0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x61, 0x74, 0x65, 0x67, 0x79, 0x48, 0x02, 0x52, 0x10, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,
0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x1a, 0x36, 0x0a, 0x0c, 0x4f, 0x72, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x88, 0x01, 0x01, 0x1a, 0x64, 0x0a, 0x0e,
0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x75, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a,
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, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72,
0x61, 0x74, 0x65, 0x67, 0x79, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f,
0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x66, 0x61, 0x6c,
0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x22, 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, 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, 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, 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, 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, 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, 0x6e, 0x1a, 0x36, 0x0a, 0x0c, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75,
0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02,
0x69, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0xc7, 0x06, 0x0a, 0x06, 0x43, 0x6f, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x71,
0x6e, 0x66, 0x69, 0x67, 0x12, 0x45, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x42, 0x11, 0x0a,
0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x0f, 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79,
0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x73, 0x74,
0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x22, 0x98, 0x01, 0x0a, 0x0b, 0x48, 0x6f, 0x73, 0x74, 0x4d,
0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x3f, 0x0a, 0x0b, 0x6e, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01,
0x61, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72,
0x32, 0x1e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79,
0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x05, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01,
0x48, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x76, 0x32, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70,
0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72,
0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01,
0x72, 0x79, 0x42, 0x02, 0x18, 0x01, 0x52, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69,
0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x6e, 0x22, 0x90, 0x07, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x45, 0x0a, 0x0b,
0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x42, 0x0a, 0x0c, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
0x61, 0x74, 0x69, 0x63, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63,
0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69,
0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x6e, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76,
0x67, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x10, 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,
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, 0x42, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x68, 0x6f, 0x73,
0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79,
0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 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, 0x47, 0x0a, 0x08, 0x66, 0x61, 0x6b, 0x65, 0x5f, 0x64,
0x6e, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79,
0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x66, 0x61,
0x6b, 0x65, 0x64, 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x50, 0x6f, 0x6f,
0x6c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, 0x07, 0x66, 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x12,
0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61,
0x67, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x74, 0x63,
0x68, 0x65, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x6f, 0x6d, 0x61, 0x69,
0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x61,
0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02,
0x18, 0x01, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65,
0x12, 0x2c, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62,
0x61, 0x63, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0f, 0x64,
0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x3a,
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, 0x42, 0x02,
0x18, 0x01, 0x52, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62,
0x61, 0x63, 0x6b, 0x49, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x48, 0x0a, 0x0e, 0x71, 0x75,
0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x09, 0x20, 0x01,
0x28, 0x0e, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 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, 0x48, 0x0a, 0x0e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x73, 0x74,
0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x76,
0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e,
0x73, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52,
0x0d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x51,
0x0a, 0x11, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74,
0x65, 0x67, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61,
0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x46,
0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52,
0x10, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
0x79, 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, 0x4a, 0x04,
0x08, 0x07, 0x10, 0x08, 0x22, 0xe3, 0x05, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66,
0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x49, 0x0a, 0x0b, 0x6e, 0x61, 0x6d,
0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28,
0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e,
0x64, 0x6e, 0x73, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 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, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49,
0x70, 0x12, 0x42, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x68, 0x6f, 0x73, 0x74,
0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e,
0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 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, 0x47, 0x0a, 0x08, 0x66, 0x61, 0x6b, 0x65, 0x5f, 0x64, 0x6e,
0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e,
0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x66, 0x61, 0x6b,
0x65, 0x64, 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x50, 0x6f, 0x6f, 0x6c,
0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, 0x07, 0x66, 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73, 0x12, 0x10,
0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67,
0x12, 0x25, 0x0a, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68,
0x65, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
@ -1272,143 +1370,102 @@ var file_app_dns_config_proto_rawDesc = []byte{
0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x46, 0x61,
0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x10, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x10,
0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79,
0x1a, 0x5b, 0x0a, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x3a, 0x16, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82,
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0xb5, 0x18, 0x05, 0x12, 0x03, 0x64, 0x6e, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04,
0x12, 0x37, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x22, 0xa2, 0x01, 0x0a, 0x15, 0x53,
0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70,
0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01,
0x69, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e,
0x07, 0x10, 0x08, 0x22, 0x9a, 0x05, 0x0a, 0x10, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61,
0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x49, 0x0a, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03,
0x6e, 0x73, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78,
0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
0x76, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0xc8, 0x07, 0x0a, 0x14, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x4e, 0x61,
0x12, 0x42, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72,
0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61,
0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65,
0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72,
0x6f, 0x73, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70,
0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70,
0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74,
0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x61, 0x67, 0x12, 0x66, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65,
0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x18, 0x08, 0x20, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37,
0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e,
0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x2c, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x6e, 0x73, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x4e, 0x61,
0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74,
0x18, 0x01, 0x52, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x11, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74,
0x61, 0x63, 0x6b, 0x12, 0x3a, 0x0a, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x69, 0x7a, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x05, 0x67, 0x65,
0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x49, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x0b, 0x20, 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61,
0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65,
0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x49, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47,
0x48, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x5c, 0x0a, 0x0e, 0x6f,
0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20,
0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65,
0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66,
0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x48, 0x0a, 0x0e, 0x63, 0x61, 0x63, 0x69, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4f, 0x72,
0x68, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 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, 0x47, 0x0a, 0x08, 0x66, 0x61, 0x6b,
0x65, 0x5f, 0x64, 0x6e, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x76, 0x32,
0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73,
0x2e, 0x66, 0x61, 0x6b, 0x65, 0x64, 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x6b, 0x65, 0x44, 0x6e, 0x73,
0x50, 0x6f, 0x6f, 0x6c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, 0x07, 0x66, 0x61, 0x6b, 0x65, 0x44,
0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61,
0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0c, 0x73, 0x6b,
0x69, 0x70, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x4d, 0x0a, 0x0e, 0x71, 0x75,
0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x08, 0x20, 0x01,
0x28, 0x0e, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e,
0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72,
0x61, 0x74, 0x65, 0x67, 0x79, 0x48, 0x00, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74,
0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x88, 0x01, 0x01, 0x12, 0x4d, 0x0a, 0x0e, 0x63, 0x61, 0x63,
0x68, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28,
0x0e, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x0e, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61,
0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74, 0x72, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74, 0x72, 0x61,
0x74, 0x65, 0x67, 0x79, 0x52, 0x0d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74, 0x72, 0x61, 0x74, 0x74, 0x65, 0x67, 0x79, 0x48, 0x01, 0x52, 0x0d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74, 0x72,
0x65, 0x67, 0x79, 0x12, 0x51, 0x0a, 0x11, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x61, 0x74, 0x65, 0x67, 0x79, 0x88, 0x01, 0x01, 0x12, 0x56, 0x0a, 0x11, 0x66, 0x61, 0x6c, 0x6c,
0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x0a, 0x20,
0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65,
0x64, 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,
0x74, 0x65, 0x67, 0x79, 0x52, 0x10, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x48, 0x02, 0x52, 0x10, 0x66, 0x61, 0x6c,
0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x3a, 0x16, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x88, 0x01, 0x01,
0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, 0x05, 0x12, 0x03, 0x64, 0x6e, 0x73, 0x4a, 0x04, 0x1a, 0x64, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61,
0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
0x22, 0xa2, 0x01, 0x0a, 0x15, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x48, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70,
0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63,
0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16,
0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, 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, 0x42, 0x11,
0x0a, 0x0f, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
0x79, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x61,
0x74, 0x65, 0x67, 0x79, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,
0x6b, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x2a, 0x45, 0x0a, 0x12, 0x44, 0x6f,
0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 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, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x75,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4b, 0x65, 0x79,
0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x25, 0x77, 0x6f, 0x72, 0x64, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x10,
0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x03, 0x2a, 0x35, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65,
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x44, 0x67, 0x79, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x00, 0x12, 0x0b,
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0xff, 0x06, 0x0a, 0x14, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55,
0x66, 0x69, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x39, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x10, 0x02, 0x2a, 0x34, 0x0a, 0x0d, 0x43, 0x61, 0x63, 0x68,
0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x65, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x61, 0x63,
0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x68, 0x65, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x43,
0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x61, 0x63, 0x68, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x10, 0x01, 0x2a, 0x45,
0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x0a, 0x10, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65,
0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x67, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x10, 0x00, 0x12,
0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, 0x0c, 0x0a, 0x08, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x10, 0x01, 0x12, 0x16, 0x0a,
0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x66, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6f, 0x12, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x49, 0x66, 0x41, 0x6e, 0x79, 0x4d, 0x61,
0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x74, 0x63, 0x68, 0x10, 0x02, 0x42, 0x57, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x50,
0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x01, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32,
0x66, 0x69, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76,
0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x11, 0x70, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x6e, 0x73, 0xaa, 0x02, 0x12, 0x56, 0x32, 0x52, 0x61,
0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44, 0x6e, 0x73, 0x62, 0x06,
0x12, 0x3f, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70,
0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x63, 0x6f,
0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69,
0x70, 0x12, 0x5c, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x72, 0x75,
0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x76, 0x32, 0x72, 0x61,
0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x53,
0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 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,
0x26, 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18,
0x06, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x46,
0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x4d, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79,
0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70,
0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65,
0x67, 0x79, 0x48, 0x00, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74,
0x65, 0x67, 0x79, 0x88, 0x01, 0x01, 0x12, 0x4d, 0x0a, 0x0e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f,
0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21,
0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e,
0x64, 0x6e, 0x73, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
0x79, 0x48, 0x01, 0x52, 0x0d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65,
0x67, 0x79, 0x88, 0x01, 0x01, 0x12, 0x56, 0x0a, 0x11, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,
0x6b, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e,
0x32, 0x24, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70,
0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74,
0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x48, 0x02, 0x52, 0x10, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61,
0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x88, 0x01, 0x01, 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, 0x42, 0x11, 0x0a, 0x0f, 0x5f,
0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x42, 0x11,
0x0a, 0x0f, 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
0x79, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x73,
0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 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, 0x2a, 0x34, 0x0a, 0x0d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x74,
0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x61, 0x63, 0x68, 0x65, 0x45,
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x61, 0x63, 0x68,
0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x10, 0x01, 0x2a, 0x45, 0x0a, 0x10, 0x46,
0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12,
0x0b, 0x0a, 0x07, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08,
0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x69,
0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x49, 0x66, 0x41, 0x6e, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68,
0x10, 0x02, 0x42, 0x57, 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, 0x26,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79,
0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61,
0x70, 0x70, 0x2f, 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 ( var (
@ -1443,45 +1500,50 @@ var file_app_dns_config_proto_goTypes = []interface{}{
(*SimplifiedNameServer_OriginalRule)(nil), // 14: v2ray.core.app.dns.SimplifiedNameServer.OriginalRule (*SimplifiedNameServer_OriginalRule)(nil), // 14: v2ray.core.app.dns.SimplifiedNameServer.OriginalRule
(*net.Endpoint)(nil), // 15: v2ray.core.common.net.Endpoint (*net.Endpoint)(nil), // 15: v2ray.core.common.net.Endpoint
(*routercommon.GeoIP)(nil), // 16: v2ray.core.app.router.routercommon.GeoIP (*routercommon.GeoIP)(nil), // 16: v2ray.core.app.router.routercommon.GeoIP
(*net.IPOrDomain)(nil), // 17: v2ray.core.common.net.IPOrDomain (*fakedns.FakeDnsPoolMulti)(nil), // 17: v2ray.core.app.dns.fakedns.FakeDnsPoolMulti
(*net.IPOrDomain)(nil), // 18: v2ray.core.common.net.IPOrDomain
} }
var file_app_dns_config_proto_depIdxs = []int32{ var file_app_dns_config_proto_depIdxs = []int32{
15, // 0: v2ray.core.app.dns.NameServer.address:type_name -> v2ray.core.common.net.Endpoint 15, // 0: v2ray.core.app.dns.NameServer.address:type_name -> v2ray.core.common.net.Endpoint
10, // 1: v2ray.core.app.dns.NameServer.prioritized_domain:type_name -> v2ray.core.app.dns.NameServer.PriorityDomain 10, // 1: v2ray.core.app.dns.NameServer.prioritized_domain:type_name -> v2ray.core.app.dns.NameServer.PriorityDomain
16, // 2: v2ray.core.app.dns.NameServer.geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP 16, // 2: v2ray.core.app.dns.NameServer.geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP
11, // 3: v2ray.core.app.dns.NameServer.original_rules:type_name -> v2ray.core.app.dns.NameServer.OriginalRule 11, // 3: v2ray.core.app.dns.NameServer.original_rules:type_name -> v2ray.core.app.dns.NameServer.OriginalRule
1, // 4: v2ray.core.app.dns.NameServer.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy 17, // 4: v2ray.core.app.dns.NameServer.fake_dns:type_name -> v2ray.core.app.dns.fakedns.FakeDnsPoolMulti
2, // 5: v2ray.core.app.dns.NameServer.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy 1, // 5: v2ray.core.app.dns.NameServer.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy
3, // 6: v2ray.core.app.dns.NameServer.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy 2, // 6: v2ray.core.app.dns.NameServer.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy
0, // 7: v2ray.core.app.dns.HostMapping.type:type_name -> v2ray.core.app.dns.DomainMatchingType 3, // 7: v2ray.core.app.dns.NameServer.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy
15, // 8: v2ray.core.app.dns.Config.NameServers:type_name -> v2ray.core.common.net.Endpoint 0, // 8: v2ray.core.app.dns.HostMapping.type:type_name -> v2ray.core.app.dns.DomainMatchingType
4, // 9: v2ray.core.app.dns.Config.name_server:type_name -> v2ray.core.app.dns.NameServer 15, // 9: v2ray.core.app.dns.Config.NameServers:type_name -> v2ray.core.common.net.Endpoint
12, // 10: v2ray.core.app.dns.Config.Hosts:type_name -> v2ray.core.app.dns.Config.HostsEntry 4, // 10: v2ray.core.app.dns.Config.name_server:type_name -> v2ray.core.app.dns.NameServer
5, // 11: v2ray.core.app.dns.Config.static_hosts:type_name -> v2ray.core.app.dns.HostMapping 12, // 11: v2ray.core.app.dns.Config.Hosts:type_name -> v2ray.core.app.dns.Config.HostsEntry
1, // 12: v2ray.core.app.dns.Config.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy 5, // 12: v2ray.core.app.dns.Config.static_hosts:type_name -> v2ray.core.app.dns.HostMapping
2, // 13: v2ray.core.app.dns.Config.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy 17, // 13: v2ray.core.app.dns.Config.fake_dns:type_name -> v2ray.core.app.dns.fakedns.FakeDnsPoolMulti
3, // 14: v2ray.core.app.dns.Config.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy 1, // 14: v2ray.core.app.dns.Config.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy
9, // 15: v2ray.core.app.dns.SimplifiedConfig.name_server:type_name -> v2ray.core.app.dns.SimplifiedNameServer 2, // 15: v2ray.core.app.dns.Config.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy
5, // 16: v2ray.core.app.dns.SimplifiedConfig.static_hosts:type_name -> v2ray.core.app.dns.HostMapping 3, // 16: v2ray.core.app.dns.Config.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy
1, // 17: v2ray.core.app.dns.SimplifiedConfig.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy 9, // 17: v2ray.core.app.dns.SimplifiedConfig.name_server:type_name -> v2ray.core.app.dns.SimplifiedNameServer
2, // 18: v2ray.core.app.dns.SimplifiedConfig.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy 5, // 18: v2ray.core.app.dns.SimplifiedConfig.static_hosts:type_name -> v2ray.core.app.dns.HostMapping
3, // 19: v2ray.core.app.dns.SimplifiedConfig.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy 17, // 19: v2ray.core.app.dns.SimplifiedConfig.fake_dns:type_name -> v2ray.core.app.dns.fakedns.FakeDnsPoolMulti
0, // 20: v2ray.core.app.dns.SimplifiedHostMapping.type:type_name -> v2ray.core.app.dns.DomainMatchingType 1, // 20: v2ray.core.app.dns.SimplifiedConfig.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy
15, // 21: v2ray.core.app.dns.SimplifiedNameServer.address:type_name -> v2ray.core.common.net.Endpoint 2, // 21: v2ray.core.app.dns.SimplifiedConfig.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy
13, // 22: v2ray.core.app.dns.SimplifiedNameServer.prioritized_domain:type_name -> v2ray.core.app.dns.SimplifiedNameServer.PriorityDomain 3, // 22: v2ray.core.app.dns.SimplifiedConfig.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy
16, // 23: v2ray.core.app.dns.SimplifiedNameServer.geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP 0, // 23: v2ray.core.app.dns.SimplifiedHostMapping.type:type_name -> v2ray.core.app.dns.DomainMatchingType
14, // 24: v2ray.core.app.dns.SimplifiedNameServer.original_rules:type_name -> v2ray.core.app.dns.SimplifiedNameServer.OriginalRule 15, // 24: v2ray.core.app.dns.SimplifiedNameServer.address:type_name -> v2ray.core.common.net.Endpoint
1, // 25: v2ray.core.app.dns.SimplifiedNameServer.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy 13, // 25: v2ray.core.app.dns.SimplifiedNameServer.prioritized_domain:type_name -> v2ray.core.app.dns.SimplifiedNameServer.PriorityDomain
2, // 26: v2ray.core.app.dns.SimplifiedNameServer.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy 16, // 26: v2ray.core.app.dns.SimplifiedNameServer.geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP
3, // 27: v2ray.core.app.dns.SimplifiedNameServer.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy 14, // 27: v2ray.core.app.dns.SimplifiedNameServer.original_rules:type_name -> v2ray.core.app.dns.SimplifiedNameServer.OriginalRule
0, // 28: v2ray.core.app.dns.NameServer.PriorityDomain.type:type_name -> v2ray.core.app.dns.DomainMatchingType 17, // 28: v2ray.core.app.dns.SimplifiedNameServer.fake_dns:type_name -> v2ray.core.app.dns.fakedns.FakeDnsPoolMulti
17, // 29: v2ray.core.app.dns.Config.HostsEntry.value:type_name -> v2ray.core.common.net.IPOrDomain 1, // 29: v2ray.core.app.dns.SimplifiedNameServer.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy
0, // 30: v2ray.core.app.dns.SimplifiedNameServer.PriorityDomain.type:type_name -> v2ray.core.app.dns.DomainMatchingType 2, // 30: v2ray.core.app.dns.SimplifiedNameServer.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy
31, // [31:31] is the sub-list for method output_type 3, // 31: v2ray.core.app.dns.SimplifiedNameServer.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy
31, // [31:31] is the sub-list for method input_type 0, // 32: v2ray.core.app.dns.NameServer.PriorityDomain.type:type_name -> v2ray.core.app.dns.DomainMatchingType
31, // [31:31] is the sub-list for extension type_name 18, // 33: v2ray.core.app.dns.Config.HostsEntry.value:type_name -> v2ray.core.common.net.IPOrDomain
31, // [31:31] is the sub-list for extension extendee 0, // 34: v2ray.core.app.dns.SimplifiedNameServer.PriorityDomain.type:type_name -> v2ray.core.app.dns.DomainMatchingType
0, // [0:31] is the sub-list for field type_name 35, // [35:35] is the sub-list for method output_type
35, // [35:35] is the sub-list for method input_type
35, // [35:35] is the sub-list for extension type_name
35, // [35:35] is the sub-list for extension extendee
0, // [0:35] is the sub-list for field type_name
} }
func init() { file_app_dns_config_proto_init() } func init() { file_app_dns_config_proto_init() }

View File

@ -9,6 +9,7 @@ option java_multiple_files = true;
import "common/net/address.proto"; import "common/net/address.proto";
import "common/net/destination.proto"; import "common/net/destination.proto";
import "app/router/routercommon/common.proto"; import "app/router/routercommon/common.proto";
import "app/dns/fakedns/fakedns.proto";
import "common/protoext/extensions.proto"; import "common/protoext/extensions.proto";
@ -31,6 +32,8 @@ message NameServer {
repeated v2ray.core.app.router.routercommon.GeoIP geoip = 3; repeated v2ray.core.app.router.routercommon.GeoIP geoip = 3;
repeated OriginalRule original_rules = 4; repeated OriginalRule original_rules = 4;
v2ray.core.app.dns.fakedns.FakeDnsPoolMulti fake_dns = 11;
// Deprecated. Use fallback_strategy. // Deprecated. Use fallback_strategy.
bool skipFallback = 6 [deprecated = true]; bool skipFallback = 6 [deprecated = true];
@ -91,8 +94,12 @@ message Config {
// (IPv6). // (IPv6).
bytes client_ip = 3; bytes client_ip = 3;
// Static domain-ip mapping in DNS server.
repeated HostMapping static_hosts = 4; repeated HostMapping static_hosts = 4;
// Global fakedns object.
v2ray.core.app.dns.fakedns.FakeDnsPoolMulti fake_dns = 16;
// Tag is the inbound tag of DNS client. // Tag is the inbound tag of DNS client.
string tag = 6; string tag = 6;
@ -143,8 +150,12 @@ message SimplifiedConfig {
// (IPv6). // (IPv6).
string client_ip = 3; string client_ip = 3;
// Static domain-ip mapping in DNS server.
repeated HostMapping static_hosts = 4; repeated HostMapping static_hosts = 4;
// Global fakedns object.
v2ray.core.app.dns.fakedns.FakeDnsPoolMulti fake_dns = 16;
// Tag is the inbound tag of DNS client. // Tag is the inbound tag of DNS client.
string tag = 6; string tag = 6;
@ -204,6 +215,8 @@ message SimplifiedNameServer {
repeated v2ray.core.app.router.routercommon.GeoIP geoip = 3; repeated v2ray.core.app.router.routercommon.GeoIP geoip = 3;
repeated OriginalRule original_rules = 4; repeated OriginalRule original_rules = 4;
v2ray.core.app.dns.fakedns.FakeDnsPoolMulti fake_dns = 11;
// Deprecated. Use fallback_strategy. // Deprecated. Use fallback_strategy.
bool skipFallback = 6 [deprecated = true]; bool skipFallback = 6 [deprecated = true];

View File

@ -12,6 +12,8 @@ import (
"strings" "strings"
"sync" "sync"
core "github.com/v2fly/v2ray-core/v5"
"github.com/v2fly/v2ray-core/v5/app/dns/fakedns"
"github.com/v2fly/v2ray-core/v5/app/router" "github.com/v2fly/v2ray-core/v5/app/router"
"github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common"
"github.com/v2fly/v2ray-core/v5/common/errors" "github.com/v2fly/v2ray-core/v5/common/errors"
@ -28,11 +30,11 @@ import (
// DNS is a DNS rely server. // DNS is a DNS rely server.
type DNS struct { type DNS struct {
sync.Mutex sync.Mutex
ipOption dns.IPOption
hosts *StaticHosts hosts *StaticHosts
clients []*Client clients []*Client
ctx context.Context ctx context.Context
clientTags map[string]bool clientTags map[string]bool
fakeDNSEngine *FakeDNSEngine
domainMatcher strmatcher.IndexMatcher domainMatcher strmatcher.IndexMatcher
matcherInfos []DomainMatcherInfo matcherInfos []DomainMatcherInfo
} }
@ -78,31 +80,31 @@ func New(ctx context.Context, config *Config) (*DNS, error) {
clients = append(clients, NewLocalDNSClient()) clients = append(clients, NewLocalDNSClient())
} }
// Establish members related to global DNS state s := &DNS{
domainMatcher, matcherInfos, err := establishDomainRules(config, clients, nsClientMap) hosts: hosts,
if err != nil { clients: clients,
return nil, err ctx: ctx,
}
if err := establishExpectedIPs(config, clients, nsClientMap); err != nil {
return nil, err
}
clientTags := make(map[string]bool)
for _, client := range clients {
clientTags[client.tag] = true
} }
return &DNS{ // Establish members related to global DNS state
ipOption: toIPOption(config.QueryStrategy), s.clientTags = make(map[string]bool)
hosts: hosts, for _, client := range clients {
clients: clients, s.clientTags[client.tag] = true
ctx: ctx, }
clientTags: clientTags, if err := establishDomainRules(s, config, nsClientMap); err != nil {
domainMatcher: domainMatcher, return nil, err
matcherInfos: matcherInfos, }
}, nil if err := establishExpectedIPs(s, config, nsClientMap); err != nil {
return nil, err
}
if err := establishFakeDNS(s, config, nsClientMap); err != nil {
return nil, err
}
return s, nil
} }
func establishDomainRules(config *Config, clients []*Client, nsClientMap map[int]int) (strmatcher.IndexMatcher, []DomainMatcherInfo, error) { func establishDomainRules(s *DNS, config *Config, nsClientMap map[int]int) error {
domainRuleCount := 0 domainRuleCount := 0
for _, ns := range config.NameServer { for _, ns := range config.NameServer {
domainRuleCount += len(ns.PrioritizedDomain) domainRuleCount += len(ns.PrioritizedDomain)
@ -128,7 +130,7 @@ func establishDomainRules(config *Config, clients []*Client, nsClientMap map[int
for _, domain := range ns.PrioritizedDomain { for _, domain := range ns.PrioritizedDomain {
domainRule, err := toStrMatcher(domain.Type, domain.Domain) domainRule, err := toStrMatcher(domain.Type, domain.Domain)
if err != nil { if err != nil {
return nil, nil, newError("failed to create prioritized domain").Base(err).AtWarning() return newError("failed to create prioritized domain").Base(err).AtWarning()
} }
originalRuleIdx := ruleCurr originalRuleIdx := ruleCurr
if ruleCurr < len(ns.OriginalRules) { if ruleCurr < len(ns.OriginalRules) {
@ -151,18 +153,20 @@ func establishDomainRules(config *Config, clients []*Client, nsClientMap map[int
domainRuleIdx: uint16(originalRuleIdx), domainRuleIdx: uint16(originalRuleIdx),
} }
if err != nil { if err != nil {
return nil, nil, newError("failed to create prioritized domain").Base(err).AtWarning() return newError("failed to create prioritized domain").Base(err).AtWarning()
} }
} }
clients[clientIdx].domains = rules s.clients[clientIdx].domains = rules
} }
if err := domainMatcher.Build(); err != nil { if err := domainMatcher.Build(); err != nil {
return nil, nil, err return err
} }
return domainMatcher, matcherInfos, nil s.domainMatcher = domainMatcher
s.matcherInfos = matcherInfos
return nil
} }
func establishExpectedIPs(config *Config, clients []*Client, nsClientMap map[int]int) error { func establishExpectedIPs(s *DNS, config *Config, nsClientMap map[int]int) error {
geoipContainer := router.GeoIPMatcherContainer{} geoipContainer := router.GeoIPMatcherContainer{}
for nsIdx, ns := range config.NameServer { for nsIdx, ns := range config.NameServer {
clientIdx := nsClientMap[nsIdx] clientIdx := nsClientMap[nsIdx]
@ -174,11 +178,51 @@ func establishExpectedIPs(config *Config, clients []*Client, nsClientMap map[int
} }
matchers = append(matchers, matcher) matchers = append(matchers, matcher)
} }
clients[clientIdx].expectIPs = matchers s.clients[clientIdx].expectIPs = matchers
} }
return nil return nil
} }
func establishFakeDNS(s *DNS, config *Config, nsClientMap map[int]int) error {
fakeHolders := &fakedns.HolderMulti{}
fakeDefault := (*fakedns.HolderMulti)(nil)
if config.FakeDns != nil {
defaultEngine, err := fakeHolders.AddPoolMulti(config.FakeDns)
if err != nil {
return newError("fail to create fake dns").Base(err).AtWarning()
}
fakeDefault = defaultEngine
}
for nsIdx, ns := range config.NameServer {
clientIdx := nsClientMap[nsIdx]
if ns.FakeDns == nil {
continue
}
engine, err := fakeHolders.AddPoolMulti(ns.FakeDns)
if err != nil {
return newError("fail to create fake dns").Base(err).AtWarning()
}
s.clients[clientIdx].fakeDNS = NewFakeDNSServer(engine)
s.clients[clientIdx].queryStrategy.FakeEnable = true
}
// Do not create FakeDNSEngine feature if no FakeDNS server is configured
if fakeHolders.IsEmpty() {
return nil
}
// Add FakeDNSEngine feature when DNS feature is added for the first time
s.fakeDNSEngine = &FakeDNSEngine{dns: s, fakeHolders: fakeHolders, fakeDefault: fakeDefault}
return core.RequireFeatures(s.ctx, func(client dns.Client) error {
v := core.MustFromContext(s.ctx)
if v.GetFeature(dns.FakeDNSEngineType()) != nil {
return nil
}
if client, ok := client.(dns.ClientWithFakeDNS); ok {
return v.AddFeature(client.AsFakeDNSEngine())
}
return nil
})
}
// Type implements common.HasType. // Type implements common.HasType.
func (*DNS) Type() interface{} { func (*DNS) Type() interface{} {
return dns.ClientType() return dns.ClientType()
@ -200,25 +244,29 @@ func (s *DNS) IsOwnLink(ctx context.Context) bool {
return inbound != nil && s.clientTags[inbound.Tag] return inbound != nil && s.clientTags[inbound.Tag]
} }
// AsFakeDNSClient implements dns.ClientWithFakeDNS.
func (s *DNS) AsFakeDNSClient() dns.Client {
return &FakeDNSClient{DNS: s}
}
// AsFakeDNSEngine implements dns.ClientWithFakeDNS.
func (s *DNS) AsFakeDNSEngine() dns.FakeDNSEngine {
return s.fakeDNSEngine
}
// LookupIP implements dns.Client. // LookupIP implements dns.Client.
func (s *DNS) LookupIP(domain string) ([]net.IP, error) { func (s *DNS) LookupIP(domain string) ([]net.IP, error) {
return s.lookupIPInternal(domain, s.ipOption) return s.lookupIPInternal(domain, dns.IPOption{IPv4Enable: true, IPv6Enable: true, FakeEnable: false})
} }
// LookupIPv4 implements dns.IPv4Lookup. // LookupIPv4 implements dns.IPv4Lookup.
func (s *DNS) LookupIPv4(domain string) ([]net.IP, error) { func (s *DNS) LookupIPv4(domain string) ([]net.IP, error) {
if option := s.ipOption.With(dns.IPOption{IPv4Enable: true}); option.IsValid() { return s.lookupIPInternal(domain, dns.IPOption{IPv4Enable: true, FakeEnable: false})
return s.lookupIPInternal(domain, option)
}
return nil, dns.ErrEmptyResponse
} }
// LookupIPv6 implements dns.IPv6Lookup. // LookupIPv6 implements dns.IPv6Lookup.
func (s *DNS) LookupIPv6(domain string) ([]net.IP, error) { func (s *DNS) LookupIPv6(domain string) ([]net.IP, error) {
if option := s.ipOption.With(dns.IPOption{IPv6Enable: true}); option.IsValid() { return s.lookupIPInternal(domain, dns.IPOption{IPv6Enable: true, FakeEnable: false})
return s.lookupIPInternal(domain, option)
}
return nil, dns.ErrEmptyResponse
} }
func (s *DNS) lookupIPInternal(domain string, option dns.IPOption) ([]net.IP, error) { func (s *DNS) lookupIPInternal(domain string, option dns.IPOption) ([]net.IP, error) {
@ -257,33 +305,20 @@ func (s *DNS) lookupIPInternal(domain string, option dns.IPOption) ([]net.IP, er
newError("failed to lookup ip for domain ", domain, " at server ", client.Name()).Base(err).WriteToLog() newError("failed to lookup ip for domain ", domain, " at server ", client.Name()).Base(err).WriteToLog()
} }
if err != context.Canceled && err != context.DeadlineExceeded && err != errExpectedIPNonMatch { if err != context.Canceled && err != context.DeadlineExceeded && err != errExpectedIPNonMatch {
return nil, err // Continues lookup for certain errors return nil, err // Only continue lookup for certain errors
} }
} }
if len(errs) == 0 {
return nil, dns.ErrEmptyResponse
}
return nil, newError("returning nil for domain ", domain).Base(errors.Combine(errs...)) return nil, newError("returning nil for domain ", domain).Base(errors.Combine(errs...))
} }
// GetIPOption implements ClientWithIPOption.
func (s *DNS) GetIPOption() *dns.IPOption {
return &s.ipOption
}
// SetQueryOption implements ClientWithIPOption.
func (s *DNS) SetQueryOption(isIPv4Enable, isIPv6Enable bool) {
s.ipOption.IPv4Enable = isIPv4Enable
s.ipOption.IPv6Enable = isIPv6Enable
}
// SetFakeDNSOption implements ClientWithIPOption.
func (s *DNS) SetFakeDNSOption(isFakeEnable bool) {
s.ipOption.FakeEnable = isFakeEnable
}
func (s *DNS) sortClients(domain string, option dns.IPOption) []*Client { func (s *DNS) sortClients(domain string, option dns.IPOption) []*Client {
clients := make([]*Client, 0, len(s.clients)) clients := make([]*Client, 0, len(s.clients))
clientUsed := make([]bool, len(s.clients)) clientUsed := make([]bool, len(s.clients))
clientNames := make([]string, 0, len(s.clients)) clientIdxs := make([]int, 0, len(s.clients))
domainRules := []string{} domainRules := []string{}
// Priority domain matching // Priority domain matching
@ -295,12 +330,12 @@ func (s *DNS) sortClients(domain string, option dns.IPOption) []*Client {
switch { switch {
case clientUsed[info.clientIdx]: case clientUsed[info.clientIdx]:
continue continue
case !option.FakeEnable && strings.EqualFold(client.Name(), "FakeDNS"): case !option.FakeEnable && isFakeDNS(client.server):
continue continue
} }
clientUsed[info.clientIdx] = true clientUsed[info.clientIdx] = true
clients = append(clients, client) clients = append(clients, client)
clientNames = append(clientNames, client.Name()) clientIdxs = append(clientIdxs, int(info.clientIdx))
} }
// Default round-robin query // Default round-robin query
@ -309,7 +344,7 @@ func (s *DNS) sortClients(domain string, option dns.IPOption) []*Client {
switch { switch {
case clientUsed[idx]: case clientUsed[idx]:
continue continue
case !option.FakeEnable && strings.EqualFold(client.Name(), "FakeDNS"): case !option.FakeEnable && isFakeDNS(client.server):
continue continue
case client.fallbackStrategy == FallbackStrategy_Disabled: case client.fallbackStrategy == FallbackStrategy_Disabled:
continue continue
@ -318,19 +353,42 @@ func (s *DNS) sortClients(domain string, option dns.IPOption) []*Client {
} }
clientUsed[idx] = true clientUsed[idx] = true
clients = append(clients, client) clients = append(clients, client)
clientNames = append(clientNames, client.Name()) clientIdxs = append(clientIdxs, idx)
} }
if len(domainRules) > 0 { if len(domainRules) > 0 {
newError("domain ", domain, " matches following rules: ", domainRules).AtDebug().WriteToLog() newError("domain ", domain, " matches following rules: ", domainRules).AtDebug().WriteToLog()
} }
if len(clientNames) > 0 { if len(clientIdxs) > 0 {
newError("domain ", domain, " will use DNS in order: ", clientNames, " ", toReqTypes(option)).AtDebug().WriteToLog() newError("domain ", domain, " will use DNS in order: ", s.formatClientNames(clientIdxs, option), " ", toReqTypes(option)).AtDebug().WriteToLog()
} }
return clients return clients
} }
func (s *DNS) formatClientNames(clientIdxs []int, option dns.IPOption) []string {
clientNames := make([]string, 0, len(clientIdxs))
counter := make(map[string]uint, len(clientIdxs))
for _, clientIdx := range clientIdxs {
client := s.clients[clientIdx]
var name string
if option.With(client.queryStrategy).FakeEnable {
name = fmt.Sprintf("%s(DNS idx:%d)", client.fakeDNS.Name(), clientIdx)
} else {
name = client.Name()
}
counter[name]++
clientNames = append(clientNames, name)
}
for idx, clientIdx := range clientIdxs {
name := clientNames[idx]
if counter[name] > 1 {
clientNames[idx] = fmt.Sprintf("%s(DNS idx:%d)", name, clientIdx)
}
}
return clientNames
}
func init() { func init() {
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return New(ctx, config.(*Config)) return New(ctx, config.(*Config))

View File

@ -226,3 +226,13 @@ L:
return ipRecord, nil return ipRecord, nil
} }
func filterIP(ips []net.Address, option dns_feature.IPOption) []net.Address {
filtered := make([]net.Address, 0, len(ips))
for _, ip := range ips {
if (ip.Family().IsIPv4() && option.IPv4Enable) || (ip.Family().IsIPv6() && option.IPv6Enable) {
filtered = append(filtered, ip)
}
}
return filtered
}

87
app/dns/fakedns.go Normal file
View File

@ -0,0 +1,87 @@
//go:build !confonly
// +build !confonly
package dns
import (
fakedns "github.com/v2fly/v2ray-core/v5/app/dns/fakedns"
"github.com/v2fly/v2ray-core/v5/common/net"
"github.com/v2fly/v2ray-core/v5/features/dns"
)
// FakeDNSClient is an implementation of dns.Client with FakeDNS enabled.
type FakeDNSClient struct {
*DNS
}
// LookupIP implements dns.Client.
func (s *FakeDNSClient) LookupIP(domain string) ([]net.IP, error) {
return s.lookupIPInternal(domain, dns.IPOption{IPv4Enable: true, IPv6Enable: true, FakeEnable: true})
}
// LookupIPv4 implements dns.IPv4Lookup.
func (s *FakeDNSClient) LookupIPv4(domain string) ([]net.IP, error) {
return s.lookupIPInternal(domain, dns.IPOption{IPv4Enable: true, FakeEnable: true})
}
// LookupIPv6 implements dns.IPv6Lookup.
func (s *FakeDNSClient) LookupIPv6(domain string) ([]net.IP, error) {
return s.lookupIPInternal(domain, dns.IPOption{IPv6Enable: true, FakeEnable: true})
}
// FakeDNSEngine is an implementation of dns.FakeDNSEngine based on a fully functional DNS.
type FakeDNSEngine struct {
dns *DNS
fakeHolders *fakedns.HolderMulti
fakeDefault *fakedns.HolderMulti
}
// Type implements common.HasType.
func (*FakeDNSEngine) Type() interface{} {
return dns.FakeDNSEngineType()
}
// Start implements common.Runnable.
func (f *FakeDNSEngine) Start() error {
return f.fakeHolders.Start()
}
// Close implements common.Closable.
func (f *FakeDNSEngine) Close() error {
return f.fakeHolders.Close()
}
// GetFakeIPForDomain implements dns.FakeDNSEngine.
func (f *FakeDNSEngine) GetFakeIPForDomain(domain string) []net.Address {
return f.GetFakeIPForDomain3(domain, true, true)
}
// GetDomainFromFakeDNS implements dns.FakeDNSEngine.
func (f *FakeDNSEngine) GetDomainFromFakeDNS(ip net.Address) string {
return f.fakeHolders.GetDomainFromFakeDNS(ip)
}
// IsIPInIPPool implements dns.FakeDNSEngineRev0.
func (f *FakeDNSEngine) IsIPInIPPool(ip net.Address) bool {
return f.fakeHolders.IsIPInIPPool(ip)
}
// GetFakeIPForDomain3 implements dns.FakeDNSEngineRev0.
func (f *FakeDNSEngine) GetFakeIPForDomain3(domain string, IPv4 bool, IPv6 bool) []net.Address { // nolint: gocritic
option := dns.IPOption{IPv4Enable: IPv4, IPv6Enable: IPv6, FakeEnable: true}
for _, client := range f.dns.sortClients(domain, option) {
fakeServer, ok := client.fakeDNS.(*FakeDNSServer)
if !ok {
continue
}
fakeEngine, ok := fakeServer.fakeDNSEngine.(dns.FakeDNSEngineRev0)
if !ok {
return filterIP(fakeServer.fakeDNSEngine.GetFakeIPForDomain(domain), option)
}
return fakeEngine.GetFakeIPForDomain3(domain, IPv4, IPv6)
}
if f.fakeDefault != nil {
return f.fakeDefault.GetFakeIPForDomain3(domain, IPv4, IPv6)
}
return nil
}

View File

@ -42,7 +42,7 @@ func (fkdns *Holder) GetFakeIPForDomain3(domain string, ipv4, ipv6 bool) []net.A
} }
func (*Holder) Type() interface{} { func (*Holder) Type() interface{} {
return (*dns.FakeDNSEngine)(nil) return dns.FakeDNSEngineType()
} }
func (fkdns *Holder) Start() error { func (fkdns *Holder) Start() error {
@ -147,8 +147,6 @@ func (fkdns *Holder) GetDomainFromFakeDNS(ip net.Address) string {
type HolderMulti struct { type HolderMulti struct {
holders []*Holder holders []*Holder
config *FakeDnsPoolMulti
} }
func (h *HolderMulti) IsIPInIPPool(ip net.Address) bool { func (h *HolderMulti) IsIPInIPPool(ip net.Address) bool {
@ -188,18 +186,67 @@ func (h *HolderMulti) GetDomainFromFakeDNS(ip net.Address) string {
return "" return ""
} }
func (h *HolderMulti) IsEmpty() bool {
return len(h.holders) == 0
}
func (h *HolderMulti) AddPool(poolConfig *FakeDnsPool) (*Holder, error) {
_, newIPRange, err := gonet.ParseCIDR(poolConfig.IpPool)
if err != nil {
return nil, err
}
running := false
for _, v := range h.holders {
var ipRange *gonet.IPNet
if v.ipRange != nil {
ipRange = v.ipRange
running = true
} else {
_, ipRange, err = gonet.ParseCIDR(v.config.IpPool)
if err != nil {
return nil, err
}
}
if ipRange.String() == newIPRange.String() {
return v, nil
}
if ipRange.Contains(newIPRange.IP) || newIPRange.Contains(ipRange.IP) {
return nil, newError("Trying to add ip pool ", newIPRange, " that overlaps with existing ip pool ", ipRange)
}
}
holder, err := NewFakeDNSHolderConfigOnly(poolConfig)
if err != nil {
return nil, err
}
if running {
if err := holder.Start(); err != nil {
return nil, err
}
}
h.holders = append(h.holders, holder)
return holder, nil
}
func (h *HolderMulti) AddPoolMulti(poolMultiConfig *FakeDnsPoolMulti) (*HolderMulti, error) {
holderMulti := &HolderMulti{}
for _, poolConfig := range poolMultiConfig.Pools {
pool, err := h.AddPool(poolConfig)
if err != nil {
return nil, err
}
holderMulti.holders = append(holderMulti.holders, pool)
}
return holderMulti, nil // Returned holderMulti holds references to pools managed by `h`
}
func (h *HolderMulti) Type() interface{} { func (h *HolderMulti) Type() interface{} {
return (*dns.FakeDNSEngine)(nil) return dns.FakeDNSEngineType()
} }
func (h *HolderMulti) Start() error { func (h *HolderMulti) Start() error {
for _, v := range h.holders { for _, v := range h.holders {
if v.config != nil && v.config.IpPool != "" && v.config.LruSize != 0 { if err := v.Start(); err != nil {
if err := v.Start(); err != nil { return newError("Cannot start all fake dns pools").Base(err)
return newError("Cannot start all fake dns pools").Base(err)
}
} else {
return newError("invalid fakeDNS setting")
} }
} }
return nil return nil
@ -214,20 +261,19 @@ func (h *HolderMulti) Close() error {
return nil return nil
} }
func (h *HolderMulti) createHolderGroups() error { func (h *HolderMulti) createHolderGroups(conf *FakeDnsPoolMulti) error {
for _, v := range h.config.Pools { for _, pool := range conf.Pools {
holder, err := NewFakeDNSHolderConfigOnly(v) _, err := h.AddPool(pool)
if err != nil { if err != nil {
return err return err
} }
h.holders = append(h.holders, holder)
} }
return nil return nil
} }
func NewFakeDNSHolderMulti(conf *FakeDnsPoolMulti) (*HolderMulti, error) { func NewFakeDNSHolderMulti(conf *FakeDnsPoolMulti) (*HolderMulti, error) {
holderMulti := &HolderMulti{nil, conf} holderMulti := &HolderMulti{}
if err := holderMulti.createHolderGroups(); err != nil { if err := holderMulti.createHolderGroups(conf); err != nil {
return nil, err return nil, err
} }
return holderMulti, nil return holderMulti, nil

View File

@ -217,3 +217,99 @@ func TestFakeDNSMulti(t *testing.T) {
}) })
}) })
} }
func TestFakeDNSMultiAddPool(t *testing.T) {
runTest := func(runTestBeforeStart bool) {
fakeMulti, err := NewFakeDNSHolderMulti(&FakeDnsPoolMulti{
Pools: []*FakeDnsPool{{
IpPool: "240.0.0.0/12",
LruSize: 256,
}, {
IpPool: "fddd:c5b4:ff5f:f4f0::/64",
LruSize: 256,
}},
})
common.Must(err)
if !runTestBeforeStart {
err = fakeMulti.Start()
common.Must(err)
}
t.Run("ipv4_return_existing", func(t *testing.T) {
pool, err := fakeMulti.AddPool(&FakeDnsPool{
IpPool: "240.0.0.1/12",
LruSize: 256,
})
common.Must(err)
if pool != fakeMulti.holders[0] {
t.Error("HolderMulti.AddPool not returning same holder for existing IPv4 pool")
}
})
t.Run("ipv6_return_existing", func(t *testing.T) {
pool, err := fakeMulti.AddPool(&FakeDnsPool{
IpPool: "fddd:c5b4:ff5f:f4f0::1/64",
LruSize: 256,
})
common.Must(err)
if pool != fakeMulti.holders[1] {
t.Error("HolderMulti.AddPool not returning same holder for existing IPv6 pool")
}
})
t.Run("ipv4_reject_overlap", func(t *testing.T) {
_, err := fakeMulti.AddPool(&FakeDnsPool{
IpPool: "240.8.0.0/13",
LruSize: 256,
})
if err == nil {
t.Error("HolderMulti.AddPool not rejecting IPv4 pool that is subnet of existing ones")
}
_, err = fakeMulti.AddPool(&FakeDnsPool{
IpPool: "240.0.0.0/11",
LruSize: 256,
})
if err == nil {
t.Error("HolderMulti.AddPool not rejecting IPv4 pool that contains existing ones")
}
})
t.Run("new_pool", func(t *testing.T) {
pool, err := fakeMulti.AddPool(&FakeDnsPool{
IpPool: "192.168.168.0/16",
LruSize: 256,
})
common.Must(err)
if pool != fakeMulti.holders[2] {
t.Error("HolderMulti.AddPool not creating new holder for new IPv4 pool")
}
})
t.Run("add_pool_multi", func(t *testing.T) {
pools, err := fakeMulti.AddPoolMulti(&FakeDnsPoolMulti{
Pools: []*FakeDnsPool{{
IpPool: "192.168.168.0/16",
LruSize: 256,
}, {
IpPool: "2001:1111::/64",
LruSize: 256,
}},
})
common.Must(err)
if len(pools.holders) != 2 {
t.Error("HolderMulti.AddPoolMutli not returning holderMulti that has the same length as passed PoolMulti config")
}
if pools.holders[0] != fakeMulti.holders[2] {
t.Error("HolderMulti.AddPoolMulti not returning same holder for existing IPv4 pool 192.168.168.0/16")
}
if pools.holders[1] != fakeMulti.holders[3] {
t.Error("HolderMulti.AddPoolMulti not creating new holder for new IPv6 pool 2001:1111::/64")
}
})
if runTestBeforeStart {
err = fakeMulti.Start()
common.Must(err)
}
}
t.Run("addPoolBeforeStart", func(t *testing.T) {
runTest(true)
})
t.Run("addPoolAfterStart", func(t *testing.T) {
runTest(false)
})
}

249
app/dns/fakedns_test.go Normal file
View File

@ -0,0 +1,249 @@
package dns_test
import (
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/miekg/dns"
"google.golang.org/protobuf/types/known/anypb"
core "github.com/v2fly/v2ray-core/v5"
"github.com/v2fly/v2ray-core/v5/app/dispatcher"
. "github.com/v2fly/v2ray-core/v5/app/dns"
"github.com/v2fly/v2ray-core/v5/app/dns/fakedns"
"github.com/v2fly/v2ray-core/v5/app/policy"
"github.com/v2fly/v2ray-core/v5/app/proxyman"
"github.com/v2fly/v2ray-core/v5/common"
"github.com/v2fly/v2ray-core/v5/common/net"
"github.com/v2fly/v2ray-core/v5/common/serial"
feature_dns "github.com/v2fly/v2ray-core/v5/features/dns"
"github.com/v2fly/v2ray-core/v5/proxy/freedom"
"github.com/v2fly/v2ray-core/v5/testing/servers/udp"
)
func TestFakeDNS(t *testing.T) {
port := udp.PickPort()
dnsServer := dns.Server{
Addr: "127.0.0.1:" + port.String(),
Net: "udp",
Handler: &staticHandler{},
UDPSize: 1200,
}
go dnsServer.ListenAndServe()
time.Sleep(time.Second)
config := &core.Config{
App: []*anypb.Any{
serial.ToTypedMessage(&Config{
NameServer: []*NameServer{
{ // "fakedns"
Address: &net.Endpoint{
Network: net.Network_UDP,
Address: &net.IPOrDomain{
Address: &net.IPOrDomain_Domain{
Domain: "fakedns",
},
},
Port: uint32(53),
},
},
{ // { "address": "127.0.0.1", "port": "<port>", "domains": ["domain:google.com"], "fakedns": "198.19.0.0/16", "fallbackStrategy": "disabled" }
Address: &net.Endpoint{
Network: net.Network_UDP,
Address: &net.IPOrDomain{
Address: &net.IPOrDomain_Ip{
Ip: []byte{127, 0, 0, 1},
},
},
Port: uint32(port),
},
PrioritizedDomain: []*NameServer_PriorityDomain{
{Type: DomainMatchingType_Subdomain, Domain: "google.com"},
},
FakeDns: &fakedns.FakeDnsPoolMulti{
Pools: []*fakedns.FakeDnsPool{
{IpPool: "198.19.0.0/16", LruSize: 256},
},
},
FallbackStrategy: FallbackStrategy_Disabled.Enum(),
},
},
FakeDns: &fakedns.FakeDnsPoolMulti{ // "fakedns": "198.18.0.0/16"
Pools: []*fakedns.FakeDnsPool{
{IpPool: "198.18.0.0/16", LruSize: 256},
},
},
}),
serial.ToTypedMessage(&dispatcher.Config{}),
serial.ToTypedMessage(&proxyman.OutboundConfig{}),
serial.ToTypedMessage(&policy.Config{}),
},
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
},
}
v, err := core.New(config)
common.Must(err)
common.Must(v.Start())
dnsClient := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
fakeClient := dnsClient.(feature_dns.ClientWithFakeDNS).AsFakeDNSClient()
var fakeIPForFacebook net.IP
var fakeIPForGoogle net.IP
{ // Lookup facebook.com with Fake Client will return 198.18.0.0/16 (global fake pool)
ips, err := fakeClient.LookupIP("facebook.com")
if err != nil {
t.Fatal("unexpected error: ", err)
}
for _, ip := range ips {
if !(&net.IPNet{IP: net.IP{198, 18, 0, 0}, Mask: net.CIDRMask(16, 8*net.IPv4len)}).Contains(ip) {
t.Fatal("Lookup facebook.com with fake client not in global pool 198.18.0.0/16")
}
}
fakeIPForFacebook = ips[0]
}
{ // Lookup facebook.com with Normal Client with return empty record (because UDP server matching "domain:google.com" are configured with fallback disabled)
_, err := dnsClient.LookupIP("facebook.com")
if err != feature_dns.ErrEmptyResponse {
t.Fatal("Lookup facebook.com with normal client not returning empty response")
}
}
{ // Lookup google.com with Fake Client will return 198.19.0.0/16 (local fake pool)
ips, err := fakeClient.LookupIP("google.com")
if err != nil {
t.Fatal("unexpected error: ", err)
}
for _, ip := range ips {
if !(&net.IPNet{IP: net.IP{198, 19, 0, 0}, Mask: net.CIDRMask(16, 8*net.IPv4len)}).Contains(ip) {
t.Fatal("Lookup google.com with fake client not in global pool 198.19.0.0/16")
}
}
fakeIPForGoogle = ips[0]
}
{ // Lookup google.com with Normal Client will return 8.8.8.8
ips, err := dnsClient.LookupIP("google.com")
if err != nil {
t.Fatal("unexpected error: ", err)
}
if r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != "" {
t.Fatal("Lookup google.com with normal client not returning 8.8.8.8")
}
}
fakeEngine := dnsClient.(feature_dns.ClientWithFakeDNS).AsFakeDNSEngine().(feature_dns.FakeDNSEngineRev0)
{
if !fakeEngine.IsIPInIPPool(net.IPAddress(fakeIPForFacebook)) {
t.Fatal("Fake IP of domain facebook.com not in FakeDNSEngine's pool.")
}
if !fakeEngine.IsIPInIPPool(net.IPAddress(fakeIPForGoogle)) {
t.Fatal("Fake IP of domain google.com not in FakeDNSEngine's pool.")
}
}
{
if domain := fakeEngine.GetDomainFromFakeDNS(net.IPAddress(fakeIPForFacebook)); domain != "facebook.com" {
t.Fatal("Recover fake IP to get domain facebook.com failed.")
}
if domain := fakeEngine.GetDomainFromFakeDNS(net.IPAddress(fakeIPForGoogle)); domain != "google.com" {
t.Fatal("Recover fake IP to get domain google.com failed.")
}
}
{
ips := fakeEngine.GetFakeIPForDomain("api.google.com")
for _, ip := range ips {
if !(&net.IPNet{IP: net.IP{198, 19, 0, 0}, Mask: net.CIDRMask(16, 8*net.IPv4len)}).Contains(ip.IP()) {
t.Fatal("Fake IP for api.google.com not in local pool 198.19.0.0/16")
}
}
}
{
ips := fakeEngine.GetFakeIPForDomain3("v2fly.org", true, false)
for _, ip := range ips {
if !(&net.IPNet{IP: net.IP{198, 18, 0, 0}, Mask: net.CIDRMask(16, 8*net.IPv4len)}).Contains(ip.IP()) {
t.Fatal("Fake IP for v2fly.org not in global pool 198.18.0.0/16")
}
}
}
}
func TestFakeDNSEmptyGlobalConfig(t *testing.T) {
config := &core.Config{
App: []*anypb.Any{
serial.ToTypedMessage(&Config{
NameServer: []*NameServer{
{ // "fakedns"
Address: &net.Endpoint{
Network: net.Network_UDP,
Address: &net.IPOrDomain{
Address: &net.IPOrDomain_Domain{
Domain: "fakedns",
},
},
},
QueryStrategy: QueryStrategy_USE_IP4.Enum(),
},
{ // "localhost"
Address: &net.Endpoint{
Network: net.Network_UDP,
Address: &net.IPOrDomain{
Address: &net.IPOrDomain_Domain{
Domain: "localhost",
},
},
},
QueryStrategy: QueryStrategy_USE_IP6.Enum(),
PrioritizedDomain: []*NameServer_PriorityDomain{
{Type: DomainMatchingType_Subdomain, Domain: "google.com"},
},
FakeDns: &fakedns.FakeDnsPoolMulti{Pools: []*fakedns.FakeDnsPool{}}, // "fakedns": true
},
},
}),
serial.ToTypedMessage(&dispatcher.Config{}),
serial.ToTypedMessage(&proxyman.OutboundConfig{}),
serial.ToTypedMessage(&policy.Config{}),
},
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
},
}
v, err := core.New(config)
common.Must(err)
common.Must(v.Start())
dnsClient := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
fakeClient := dnsClient.(feature_dns.ClientWithFakeDNS).AsFakeDNSClient()
{ // Lookup facebook.com will return 198.18.0.0/15 (default IPv4 pool)
ips, err := fakeClient.LookupIP("facebook.com")
if err != nil {
t.Fatal("unexpected error: ", err)
}
for _, ip := range ips {
if !(&net.IPNet{IP: net.IP{198, 18, 0, 0}, Mask: net.CIDRMask(15, 8*net.IPv4len)}).Contains(ip) {
t.Fatal("Lookup facebook.com with fake client not in default IPv4 pool 198.18.0.0/15")
}
}
}
{ // Lookup google.com will return fc00::/18 (default IPv6 pool)
ips, err := fakeClient.LookupIP("google.com")
if err != nil {
t.Fatal("unexpected error: ", err)
}
for _, ip := range ips {
if !(&net.IPNet{IP: net.IP{0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Mask: net.CIDRMask(18, 8*net.IPv6len)}).Contains(ip) {
t.Fatal("Lookup google.com with fake client not in default IPv6 pool fc00::/18")
}
}
}
}

View File

@ -67,16 +67,6 @@ func NewStaticHosts(hosts []*HostMapping, legacy map[string]*net.IPOrDomain) (*S
return sh, nil return sh, nil
} }
func filterIP(ips []net.Address, option dns.IPOption) []net.Address {
filtered := make([]net.Address, 0, len(ips))
for _, ip := range ips {
if (ip.Family().IsIPv4() && option.IPv4Enable) || (ip.Family().IsIPv6() && option.IPv6Enable) {
filtered = append(filtered, ip)
}
}
return filtered
}
func (h *StaticHosts) lookupInternal(domain string) []net.Address { func (h *StaticHosts) lookupInternal(domain string) []net.Address {
var ips []net.Address var ips []net.Address
for _, id := range h.matchers.Match(domain) { for _, id := range h.matchers.Match(domain) {

View File

@ -7,6 +7,7 @@ import (
"time" "time"
core "github.com/v2fly/v2ray-core/v5" core "github.com/v2fly/v2ray-core/v5"
"github.com/v2fly/v2ray-core/v5/app/dns/fakedns"
"github.com/v2fly/v2ray-core/v5/app/router" "github.com/v2fly/v2ray-core/v5/app/router"
"github.com/v2fly/v2ray-core/v5/common/errors" "github.com/v2fly/v2ray-core/v5/common/errors"
"github.com/v2fly/v2ray-core/v5/common/net" "github.com/v2fly/v2ray-core/v5/common/net"
@ -36,41 +37,48 @@ type Client struct {
domains []string domains []string
expectIPs []*router.GeoIPMatcher expectIPs []*router.GeoIPMatcher
fakeDNS Server
} }
var errExpectedIPNonMatch = errors.New("expectIPs not match") var errExpectedIPNonMatch = errors.New("expectIPs not match")
// NewServer creates a name server object according to the network destination url. // NewServer creates a name server object according to the network destination url.
func NewServer(dest net.Destination, dispatcher routing.Dispatcher) (Server, error) { func NewServer(ctx context.Context, dest net.Destination, onCreated func(Server) error) error {
onCreatedWithError := func(server Server, err error) error {
if err != nil {
return err
}
return onCreated(server)
}
if address := dest.Address; address.Family().IsDomain() { if address := dest.Address; address.Family().IsDomain() {
u, err := url.Parse(address.Domain()) u, err := url.Parse(address.Domain())
if err != nil { if err != nil {
return nil, err return err
} }
switch { switch {
case strings.EqualFold(u.String(), "localhost"): case strings.EqualFold(u.String(), "localhost"):
return NewLocalNameServer(), nil return onCreated(NewLocalNameServer())
case strings.EqualFold(u.Scheme, "https"): // DOH Remote mode
return NewDoHNameServer(u, dispatcher)
case strings.EqualFold(u.Scheme, "https+local"): // DOH Local mode
return NewDoHLocalNameServer(u), nil
case strings.EqualFold(u.Scheme, "quic+local"): // DNS-over-QUIC Local mode
return NewQUICNameServer(u)
case strings.EqualFold(u.Scheme, "tcp"): // DNS-over-TCP Remote mode
return NewTCPNameServer(u, dispatcher)
case strings.EqualFold(u.Scheme, "tcp+local"): // DNS-over-TCP Local mode
return NewTCPLocalNameServer(u)
case strings.EqualFold(u.String(), "fakedns"): case strings.EqualFold(u.String(), "fakedns"):
return NewFakeDNSServer(), nil return core.RequireFeatures(ctx, func(fakedns dns.FakeDNSEngine) error { return onCreated(NewFakeDNSServer(fakedns)) })
case strings.EqualFold(u.Scheme, "https"): // DOH Remote mode
return core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error { return onCreatedWithError(NewDoHNameServer(u, dispatcher)) })
case strings.EqualFold(u.Scheme, "https+local"): // DOH Local mode
return onCreated(NewDoHLocalNameServer(u))
case strings.EqualFold(u.Scheme, "tcp"): // DNS-over-TCP Remote mode
return core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error { return onCreatedWithError(NewTCPNameServer(u, dispatcher)) })
case strings.EqualFold(u.Scheme, "tcp+local"): // DNS-over-TCP Local mode
return onCreatedWithError(NewTCPLocalNameServer(u))
case strings.EqualFold(u.Scheme, "quic+local"): // DNS-over-QUIC Local mode
return onCreatedWithError(NewQUICNameServer(u))
} }
} }
if dest.Network == net.Network_Unknown { if dest.Network == net.Network_Unknown {
dest.Network = net.Network_UDP dest.Network = net.Network_UDP
} }
if dest.Network == net.Network_UDP { // UDP classic DNS mode if dest.Network == net.Network_UDP { // UDP classic DNS mode
return NewClassicNameServer(dest, dispatcher), nil return core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error { return onCreated(NewClassicNameServer(dest, dispatcher)) })
} }
return nil, newError("No available name server could be created from ", dest).AtWarning() return newError("No available name server could be created from ", dest).AtWarning()
} }
// NewClient creates a DNS client managing a name server with client IP, domain rules and expected IPs. // NewClient creates a DNS client managing a name server with client IP, domain rules and expected IPs.
@ -78,12 +86,7 @@ func NewClient(ctx context.Context, ns *NameServer, dns *Config) (*Client, error
client := &Client{} client := &Client{}
// Create DNS server instance // Create DNS server instance
err := core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error { err := NewServer(ctx, ns.Address.AsDestination(), func(server Server) error {
// Create a new server for each client for now
server, err := NewServer(ns.Address.AsDestination(), dispatcher)
if err != nil {
return newError("failed to create nameserver").Base(err).AtWarning()
}
client.server = server client.server = server
return nil return nil
}) })
@ -130,6 +133,27 @@ func NewClient(ctx context.Context, ns *NameServer, dns *Config) (*Client, error
*ns.FallbackStrategy = FallbackStrategy_DisabledIfAnyMatch *ns.FallbackStrategy = FallbackStrategy_DisabledIfAnyMatch
} }
} }
if (ns.FakeDns != nil && len(ns.FakeDns.Pools) == 0) || // Use globally configured fake ip pool if: 1. `fakedns` config is set, but empty(represents { "fakedns": true } in JSON settings);
ns.FakeDns == nil && strings.EqualFold(ns.Address.Address.GetDomain(), "fakedns") { // 2. `fakedns` config not set, but server address is `fakedns`(represents { "address": "fakedns" } in JSON settings).
if dns.FakeDns != nil {
ns.FakeDns = dns.FakeDns
} else {
ns.FakeDns = &fakedns.FakeDnsPoolMulti{}
queryStrategy := toIPOption(*ns.QueryStrategy)
if queryStrategy.IPv4Enable {
ns.FakeDns.Pools = append(ns.FakeDns.Pools, &fakedns.FakeDnsPool{
IpPool: "198.18.0.0/15",
LruSize: 65535,
})
}
if queryStrategy.IPv6Enable {
ns.FakeDns.Pools = append(ns.FakeDns.Pools, &fakedns.FakeDnsPool{
IpPool: "fc00::/18",
LruSize: 65535,
})
}
}
}
// Priotize local domains with specific TLDs or without any dot to local DNS // Priotize local domains with specific TLDs or without any dot to local DNS
if strings.EqualFold(ns.Address.Address.GetDomain(), "localhost") { if strings.EqualFold(ns.Address.Address.GetDomain(), "localhost") {
@ -154,21 +178,25 @@ func (c *Client) Name() string {
return c.server.Name() return c.server.Name()
} }
// QueryIP send DNS query to the name server with the client's IP. // QueryIP send DNS query to the name server with the client's IP and IP options.
func (c *Client) QueryIP(ctx context.Context, domain string, option dns.IPOption) ([]net.IP, error) { func (c *Client) QueryIP(ctx context.Context, domain string, option dns.IPOption) ([]net.IP, error) {
queryOption := option.With(c.queryStrategy) queryOption := option.With(c.queryStrategy)
if !queryOption.IsValid() { if !queryOption.IsValid() {
newError(c.server.Name(), " returns empty answer: ", domain, ". ", toReqTypes(option)).AtInfo().WriteToLog() newError(c.server.Name(), " returns empty answer: ", domain, ". ", toReqTypes(option)).AtInfo().WriteToLog()
return nil, dns.ErrEmptyResponse return nil, dns.ErrEmptyResponse
} }
server := c.server
if queryOption.FakeEnable && c.fakeDNS != nil {
server = c.fakeDNS
}
disableCache := c.cacheStrategy == CacheStrategy_CacheDisabled disableCache := c.cacheStrategy == CacheStrategy_CacheDisabled
ctx = session.ContextWithInbound(ctx, &session.Inbound{Tag: c.tag}) ctx = session.ContextWithInbound(ctx, &session.Inbound{Tag: c.tag})
ctx, cancel := context.WithTimeout(ctx, 4*time.Second) ctx, cancel := context.WithTimeout(ctx, 4*time.Second)
ips, err := c.server.QueryIP(ctx, domain, c.clientIP, queryOption, disableCache) ips, err := server.QueryIP(ctx, domain, c.clientIP, queryOption, disableCache)
cancel() cancel()
if err != nil { if err != nil || queryOption.FakeEnable {
return ips, err return ips, err
} }
return c.MatchExpectedIPs(domain, ips) return c.MatchExpectedIPs(domain, ips)

View File

@ -15,15 +15,18 @@ type FakeDNSServer struct {
fakeDNSEngine dns.FakeDNSEngine fakeDNSEngine dns.FakeDNSEngine
} }
func NewFakeDNSServer() *FakeDNSServer { func NewFakeDNSServer(fakeDNSEngine dns.FakeDNSEngine) *FakeDNSServer {
return &FakeDNSServer{} return &FakeDNSServer{fakeDNSEngine: fakeDNSEngine}
} }
func (FakeDNSServer) Name() string { func (FakeDNSServer) Name() string {
return "FakeDNS" return "fakedns"
} }
func (f *FakeDNSServer) QueryIP(ctx context.Context, domain string, _ net.IP, opt dns.IPOption, _ bool) ([]net.IP, error) { func (f *FakeDNSServer) QueryIP(ctx context.Context, domain string, _ net.IP, opt dns.IPOption, _ bool) ([]net.IP, error) {
if !opt.FakeEnable {
return nil, nil // Returning empty ip record with no error will continue DNS lookup, effectively indicating that this server is disabled.
}
if f.fakeDNSEngine == nil { if f.fakeDNSEngine == nil {
if err := core.RequireFeatures(ctx, func(fd dns.FakeDNSEngine) { if err := core.RequireFeatures(ctx, func(fd dns.FakeDNSEngine) {
f.fakeDNSEngine = fd f.fakeDNSEngine = fd
@ -35,7 +38,7 @@ func (f *FakeDNSServer) QueryIP(ctx context.Context, domain string, _ net.IP, op
if fkr0, ok := f.fakeDNSEngine.(dns.FakeDNSEngineRev0); ok { if fkr0, ok := f.fakeDNSEngine.(dns.FakeDNSEngineRev0); ok {
ips = fkr0.GetFakeIPForDomain3(domain, opt.IPv4Enable, opt.IPv6Enable) ips = fkr0.GetFakeIPForDomain3(domain, opt.IPv4Enable, opt.IPv6Enable)
} else { } else {
ips = f.fakeDNSEngine.GetFakeIPForDomain(domain) ips = filterIP(f.fakeDNSEngine.GetFakeIPForDomain(domain), opt)
} }
netIP, err := toNetIP(ips) netIP, err := toNetIP(ips)
@ -50,3 +53,8 @@ func (f *FakeDNSServer) QueryIP(ctx context.Context, domain string, _ net.IP, op
} }
return nil, dns.ErrEmptyResponse return nil, dns.ErrEmptyResponse
} }
func isFakeDNS(server Server) bool {
_, ok := server.(*FakeDNSServer)
return ok
}

View File

@ -19,6 +19,7 @@ var (
ListenUDP = net.ListenUDP ListenUDP = net.ListenUDP
ListenUnix = net.ListenUnix ListenUnix = net.ListenUnix
LookupIP = net.LookupIP LookupIP = net.LookupIP
ParseCIDR = net.ParseCIDR
ParseIP = net.ParseIP ParseIP = net.ParseIP
ResolveUDPAddr = net.ResolveUDPAddr ResolveUDPAddr = net.ResolveUDPAddr
ResolveUnixAddr = net.ResolveUnixAddr ResolveUnixAddr = net.ResolveUnixAddr

View File

@ -50,18 +50,30 @@ type IPv6Lookup interface {
LookupIPv6(domain string) ([]net.IP, error) LookupIPv6(domain string) ([]net.IP, error)
} }
// ClientWithIPOption is an optional feature for querying DNS information. // LookupIPWithOption is a helper function for querying DNS information from a dns.Client with dns.IPOption.
// //
// v2ray:api:beta // v2ray:api:beta
type ClientWithIPOption interface { func LookupIPWithOption(client Client, domain string, option IPOption) ([]net.IP, error) {
// GetIPOption returns IPOption for the DNS client. if option.FakeEnable {
GetIPOption() *IPOption if clientWithFakeDNS, ok := client.(ClientWithFakeDNS); ok {
client = clientWithFakeDNS.AsFakeDNSClient()
// SetQueryOption sets IPv4Enable and IPv6Enable for the DNS client. }
SetQueryOption(isIPv4Enable, isIPv6Enable bool) }
if option.IPv4Enable && !option.IPv6Enable {
// SetFakeDNSOption sets FakeEnable option for DNS client. if ipv4Lookup, ok := client.(IPv4Lookup); ok {
SetFakeDNSOption(isFakeEnable bool) return ipv4Lookup.LookupIPv4(domain)
} else {
return nil, errors.New("dns.Client doesn't implement IPv4Lookup")
}
}
if option.IPv6Enable && !option.IPv4Enable {
if ipv6Lookup, ok := client.(IPv6Lookup); ok {
return ipv6Lookup.LookupIPv6(domain)
} else {
return nil, errors.New("dns.Client doesn't implement IPv6Lookup")
}
}
return client.LookupIP(domain)
} }
// ClientType returns the type of Client interface. Can be used for implementing common.HasType. // ClientType returns the type of Client interface. Can be used for implementing common.HasType.

View File

@ -5,14 +5,46 @@ import (
"github.com/v2fly/v2ray-core/v5/features" "github.com/v2fly/v2ray-core/v5/features"
) )
// FakeDNSEngine is a V2Ray feature for converting between domain and fake IPs.
//
// v2ray:api:beta
type FakeDNSEngine interface { type FakeDNSEngine interface {
features.Feature features.Feature
// GetFakeIPForDomain returns fake IP addresses for the given domain, and registers the domain with the returned IPs.
GetFakeIPForDomain(domain string) []net.Address GetFakeIPForDomain(domain string) []net.Address
// GetDomainFromFakeDNS returns the bound domain name for the given fake IP.
GetDomainFromFakeDNS(ip net.Address) string GetDomainFromFakeDNS(ip net.Address) string
} }
// FakeDNSEngineRev0 adds additional APIs for FakeDNSEngine.
//
// v2ray:api:beta
type FakeDNSEngineRev0 interface { type FakeDNSEngineRev0 interface {
FakeDNSEngine FakeDNSEngine
// IsIPInIPPool tests whether the given IP address resides in managed fake IP pools.
IsIPInIPPool(ip net.Address) bool IsIPInIPPool(ip net.Address) bool
GetFakeIPForDomain3(domain string, IPv4, IPv6 bool) []net.Address
// GetFakeIPForDomain3 registers and returns fake IP addresses for the given domain in IPv4 and/or IPv6.
GetFakeIPForDomain3(domain string, IPv4 bool, IPv6 bool) []net.Address
}
// ClientWithFakeDNS is an optional feature for utilizing FakeDNS feature of DNS client.
//
// v2ray:api:beta
type ClientWithFakeDNS interface {
// AsFakeDNSClient converts the client to dns.Client that enables FakeDNS querying option.
AsFakeDNSClient() Client
// AsFakeDNSEngine converts the client to dns.FakeDNSEngine that could serve FakeDNSEngine feature.
AsFakeDNSEngine() FakeDNSEngine
}
// FakeDNSEngineType returns the type of FakeDNSEngine interface. Can be used for implementing common.HasType.
//
// v2ray:api:beta
func FakeDNSEngineType() interface{} {
return (*FakeDNSEngine)(nil)
} }

View File

@ -26,35 +26,7 @@ func (ctx *ResolvableContext) GetTargetIPs() []net.IP {
} }
if domain := ctx.GetTargetDomain(); len(domain) != 0 { if domain := ctx.GetTargetDomain(); len(domain) != 0 {
lookupFunc := ctx.dnsClient.LookupIP ips, err := ctx.dnsClient.LookupIP(domain)
ipOption := &dns.IPOption{
IPv4Enable: true,
IPv6Enable: true,
}
if c, ok := ctx.dnsClient.(dns.ClientWithIPOption); ok {
ipOption = c.GetIPOption()
c.SetFakeDNSOption(false) // Skip FakeDNS.
} else {
newError("ctx.dnsClient doesn't implement ClientWithIPOption").AtDebug().WriteToLog()
}
switch {
case ipOption.IPv4Enable && !ipOption.IPv6Enable:
if lookupIPv4, ok := ctx.dnsClient.(dns.IPv4Lookup); ok {
lookupFunc = lookupIPv4.LookupIPv4
} else {
newError("ctx.dnsClient doesn't implement IPv4Lookup. Use LookupIP instead.").AtDebug().WriteToLog()
}
case !ipOption.IPv4Enable && ipOption.IPv6Enable:
if lookupIPv6, ok := ctx.dnsClient.(dns.IPv6Lookup); ok {
lookupFunc = lookupIPv6.LookupIPv6
} else {
newError("ctx.dnsClient doesn't implement IPv6Lookup. Use LookupIP instead.").AtDebug().WriteToLog()
}
}
ips, err := lookupFunc(domain)
if err == nil { if err == nil {
ctx.resolvedIPs = ips ctx.resolvedIPs = ips
return ips return ips

View File

@ -9,6 +9,7 @@ import (
"strings" "strings"
"github.com/v2fly/v2ray-core/v5/app/dns" "github.com/v2fly/v2ray-core/v5/app/dns"
"github.com/v2fly/v2ray-core/v5/app/dns/fakedns"
"github.com/v2fly/v2ray-core/v5/app/router/routercommon" "github.com/v2fly/v2ray-core/v5/app/router/routercommon"
"github.com/v2fly/v2ray-core/v5/common/net" "github.com/v2fly/v2ray-core/v5/common/net"
"github.com/v2fly/v2ray-core/v5/common/platform" "github.com/v2fly/v2ray-core/v5/common/platform"
@ -28,6 +29,7 @@ type NameServerConfig struct {
SkipFallback bool SkipFallback bool
Domains []string Domains []string
ExpectIPs cfgcommon.StringList ExpectIPs cfgcommon.StringList
FakeDNS FakeDNSConfigExtend
cfgctx context.Context cfgctx context.Context
} }
@ -50,6 +52,7 @@ func (c *NameServerConfig) UnmarshalJSON(data []byte) error {
SkipFallback bool `json:"skipFallback"` SkipFallback bool `json:"skipFallback"`
Domains []string `json:"domains"` Domains []string `json:"domains"`
ExpectIPs cfgcommon.StringList `json:"expectIps"` ExpectIPs cfgcommon.StringList `json:"expectIps"`
FakeDNS FakeDNSConfigExtend `json:"fakedns"`
} }
if err := json.Unmarshal(data, &advanced); err == nil { if err := json.Unmarshal(data, &advanced); err == nil {
c.Address = advanced.Address c.Address = advanced.Address
@ -62,6 +65,7 @@ func (c *NameServerConfig) UnmarshalJSON(data []byte) error {
c.SkipFallback = advanced.SkipFallback c.SkipFallback = advanced.SkipFallback
c.Domains = advanced.Domains c.Domains = advanced.Domains
c.ExpectIPs = advanced.ExpectIPs c.ExpectIPs = advanced.ExpectIPs
c.FakeDNS = advanced.FakeDNS
return nil return nil
} }
@ -121,6 +125,15 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) {
return nil, newError("invalid IP rule: ", c.ExpectIPs).Base(err) return nil, newError("invalid IP rule: ", c.ExpectIPs).Base(err)
} }
var fakeDNS *fakedns.FakeDnsPoolMulti
if c.FakeDNS.FakeDNSConfig != nil {
fake, err := c.FakeDNS.FakeDNSConfig.Build()
if err != nil {
return nil, newError("failed to build fakedns").Base(err)
}
fakeDNS = fake
}
var myClientIP []byte var myClientIP []byte
if c.ClientIP != nil { if c.ClientIP != nil {
if !c.ClientIP.Family().IsIP() { if !c.ClientIP.Family().IsIP() {
@ -178,6 +191,7 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) {
PrioritizedDomain: domains, PrioritizedDomain: domains,
Geoip: geoipList, Geoip: geoipList,
OriginalRules: originalRules, OriginalRules: originalRules,
FakeDns: fakeDNS,
}, nil }, nil
} }
@ -192,6 +206,7 @@ var typeMap = map[routercommon.Domain_Type]dns.DomainMatchingType{
type DNSConfig struct { // nolint: revive type DNSConfig struct { // nolint: revive
Servers []*NameServerConfig `json:"servers"` Servers []*NameServerConfig `json:"servers"`
Hosts map[string]*HostAddress `json:"hosts"` Hosts map[string]*HostAddress `json:"hosts"`
FakeDNS *FakeDNSConfig `json:"fakedns"`
DomainMatcher string `json:"domainMatcher"` DomainMatcher string `json:"domainMatcher"`
ClientIP *cfgcommon.Address `json:"clientIp"` ClientIP *cfgcommon.Address `json:"clientIp"`
Tag string `json:"tag"` Tag string `json:"tag"`
@ -435,5 +450,13 @@ func (c *DNSConfig) Build() (*dns.Config, error) {
config.StaticHosts = append(config.StaticHosts, mappings...) config.StaticHosts = append(config.StaticHosts, mappings...)
} }
if c.FakeDNS != nil {
fakeDNS, err := c.FakeDNS.Build()
if err != nil {
return nil, newError("failed to build fakedns").Base(err)
}
config.FakeDns = fakeDNS
}
return config, nil return config, nil
} }

View File

@ -11,6 +11,7 @@ import (
"google.golang.org/protobuf/runtime/protoiface" "google.golang.org/protobuf/runtime/protoiface"
"github.com/v2fly/v2ray-core/v5/app/dns" "github.com/v2fly/v2ray-core/v5/app/dns"
"github.com/v2fly/v2ray-core/v5/app/dns/fakedns"
"github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common"
"github.com/v2fly/v2ray-core/v5/common/net" "github.com/v2fly/v2ray-core/v5/common/net"
"github.com/v2fly/v2ray-core/v5/common/platform/filesystem" "github.com/v2fly/v2ray-core/v5/common/platform/filesystem"
@ -149,5 +150,141 @@ func TestDNSConfigParsing(t *testing.T) {
DisableFallback: true, DisableFallback: true,
}, },
}, },
{
Input: `{
"servers": [{
"address": "fakedns",
"tag": "fake",
"queryStrategy": "UseIPv6",
"fallbackStrategy": "disabledIfAnyMatch",
"fakedns": true
}, {
"address": "8.8.8.8",
"port": 5353,
"tag": "local",
"clientIp": "10.0.0.1",
"queryStrategy": "UseIP",
"cacheStrategy": "enabled",
"fallbackStrategy": "disabled",
"domains": ["domain:v2fly.org"],
"fakedns": ["198.19.0.0/16", "fc01::/18"]
}],
"hosts": {
"v2fly.org": "127.0.0.1",
"www.v2fly.org": ["1.2.3.4", "5.6.7.8"],
"domain:example.com": "google.com",
"geosite:test": ["127.0.0.1", "127.0.0.2"],
"keyword:google": ["8.8.8.8", "8.8.4.4"],
"regexp:.*\\.com": "8.8.4.4"
},
"fakedns": [
{ "ipPool": "198.18.0.0/16", "poolSize": 32768 },
{ "ipPool": "fc00::/18", "poolSize": 32768 }
],
"tag": "global",
"clientIp": "10.0.0.1",
"queryStrategy": "UseIPv4",
"cacheStrategy": "disabled",
"fallbackStrategy": "enabled"
}`,
Parser: parserCreator(),
Output: &dns.Config{
NameServer: []*dns.NameServer{
{
Address: &net.Endpoint{
Address: &net.IPOrDomain{
Address: &net.IPOrDomain_Domain{
Domain: "fakedns",
},
},
Network: net.Network_UDP,
},
Tag: "fake",
QueryStrategy: dns.QueryStrategy_USE_IP6.Enum(),
FallbackStrategy: dns.FallbackStrategy_DisabledIfAnyMatch.Enum(),
FakeDns: &fakedns.FakeDnsPoolMulti{
Pools: []*fakedns.FakeDnsPool{},
},
},
{
Address: &net.Endpoint{
Address: &net.IPOrDomain{
Address: &net.IPOrDomain_Ip{
Ip: []byte{8, 8, 8, 8},
},
},
Network: net.Network_UDP,
Port: 5353,
},
Tag: "local",
ClientIp: []byte{10, 0, 0, 1},
QueryStrategy: dns.QueryStrategy_USE_IP.Enum(),
CacheStrategy: dns.CacheStrategy_CacheEnabled.Enum(),
FallbackStrategy: dns.FallbackStrategy_Disabled.Enum(),
PrioritizedDomain: []*dns.NameServer_PriorityDomain{
{
Type: dns.DomainMatchingType_Subdomain,
Domain: "v2fly.org",
},
},
OriginalRules: []*dns.NameServer_OriginalRule{
{
Rule: "domain:v2fly.org",
Size: 1,
},
},
FakeDns: &fakedns.FakeDnsPoolMulti{
Pools: []*fakedns.FakeDnsPool{
{IpPool: "198.19.0.0/16", LruSize: 65535},
{IpPool: "fc01::/18", LruSize: 65535},
},
},
},
},
StaticHosts: []*dns.HostMapping{
{
Type: dns.DomainMatchingType_Subdomain,
Domain: "example.com",
ProxiedDomain: "google.com",
},
{
Type: dns.DomainMatchingType_Full,
Domain: "test.example.com",
Ip: [][]byte{{127, 0, 0, 1}, {127, 0, 0, 2}},
},
{
Type: dns.DomainMatchingType_Keyword,
Domain: "google",
Ip: [][]byte{{8, 8, 8, 8}, {8, 8, 4, 4}},
},
{
Type: dns.DomainMatchingType_Regex,
Domain: ".*\\.com",
Ip: [][]byte{{8, 8, 4, 4}},
},
{
Type: dns.DomainMatchingType_Full,
Domain: "v2fly.org",
Ip: [][]byte{{127, 0, 0, 1}},
},
{
Type: dns.DomainMatchingType_Full,
Domain: "www.v2fly.org",
Ip: [][]byte{{1, 2, 3, 4}, {5, 6, 7, 8}},
},
},
FakeDns: &fakedns.FakeDnsPoolMulti{
Pools: []*fakedns.FakeDnsPool{
{IpPool: "198.18.0.0/16", LruSize: 32768},
{IpPool: "fc00::/18", LruSize: 32768},
},
},
Tag: "global",
ClientIp: []byte{10, 0, 0, 1},
QueryStrategy: dns.QueryStrategy_USE_IP4,
CacheStrategy: dns.CacheStrategy_CacheDisabled,
FallbackStrategy: dns.FallbackStrategy_Enabled,
},
},
}) })
} }

View File

@ -0,0 +1,87 @@
package dns
import (
"encoding/json"
"net"
"github.com/v2fly/v2ray-core/v5/app/dns/fakedns"
)
type FakeDNSPoolElementConfig struct {
IPPool string `json:"ipPool"`
LRUSize int64 `json:"poolSize"`
}
type FakeDNSConfig struct {
pool *FakeDNSPoolElementConfig
pools []*FakeDNSPoolElementConfig
}
// UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON
func (f *FakeDNSConfig) UnmarshalJSON(data []byte) error {
var pool FakeDNSPoolElementConfig
var pools []*FakeDNSPoolElementConfig
var ipPools []string
switch {
case json.Unmarshal(data, &pool) == nil:
f.pool = &pool
case json.Unmarshal(data, &pools) == nil:
f.pools = pools
case json.Unmarshal(data, &ipPools) == nil:
f.pools = make([]*FakeDNSPoolElementConfig, 0, len(ipPools))
for _, ipPool := range ipPools {
_, ipNet, err := net.ParseCIDR(ipPool)
if err != nil {
return err
}
ones, bits := ipNet.Mask.Size()
sizeInBits := bits - ones
if sizeInBits > 16 { // At most 65536 ips for a IP pool
sizeInBits = 16
}
f.pools = append(f.pools, &FakeDNSPoolElementConfig{
IPPool: ipPool,
LRUSize: (1 << sizeInBits) - 1,
})
}
default:
return newError("invalid fakedns config")
}
return nil
}
func (f *FakeDNSConfig) Build() (*fakedns.FakeDnsPoolMulti, error) {
fakeDNSPool := fakedns.FakeDnsPoolMulti{}
if f.pool != nil {
fakeDNSPool.Pools = append(fakeDNSPool.Pools, &fakedns.FakeDnsPool{
IpPool: f.pool.IPPool,
LruSize: f.pool.LRUSize,
})
return &fakeDNSPool, nil
}
if f.pools != nil {
for _, v := range f.pools {
fakeDNSPool.Pools = append(fakeDNSPool.Pools, &fakedns.FakeDnsPool{IpPool: v.IPPool, LruSize: v.LRUSize})
}
return &fakeDNSPool, nil
}
return nil, newError("no valid FakeDNS config")
}
type FakeDNSConfigExtend struct { // Adds boolean value parsing for "fakedns" config
*FakeDNSConfig
}
func (f *FakeDNSConfigExtend) UnmarshalJSON(data []byte) error {
var enabled bool
if json.Unmarshal(data, &enabled) == nil {
if enabled {
f.FakeDNSConfig = &FakeDNSConfig{pools: []*FakeDNSPoolElementConfig{}}
}
return nil
}
return json.Unmarshal(data, &f.FakeDNSConfig)
}

View File

@ -1,129 +0,0 @@
package v4
import (
"encoding/json"
"strings"
"github.com/v2fly/v2ray-core/v5/app/dns/fakedns"
)
type FakeDNSPoolElementConfig struct {
IPPool string `json:"ipPool"`
LRUSize int64 `json:"poolSize"`
}
type FakeDNSConfig struct {
pool *FakeDNSPoolElementConfig
pools []*FakeDNSPoolElementConfig
}
// UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON
func (f *FakeDNSConfig) UnmarshalJSON(data []byte) error {
var pool FakeDNSPoolElementConfig
var pools []*FakeDNSPoolElementConfig
switch {
case json.Unmarshal(data, &pool) == nil:
f.pool = &pool
case json.Unmarshal(data, &pools) == nil:
f.pools = pools
default:
return newError("invalid fakedns config")
}
return nil
}
func (f *FakeDNSConfig) Build() (*fakedns.FakeDnsPoolMulti, error) {
fakeDNSPool := fakedns.FakeDnsPoolMulti{}
if f.pool != nil {
fakeDNSPool.Pools = append(fakeDNSPool.Pools, &fakedns.FakeDnsPool{
IpPool: f.pool.IPPool,
LruSize: f.pool.LRUSize,
})
return &fakeDNSPool, nil
}
if f.pools != nil {
for _, v := range f.pools {
fakeDNSPool.Pools = append(fakeDNSPool.Pools, &fakedns.FakeDnsPool{IpPool: v.IPPool, LruSize: v.LRUSize})
}
return &fakeDNSPool, nil
}
return nil, newError("no valid FakeDNS config")
}
type FakeDNSPostProcessingStage struct{}
func (FakeDNSPostProcessingStage) Process(config *Config) error {
fakeDNSInUse := false
isIPv4Enable, isIPv6Enable := true, true
if config.DNSConfig != nil {
for _, v := range config.DNSConfig.Servers {
if v.Address.Family().IsDomain() && strings.EqualFold(v.Address.Domain(), "fakedns") {
fakeDNSInUse = true
}
}
switch strings.ToLower(config.DNSConfig.QueryStrategy) {
case "useip4", "useipv4", "use_ip4", "use_ipv4", "use_ip_v4", "use-ip4", "use-ipv4", "use-ip-v4":
isIPv4Enable, isIPv6Enable = true, false
case "useip6", "useipv6", "use_ip6", "use_ipv6", "use_ip_v6", "use-ip6", "use-ipv6", "use-ip-v6":
isIPv4Enable, isIPv6Enable = false, true
}
}
if fakeDNSInUse {
// Add a Fake DNS Config if there is none
if config.FakeDNS == nil {
config.FakeDNS = &FakeDNSConfig{}
switch {
case isIPv4Enable && isIPv6Enable:
config.FakeDNS.pools = []*FakeDNSPoolElementConfig{
{
IPPool: "198.18.0.0/15",
LRUSize: 32768,
},
{
IPPool: "fc00::/18",
LRUSize: 32768,
},
}
case !isIPv4Enable && isIPv6Enable:
config.FakeDNS.pool = &FakeDNSPoolElementConfig{
IPPool: "fc00::/18",
LRUSize: 65535,
}
case isIPv4Enable && !isIPv6Enable:
config.FakeDNS.pool = &FakeDNSPoolElementConfig{
IPPool: "198.18.0.0/15",
LRUSize: 65535,
}
}
}
found := false
// Check if there is a Outbound with necessary sniffer on
var inbounds []InboundDetourConfig
if len(config.InboundConfigs) > 0 {
inbounds = append(inbounds, config.InboundConfigs...)
}
for _, v := range inbounds {
if v.SniffingConfig != nil && v.SniffingConfig.Enabled && v.SniffingConfig.DestOverride != nil {
for _, dov := range *v.SniffingConfig.DestOverride {
if strings.EqualFold(dov, "fakedns") || strings.EqualFold(dov, "fakedns+others") {
found = true
break
}
}
}
}
if !found {
newError("Defined FakeDNS but haven't enabled FakeDNS destOverride at any inbound.").AtWarning().WriteToLog()
}
}
return nil
}

View File

@ -1,5 +0,0 @@
package v4
func init() {
RegisterConfigureFilePostProcessingStage("FakeDNS", &FakeDNSPostProcessingStage{})
}

View File

@ -11,6 +11,7 @@ import (
"github.com/v2fly/v2ray-core/v5/app/proxyman" "github.com/v2fly/v2ray-core/v5/app/proxyman"
"github.com/v2fly/v2ray-core/v5/app/stats" "github.com/v2fly/v2ray-core/v5/app/stats"
"github.com/v2fly/v2ray-core/v5/common/serial" "github.com/v2fly/v2ray-core/v5/common/serial"
"github.com/v2fly/v2ray-core/v5/features"
"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon" "github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon"
"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/loader" "github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/loader"
"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/muxcfg" "github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/muxcfg"
@ -302,7 +303,7 @@ type Config struct {
API *APIConfig `json:"api"` API *APIConfig `json:"api"`
Stats *StatsConfig `json:"stats"` Stats *StatsConfig `json:"stats"`
Reverse *ReverseConfig `json:"reverse"` Reverse *ReverseConfig `json:"reverse"`
FakeDNS *FakeDNSConfig `json:"fakeDns"` FakeDNS *dns.FakeDNSConfig `json:"fakeDns"`
BrowserForwarder *BrowserForwarderConfig `json:"browserForwarder"` BrowserForwarder *BrowserForwarderConfig `json:"browserForwarder"`
Observatory *ObservatoryConfig `json:"observatory"` Observatory *ObservatoryConfig `json:"observatory"`
BurstObservatory *BurstObservatoryConfig `json:"burstObservatory"` BurstObservatory *BurstObservatoryConfig `json:"burstObservatory"`
@ -399,6 +400,17 @@ func (c *Config) Build() (*core.Config, error) {
config.App = append(config.App, serial.ToTypedMessage(routerConfig)) config.App = append(config.App, serial.ToTypedMessage(routerConfig))
} }
if c.FakeDNS != nil {
features.PrintDeprecatedFeatureWarning("root fakedns settings")
if c.DNSConfig != nil {
c.DNSConfig.FakeDNS = c.FakeDNS
} else {
c.DNSConfig = &dns.DNSConfig{
FakeDNS: c.FakeDNS,
}
}
}
if c.DNSConfig != nil { if c.DNSConfig != nil {
dnsApp, err := c.DNSConfig.Build() dnsApp, err := c.DNSConfig.Build()
if err != nil { if err != nil {
@ -423,14 +435,6 @@ func (c *Config) Build() (*core.Config, error) {
config.App = append(config.App, serial.ToTypedMessage(r)) config.App = append(config.App, serial.ToTypedMessage(r))
} }
if c.FakeDNS != nil {
r, err := c.FakeDNS.Build()
if err != nil {
return nil, err
}
config.App = append(config.App, serial.ToTypedMessage(r))
}
if c.BrowserForwarder != nil { if c.BrowserForwarder != nil {
r, err := c.BrowserForwarder.Build() r, err := c.BrowserForwarder.Build()
if err != nil { if err != nil {

View File

@ -56,6 +56,10 @@ type Handler struct {
} }
func (h *Handler) Init(config *Config, dnsClient dns.Client, policyManager policy.Manager) error { func (h *Handler) Init(config *Config, dnsClient dns.Client, policyManager policy.Manager) error {
// Enable FakeDNS for DNS outbound
if clientWithFakeDNS, ok := dnsClient.(dns.ClientWithFakeDNS); ok {
dnsClient = clientWithFakeDNS.AsFakeDNSClient()
}
h.client = dnsClient h.client = dnsClient
h.timeout = policyManager.ForLevel(config.UserLevel).Timeouts.ConnectionIdle h.timeout = policyManager.ForLevel(config.UserLevel).Timeouts.ConnectionIdle
@ -236,13 +240,6 @@ func (h *Handler) handleIPQuery(id uint16, qType dnsmessage.Type, domain string,
var ttl uint32 = 600 var ttl uint32 = 600
// Do NOT skip FakeDNS
if c, ok := h.client.(dns.ClientWithIPOption); ok {
c.SetFakeDNSOption(true)
} else {
newError("dns.Client doesn't implement ClientWithIPOption")
}
switch qType { switch qType {
case dnsmessage.TypeA: case dnsmessage.TypeA:
ips, err = h.ipv4Lookup.LookupIPv4(domain) ips, err = h.ipv4Lookup.LookupIPv4(domain)

View File

@ -65,24 +65,11 @@ func (h *Handler) policy() policy.Session {
} }
func (h *Handler) resolveIP(ctx context.Context, domain string, localAddr net.Address) net.Address { func (h *Handler) resolveIP(ctx context.Context, domain string, localAddr net.Address) net.Address {
if c, ok := h.dns.(dns.ClientWithIPOption); ok { ips, err := dns.LookupIPWithOption(h.dns, domain, dns.IPOption{
c.SetFakeDNSOption(false) // Skip FakeDNS IPv4Enable: h.config.DomainStrategy == Config_USE_IP || h.config.DomainStrategy == Config_USE_IP4 || (localAddr != nil && localAddr.Family().IsIPv4()),
} else { IPv6Enable: h.config.DomainStrategy == Config_USE_IP || h.config.DomainStrategy == Config_USE_IP6 || (localAddr != nil && localAddr.Family().IsIPv6()),
newError("DNS client doesn't implement ClientWithIPOption") FakeEnable: false,
} })
lookupFunc := h.dns.LookupIP
if h.config.DomainStrategy == Config_USE_IP4 || (localAddr != nil && localAddr.Family().IsIPv4()) {
if lookupIPv4, ok := h.dns.(dns.IPv4Lookup); ok {
lookupFunc = lookupIPv4.LookupIPv4
}
} else if h.config.DomainStrategy == Config_USE_IP6 || (localAddr != nil && localAddr.Family().IsIPv6()) {
if lookupIPv6, ok := h.dns.(dns.IPv6Lookup); ok {
lookupFunc = lookupIPv6.LookupIPv6
}
}
ips, err := lookupFunc(domain)
if err != nil { if err != nil {
newError("failed to get IP address for domain ", domain).Base(err).WriteToLog(session.ExportIDToError(ctx)) newError("failed to get IP address for domain ", domain).Base(err).WriteToLog(session.ExportIDToError(ctx))
} }

View File

@ -104,17 +104,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
switch c.version { switch c.version {
case Version_SOCKS4: case Version_SOCKS4:
if request.Address.Family().IsDomain() { if request.Address.Family().IsDomain() {
if d, ok := c.dns.(dns.ClientWithIPOption); ok { ips, err := dns.LookupIPWithOption(c.dns, request.Address.Domain(), dns.IPOption{IPv4Enable: true, IPv6Enable: false, FakeEnable: false})
d.SetFakeDNSOption(false) // Skip FakeDNS
} else {
newError("DNS client doesn't implement ClientWithIPOption")
}
lookupFunc := c.dns.LookupIP
if lookupIPv4, ok := c.dns.(dns.IPv4Lookup); ok {
lookupFunc = lookupIPv4.LookupIPv4
}
ips, err := lookupFunc(request.Address.Domain())
if err != nil { if err != nil {
return err return err
} else if len(ips) == 0 { } else if len(ips) == 0 {