diff --git a/app/dns/config.go b/app/dns/config.go index b960a8473..3859b0d45 100644 --- a/app/dns/config.go +++ b/app/dns/config.go @@ -4,9 +4,12 @@ package dns import ( + "golang.org/x/net/dns/dnsmessage" + "github.com/v2fly/v2ray-core/v5/common/net" "github.com/v2fly/v2ray-core/v5/common/strmatcher" "github.com/v2fly/v2ray-core/v5/common/uuid" + "github.com/v2fly/v2ray-core/v5/features/dns" ) var typeMap = map[DomainMatchingType]strmatcher.Type{ @@ -60,6 +63,25 @@ func toNetIP(addrs []net.Address) ([]net.IP, error) { return ips, nil } +func toIPOption(s QueryStrategy) dns.IPOption { + return dns.IPOption{ + IPv4Enable: s == QueryStrategy_USE_IP || s == QueryStrategy_USE_IP4, + IPv6Enable: s == QueryStrategy_USE_IP || s == QueryStrategy_USE_IP6, + FakeEnable: false, + } +} + +func toReqTypes(option dns.IPOption) []dnsmessage.Type { + var reqTypes []dnsmessage.Type + if option.IPv4Enable { + reqTypes = append(reqTypes, dnsmessage.TypeA) + } + if option.IPv6Enable { + reqTypes = append(reqTypes, dnsmessage.TypeAAAA) + } + return reqTypes +} + func generateRandomTag() string { id := uuid.New() return "v2ray.system." + id.String() diff --git a/app/dns/config.pb.go b/app/dns/config.pb.go index d6f04f2f1..8d1ff6284 100644 --- a/app/dns/config.pb.go +++ b/app/dns/config.pb.go @@ -118,6 +118,101 @@ func (QueryStrategy) EnumDescriptor() ([]byte, []int) { return file_app_dns_config_proto_rawDescGZIP(), []int{1} } +type CacheStrategy int32 + +const ( + CacheStrategy_CacheEnabled CacheStrategy = 0 + CacheStrategy_CacheDisabled CacheStrategy = 1 +) + +// Enum value maps for CacheStrategy. +var ( + CacheStrategy_name = map[int32]string{ + 0: "CacheEnabled", + 1: "CacheDisabled", + } + CacheStrategy_value = map[string]int32{ + "CacheEnabled": 0, + "CacheDisabled": 1, + } +) + +func (x CacheStrategy) Enum() *CacheStrategy { + p := new(CacheStrategy) + *p = x + return p +} + +func (x CacheStrategy) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CacheStrategy) Descriptor() protoreflect.EnumDescriptor { + return file_app_dns_config_proto_enumTypes[2].Descriptor() +} + +func (CacheStrategy) Type() protoreflect.EnumType { + return &file_app_dns_config_proto_enumTypes[2] +} + +func (x CacheStrategy) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use CacheStrategy.Descriptor instead. +func (CacheStrategy) EnumDescriptor() ([]byte, []int) { + return file_app_dns_config_proto_rawDescGZIP(), []int{2} +} + +type FallbackStrategy int32 + +const ( + FallbackStrategy_Enabled FallbackStrategy = 0 + FallbackStrategy_Disabled FallbackStrategy = 1 + FallbackStrategy_DisabledIfAnyMatch FallbackStrategy = 2 +) + +// Enum value maps for FallbackStrategy. +var ( + FallbackStrategy_name = map[int32]string{ + 0: "Enabled", + 1: "Disabled", + 2: "DisabledIfAnyMatch", + } + FallbackStrategy_value = map[string]int32{ + "Enabled": 0, + "Disabled": 1, + "DisabledIfAnyMatch": 2, + } +) + +func (x FallbackStrategy) Enum() *FallbackStrategy { + p := new(FallbackStrategy) + *p = x + return p +} + +func (x FallbackStrategy) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (FallbackStrategy) Descriptor() protoreflect.EnumDescriptor { + return file_app_dns_config_proto_enumTypes[3].Descriptor() +} + +func (FallbackStrategy) Type() protoreflect.EnumType { + return &file_app_dns_config_proto_enumTypes[3] +} + +func (x FallbackStrategy) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use FallbackStrategy.Descriptor instead. +func (FallbackStrategy) EnumDescriptor() ([]byte, []int) { + return file_app_dns_config_proto_rawDescGZIP(), []int{3} +} + type NameServer struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -125,10 +220,17 @@ type NameServer struct { Address *net.Endpoint `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` ClientIp []byte `protobuf:"bytes,5,opt,name=client_ip,json=clientIp,proto3" json:"client_ip,omitempty"` - SkipFallback bool `protobuf:"varint,6,opt,name=skipFallback,proto3" json:"skipFallback,omitempty"` + Tag string `protobuf:"bytes,7,opt,name=tag,proto3" json:"tag,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"` OriginalRules []*NameServer_OriginalRule `protobuf:"bytes,4,rep,name=original_rules,json=originalRules,proto3" json:"original_rules,omitempty"` + // Deprecated. Use fallback_strategy. + // + // Deprecated: Do not use. + SkipFallback bool `protobuf:"varint,6,opt,name=skipFallback,proto3" json:"skipFallback,omitempty"` + QueryStrategy *QueryStrategy `protobuf:"varint,8,opt,name=query_strategy,json=queryStrategy,proto3,enum=v2ray.core.app.dns.QueryStrategy,oneof" json:"query_strategy,omitempty"` + CacheStrategy *CacheStrategy `protobuf:"varint,9,opt,name=cache_strategy,json=cacheStrategy,proto3,enum=v2ray.core.app.dns.CacheStrategy,oneof" json:"cache_strategy,omitempty"` + FallbackStrategy *FallbackStrategy `protobuf:"varint,10,opt,name=fallback_strategy,json=fallbackStrategy,proto3,enum=v2ray.core.app.dns.FallbackStrategy,oneof" json:"fallback_strategy,omitempty"` } func (x *NameServer) Reset() { @@ -177,11 +279,11 @@ func (x *NameServer) GetClientIp() []byte { return nil } -func (x *NameServer) GetSkipFallback() bool { +func (x *NameServer) GetTag() string { if x != nil { - return x.SkipFallback + return x.Tag } - return false + return "" } func (x *NameServer) GetPrioritizedDomain() []*NameServer_PriorityDomain { @@ -205,6 +307,35 @@ func (x *NameServer) GetOriginalRules() []*NameServer_OriginalRule { return nil } +// Deprecated: Do not use. +func (x *NameServer) GetSkipFallback() bool { + if x != nil { + return x.SkipFallback + } + return false +} + +func (x *NameServer) GetQueryStrategy() QueryStrategy { + if x != nil && x.QueryStrategy != nil { + return *x.QueryStrategy + } + return QueryStrategy_USE_IP +} + +func (x *NameServer) GetCacheStrategy() CacheStrategy { + if x != nil && x.CacheStrategy != nil { + return *x.CacheStrategy + } + return CacheStrategy_CacheEnabled +} + +func (x *NameServer) GetFallbackStrategy() FallbackStrategy { + if x != nil && x.FallbackStrategy != nil { + return *x.FallbackStrategy + } + return FallbackStrategy_Enabled +} + type HostMapping struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -303,10 +434,24 @@ type Config struct { // Tag is the inbound tag of DNS client. Tag string `protobuf:"bytes,6,opt,name=tag,proto3" json:"tag,omitempty"` // DisableCache disables DNS cache - DisableCache bool `protobuf:"varint,8,opt,name=disableCache,proto3" json:"disableCache,omitempty"` - QueryStrategy QueryStrategy `protobuf:"varint,9,opt,name=query_strategy,json=queryStrategy,proto3,enum=v2ray.core.app.dns.QueryStrategy" json:"query_strategy,omitempty"` - DisableFallback bool `protobuf:"varint,10,opt,name=disableFallback,proto3" json:"disableFallback,omitempty"` - DisableFallbackIfMatch bool `protobuf:"varint,11,opt,name=disableFallbackIfMatch,proto3" json:"disableFallbackIfMatch,omitempty"` + // Deprecated. Use cache_strategy. + // + // Deprecated: Do not use. + DisableCache bool `protobuf:"varint,8,opt,name=disableCache,proto3" json:"disableCache,omitempty"` + // Deprecated. Use fallback_strategy. + // + // Deprecated: Do not use. + DisableFallback bool `protobuf:"varint,10,opt,name=disableFallback,proto3" json:"disableFallback,omitempty"` + // Deprecated. Use fallback_strategy. + // + // Deprecated: Do not use. + DisableFallbackIfMatch bool `protobuf:"varint,11,opt,name=disableFallbackIfMatch,proto3" json:"disableFallbackIfMatch,omitempty"` + // Default query strategy (IPv4, IPv6, or both) for each name server. + QueryStrategy QueryStrategy `protobuf:"varint,9,opt,name=query_strategy,json=queryStrategy,proto3,enum=v2ray.core.app.dns.QueryStrategy" json:"query_strategy,omitempty"` + // Default cache strategy for each name server. + CacheStrategy CacheStrategy `protobuf:"varint,12,opt,name=cache_strategy,json=cacheStrategy,proto3,enum=v2ray.core.app.dns.CacheStrategy" json:"cache_strategy,omitempty"` + // Default fallback strategy for each name server. + FallbackStrategy FallbackStrategy `protobuf:"varint,13,opt,name=fallback_strategy,json=fallbackStrategy,proto3,enum=v2ray.core.app.dns.FallbackStrategy" json:"fallback_strategy,omitempty"` } func (x *Config) Reset() { @@ -385,6 +530,7 @@ func (x *Config) GetTag() string { return "" } +// Deprecated: Do not use. func (x *Config) GetDisableCache() bool { if x != nil { return x.DisableCache @@ -392,6 +538,22 @@ func (x *Config) GetDisableCache() bool { return false } +// Deprecated: Do not use. +func (x *Config) GetDisableFallback() bool { + if x != nil { + return x.DisableFallback + } + return false +} + +// Deprecated: Do not use. +func (x *Config) GetDisableFallbackIfMatch() bool { + if x != nil { + return x.DisableFallbackIfMatch + } + return false +} + func (x *Config) GetQueryStrategy() QueryStrategy { if x != nil { return x.QueryStrategy @@ -399,18 +561,18 @@ func (x *Config) GetQueryStrategy() QueryStrategy { return QueryStrategy_USE_IP } -func (x *Config) GetDisableFallback() bool { +func (x *Config) GetCacheStrategy() CacheStrategy { if x != nil { - return x.DisableFallback + return x.CacheStrategy } - return false + return CacheStrategy_CacheEnabled } -func (x *Config) GetDisableFallbackIfMatch() bool { +func (x *Config) GetFallbackStrategy() FallbackStrategy { if x != nil { - return x.DisableFallbackIfMatch + return x.FallbackStrategy } - return false + return FallbackStrategy_Enabled } type SimplifiedConfig struct { @@ -427,10 +589,24 @@ type SimplifiedConfig struct { // Tag is the inbound tag of DNS client. Tag string `protobuf:"bytes,6,opt,name=tag,proto3" json:"tag,omitempty"` // DisableCache disables DNS cache - DisableCache bool `protobuf:"varint,8,opt,name=disableCache,proto3" json:"disableCache,omitempty"` - QueryStrategy QueryStrategy `protobuf:"varint,9,opt,name=query_strategy,json=queryStrategy,proto3,enum=v2ray.core.app.dns.QueryStrategy" json:"query_strategy,omitempty"` - DisableFallback bool `protobuf:"varint,10,opt,name=disableFallback,proto3" json:"disableFallback,omitempty"` - DisableFallbackIfMatch bool `protobuf:"varint,11,opt,name=disableFallbackIfMatch,proto3" json:"disableFallbackIfMatch,omitempty"` + // Deprecated. Use cache_strategy. + // + // Deprecated: Do not use. + DisableCache bool `protobuf:"varint,8,opt,name=disableCache,proto3" json:"disableCache,omitempty"` + // Deprecated. Use fallback_strategy. + // + // Deprecated: Do not use. + DisableFallback bool `protobuf:"varint,10,opt,name=disableFallback,proto3" json:"disableFallback,omitempty"` + // Deprecated. Use fallback_strategy. + // + // Deprecated: Do not use. + DisableFallbackIfMatch bool `protobuf:"varint,11,opt,name=disableFallbackIfMatch,proto3" json:"disableFallbackIfMatch,omitempty"` + // Default query strategy (IPv4, IPv6, or both) for each name server. + QueryStrategy QueryStrategy `protobuf:"varint,9,opt,name=query_strategy,json=queryStrategy,proto3,enum=v2ray.core.app.dns.QueryStrategy" json:"query_strategy,omitempty"` + // Default cache strategy for each name server. + CacheStrategy CacheStrategy `protobuf:"varint,12,opt,name=cache_strategy,json=cacheStrategy,proto3,enum=v2ray.core.app.dns.CacheStrategy" json:"cache_strategy,omitempty"` + // Default fallback strategy for each name server. + FallbackStrategy FallbackStrategy `protobuf:"varint,13,opt,name=fallback_strategy,json=fallbackStrategy,proto3,enum=v2ray.core.app.dns.FallbackStrategy" json:"fallback_strategy,omitempty"` } func (x *SimplifiedConfig) Reset() { @@ -493,6 +669,7 @@ func (x *SimplifiedConfig) GetTag() string { return "" } +// Deprecated: Do not use. func (x *SimplifiedConfig) GetDisableCache() bool { if x != nil { return x.DisableCache @@ -500,6 +677,22 @@ func (x *SimplifiedConfig) GetDisableCache() bool { return false } +// Deprecated: Do not use. +func (x *SimplifiedConfig) GetDisableFallback() bool { + if x != nil { + return x.DisableFallback + } + return false +} + +// Deprecated: Do not use. +func (x *SimplifiedConfig) GetDisableFallbackIfMatch() bool { + if x != nil { + return x.DisableFallbackIfMatch + } + return false +} + func (x *SimplifiedConfig) GetQueryStrategy() QueryStrategy { if x != nil { return x.QueryStrategy @@ -507,18 +700,18 @@ func (x *SimplifiedConfig) GetQueryStrategy() QueryStrategy { return QueryStrategy_USE_IP } -func (x *SimplifiedConfig) GetDisableFallback() bool { +func (x *SimplifiedConfig) GetCacheStrategy() CacheStrategy { if x != nil { - return x.DisableFallback + return x.CacheStrategy } - return false + return CacheStrategy_CacheEnabled } -func (x *SimplifiedConfig) GetDisableFallbackIfMatch() bool { +func (x *SimplifiedConfig) GetFallbackStrategy() FallbackStrategy { if x != nil { - return x.DisableFallbackIfMatch + return x.FallbackStrategy } - return false + return FallbackStrategy_Enabled } type SimplifiedHostMapping struct { @@ -601,10 +794,17 @@ type SimplifiedNameServer struct { Address *net.Endpoint `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` ClientIp string `protobuf:"bytes,5,opt,name=client_ip,json=clientIp,proto3" json:"client_ip,omitempty"` - SkipFallback bool `protobuf:"varint,6,opt,name=skipFallback,proto3" json:"skipFallback,omitempty"` + Tag string `protobuf:"bytes,7,opt,name=tag,proto3" json:"tag,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"` OriginalRules []*SimplifiedNameServer_OriginalRule `protobuf:"bytes,4,rep,name=original_rules,json=originalRules,proto3" json:"original_rules,omitempty"` + // Deprecated. Use fallback_strategy. + // + // Deprecated: Do not use. + SkipFallback bool `protobuf:"varint,6,opt,name=skipFallback,proto3" json:"skipFallback,omitempty"` + QueryStrategy *QueryStrategy `protobuf:"varint,8,opt,name=query_strategy,json=queryStrategy,proto3,enum=v2ray.core.app.dns.QueryStrategy,oneof" json:"query_strategy,omitempty"` + CacheStrategy *CacheStrategy `protobuf:"varint,9,opt,name=cache_strategy,json=cacheStrategy,proto3,enum=v2ray.core.app.dns.CacheStrategy,oneof" json:"cache_strategy,omitempty"` + FallbackStrategy *FallbackStrategy `protobuf:"varint,10,opt,name=fallback_strategy,json=fallbackStrategy,proto3,enum=v2ray.core.app.dns.FallbackStrategy,oneof" json:"fallback_strategy,omitempty"` } func (x *SimplifiedNameServer) Reset() { @@ -653,11 +853,11 @@ func (x *SimplifiedNameServer) GetClientIp() string { return "" } -func (x *SimplifiedNameServer) GetSkipFallback() bool { +func (x *SimplifiedNameServer) GetTag() string { if x != nil { - return x.SkipFallback + return x.Tag } - return false + return "" } func (x *SimplifiedNameServer) GetPrioritizedDomain() []*SimplifiedNameServer_PriorityDomain { @@ -681,6 +881,35 @@ func (x *SimplifiedNameServer) GetOriginalRules() []*SimplifiedNameServer_Origin return nil } +// Deprecated: Do not use. +func (x *SimplifiedNameServer) GetSkipFallback() bool { + if x != nil { + return x.SkipFallback + } + return false +} + +func (x *SimplifiedNameServer) GetQueryStrategy() QueryStrategy { + if x != nil && x.QueryStrategy != nil { + return *x.QueryStrategy + } + return QueryStrategy_USE_IP +} + +func (x *SimplifiedNameServer) GetCacheStrategy() CacheStrategy { + if x != nil && x.CacheStrategy != nil { + return *x.CacheStrategy + } + return CacheStrategy_CacheEnabled +} + +func (x *SimplifiedNameServer) GetFallbackStrategy() FallbackStrategy { + if x != nil && x.FallbackStrategy != nil { + return *x.FallbackStrategy + } + return FallbackStrategy_Enabled +} + type NameServer_PriorityDomain struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -914,179 +1143,249 @@ var file_app_dns_config_proto_rawDesc = []byte{ 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, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x99, 0x04, 0x0a, 0x0a, 0x4e, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe1, 0x06, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, - 0x70, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, - 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x6c, - 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x5c, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, - 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x2d, 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, 0x2e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, - 0x52, 0x11, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x44, 0x6f, 0x6d, - 0x61, 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 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, 0x52, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, - 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76, - 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, - 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4f, 0x72, 0x69, - 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, - 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x1a, 0x64, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6f, - 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, - 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, - 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x1a, 0x36, - 0x0a, 0x0c, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x75, - 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 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, + 0x70, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x74, 0x61, 0x67, 0x12, 0x5c, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, + 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x2d, 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, 0x2e, + 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x11, + 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x12, 0x3f, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 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, 0x52, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x72, + 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76, 0x32, 0x72, + 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, + 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, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, - 0x6f, 0x78, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x22, 0xf7, 0x04, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x45, 0x0a, 0x0b, - 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x73, 0x12, 0x3f, 0x0a, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, - 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, - 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x76, 0x32, 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, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x61, - 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, - 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 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, 0x28, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, - 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, - 0x12, 0x36, 0x0a, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, - 0x61, 0x63, 0x6b, 0x49, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, - 0x6b, 0x49, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 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, 0xca, 0x03, 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, 0x10, 0x0a, 0x03, - 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x22, - 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, - 0x68, 0x65, 0x12, 0x48, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, + 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, 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, + 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, + 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x02, + 0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, + 0x69, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0xa0, 0x06, 0x0a, 0x06, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x45, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, + 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, + 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x3f, 0x0a, 0x0b, 0x6e, + 0x61, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, + 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x05, + 0x48, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x76, 0x32, + 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, 0x10, + 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, + 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, 0x28, 0x0a, 0x0f, - 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, - 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x36, 0x0a, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, - 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x49, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, - 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x49, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x3a, 0x16, - 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, - 0x05, 0x12, 0x03, 0x64, 0x6e, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, - 0x10, 0x03, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x22, 0xa2, 0x01, 0x0a, 0x15, 0x53, 0x69, 0x6d, - 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, - 0x6e, 0x67, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, - 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, - 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, - 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, - 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0xb7, 0x04, - 0x0a, 0x14, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, - 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, - 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x22, - 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, - 0x63, 0x6b, 0x12, 0x66, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, - 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, - 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, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x11, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, - 0x69, 0x7a, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x05, 0x67, 0x65, - 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 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, 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, 0x2a, 0x45, 0x0a, 0x12, 0x44, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, - 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x64, 0x6f, - 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x77, 0x6f, 0x72, - 0x64, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x10, 0x03, 0x2a, 0x35, - 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, - 0x0a, 0x0a, 0x06, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x55, - 0x53, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, - 0x49, 0x50, 0x36, 0x10, 0x02, 0x42, 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, + 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, 0xf3, 0x04, 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, 0x10, 0x0a, + 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 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, 0x3a, 0x16, 0x82, 0xb5, 0x18, 0x09, 0x0a, 0x07, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x82, 0xb5, 0x18, 0x05, 0x12, 0x03, 0x64, 0x6e, 0x73, + 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x07, + 0x10, 0x08, 0x22, 0xa2, 0x01, 0x0a, 0x15, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x69, 0x65, + 0x64, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x3a, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x76, 0x32, 0x72, + 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, + 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, + 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, + 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0xff, 0x06, 0x0a, 0x14, 0x53, 0x69, 0x6d, 0x70, + 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x12, 0x39, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x66, 0x0a, 0x12, 0x70, 0x72, + 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 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, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, + 0x11, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 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 ( @@ -1101,53 +1400,65 @@ func file_app_dns_config_proto_rawDescGZIP() []byte { return file_app_dns_config_proto_rawDescData } -var file_app_dns_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_app_dns_config_proto_enumTypes = make([]protoimpl.EnumInfo, 4) var file_app_dns_config_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_app_dns_config_proto_goTypes = []interface{}{ (DomainMatchingType)(0), // 0: v2ray.core.app.dns.DomainMatchingType (QueryStrategy)(0), // 1: v2ray.core.app.dns.QueryStrategy - (*NameServer)(nil), // 2: v2ray.core.app.dns.NameServer - (*HostMapping)(nil), // 3: v2ray.core.app.dns.HostMapping - (*Config)(nil), // 4: v2ray.core.app.dns.Config - (*SimplifiedConfig)(nil), // 5: v2ray.core.app.dns.SimplifiedConfig - (*SimplifiedHostMapping)(nil), // 6: v2ray.core.app.dns.SimplifiedHostMapping - (*SimplifiedNameServer)(nil), // 7: v2ray.core.app.dns.SimplifiedNameServer - (*NameServer_PriorityDomain)(nil), // 8: v2ray.core.app.dns.NameServer.PriorityDomain - (*NameServer_OriginalRule)(nil), // 9: v2ray.core.app.dns.NameServer.OriginalRule - nil, // 10: v2ray.core.app.dns.Config.HostsEntry - (*SimplifiedNameServer_PriorityDomain)(nil), // 11: v2ray.core.app.dns.SimplifiedNameServer.PriorityDomain - (*SimplifiedNameServer_OriginalRule)(nil), // 12: v2ray.core.app.dns.SimplifiedNameServer.OriginalRule - (*net.Endpoint)(nil), // 13: v2ray.core.common.net.Endpoint - (*routercommon.GeoIP)(nil), // 14: v2ray.core.app.router.routercommon.GeoIP - (*net.IPOrDomain)(nil), // 15: v2ray.core.common.net.IPOrDomain + (CacheStrategy)(0), // 2: v2ray.core.app.dns.CacheStrategy + (FallbackStrategy)(0), // 3: v2ray.core.app.dns.FallbackStrategy + (*NameServer)(nil), // 4: v2ray.core.app.dns.NameServer + (*HostMapping)(nil), // 5: v2ray.core.app.dns.HostMapping + (*Config)(nil), // 6: v2ray.core.app.dns.Config + (*SimplifiedConfig)(nil), // 7: v2ray.core.app.dns.SimplifiedConfig + (*SimplifiedHostMapping)(nil), // 8: v2ray.core.app.dns.SimplifiedHostMapping + (*SimplifiedNameServer)(nil), // 9: v2ray.core.app.dns.SimplifiedNameServer + (*NameServer_PriorityDomain)(nil), // 10: v2ray.core.app.dns.NameServer.PriorityDomain + (*NameServer_OriginalRule)(nil), // 11: v2ray.core.app.dns.NameServer.OriginalRule + nil, // 12: v2ray.core.app.dns.Config.HostsEntry + (*SimplifiedNameServer_PriorityDomain)(nil), // 13: v2ray.core.app.dns.SimplifiedNameServer.PriorityDomain + (*SimplifiedNameServer_OriginalRule)(nil), // 14: v2ray.core.app.dns.SimplifiedNameServer.OriginalRule + (*net.Endpoint)(nil), // 15: v2ray.core.common.net.Endpoint + (*routercommon.GeoIP)(nil), // 16: v2ray.core.app.router.routercommon.GeoIP + (*net.IPOrDomain)(nil), // 17: v2ray.core.common.net.IPOrDomain } var file_app_dns_config_proto_depIdxs = []int32{ - 13, // 0: v2ray.core.app.dns.NameServer.address:type_name -> v2ray.core.common.net.Endpoint - 8, // 1: v2ray.core.app.dns.NameServer.prioritized_domain:type_name -> v2ray.core.app.dns.NameServer.PriorityDomain - 14, // 2: v2ray.core.app.dns.NameServer.geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP - 9, // 3: v2ray.core.app.dns.NameServer.original_rules:type_name -> v2ray.core.app.dns.NameServer.OriginalRule - 0, // 4: v2ray.core.app.dns.HostMapping.type:type_name -> v2ray.core.app.dns.DomainMatchingType - 13, // 5: v2ray.core.app.dns.Config.NameServers:type_name -> v2ray.core.common.net.Endpoint - 2, // 6: v2ray.core.app.dns.Config.name_server:type_name -> v2ray.core.app.dns.NameServer - 10, // 7: v2ray.core.app.dns.Config.Hosts:type_name -> v2ray.core.app.dns.Config.HostsEntry - 3, // 8: v2ray.core.app.dns.Config.static_hosts:type_name -> v2ray.core.app.dns.HostMapping - 1, // 9: v2ray.core.app.dns.Config.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy - 7, // 10: v2ray.core.app.dns.SimplifiedConfig.name_server:type_name -> v2ray.core.app.dns.SimplifiedNameServer - 3, // 11: v2ray.core.app.dns.SimplifiedConfig.static_hosts:type_name -> v2ray.core.app.dns.HostMapping - 1, // 12: v2ray.core.app.dns.SimplifiedConfig.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy - 0, // 13: v2ray.core.app.dns.SimplifiedHostMapping.type:type_name -> v2ray.core.app.dns.DomainMatchingType - 13, // 14: v2ray.core.app.dns.SimplifiedNameServer.address:type_name -> v2ray.core.common.net.Endpoint - 11, // 15: v2ray.core.app.dns.SimplifiedNameServer.prioritized_domain:type_name -> v2ray.core.app.dns.SimplifiedNameServer.PriorityDomain - 14, // 16: v2ray.core.app.dns.SimplifiedNameServer.geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP - 12, // 17: v2ray.core.app.dns.SimplifiedNameServer.original_rules:type_name -> v2ray.core.app.dns.SimplifiedNameServer.OriginalRule - 0, // 18: v2ray.core.app.dns.NameServer.PriorityDomain.type:type_name -> v2ray.core.app.dns.DomainMatchingType - 15, // 19: v2ray.core.app.dns.Config.HostsEntry.value:type_name -> v2ray.core.common.net.IPOrDomain - 0, // 20: v2ray.core.app.dns.SimplifiedNameServer.PriorityDomain.type:type_name -> v2ray.core.app.dns.DomainMatchingType - 21, // [21:21] is the sub-list for method output_type - 21, // [21:21] is the sub-list for method input_type - 21, // [21:21] is the sub-list for extension type_name - 21, // [21:21] is the sub-list for extension extendee - 0, // [0:21] is the sub-list for field type_name + 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 + 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 + 1, // 4: v2ray.core.app.dns.NameServer.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy + 2, // 5: v2ray.core.app.dns.NameServer.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy + 3, // 6: v2ray.core.app.dns.NameServer.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy + 0, // 7: v2ray.core.app.dns.HostMapping.type:type_name -> v2ray.core.app.dns.DomainMatchingType + 15, // 8: v2ray.core.app.dns.Config.NameServers:type_name -> v2ray.core.common.net.Endpoint + 4, // 9: v2ray.core.app.dns.Config.name_server:type_name -> v2ray.core.app.dns.NameServer + 12, // 10: v2ray.core.app.dns.Config.Hosts:type_name -> v2ray.core.app.dns.Config.HostsEntry + 5, // 11: v2ray.core.app.dns.Config.static_hosts:type_name -> v2ray.core.app.dns.HostMapping + 1, // 12: v2ray.core.app.dns.Config.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy + 2, // 13: v2ray.core.app.dns.Config.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy + 3, // 14: v2ray.core.app.dns.Config.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy + 9, // 15: v2ray.core.app.dns.SimplifiedConfig.name_server:type_name -> v2ray.core.app.dns.SimplifiedNameServer + 5, // 16: v2ray.core.app.dns.SimplifiedConfig.static_hosts:type_name -> v2ray.core.app.dns.HostMapping + 1, // 17: v2ray.core.app.dns.SimplifiedConfig.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy + 2, // 18: v2ray.core.app.dns.SimplifiedConfig.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy + 3, // 19: v2ray.core.app.dns.SimplifiedConfig.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy + 0, // 20: v2ray.core.app.dns.SimplifiedHostMapping.type:type_name -> v2ray.core.app.dns.DomainMatchingType + 15, // 21: v2ray.core.app.dns.SimplifiedNameServer.address:type_name -> v2ray.core.common.net.Endpoint + 13, // 22: v2ray.core.app.dns.SimplifiedNameServer.prioritized_domain:type_name -> v2ray.core.app.dns.SimplifiedNameServer.PriorityDomain + 16, // 23: v2ray.core.app.dns.SimplifiedNameServer.geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP + 14, // 24: v2ray.core.app.dns.SimplifiedNameServer.original_rules:type_name -> v2ray.core.app.dns.SimplifiedNameServer.OriginalRule + 1, // 25: v2ray.core.app.dns.SimplifiedNameServer.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy + 2, // 26: v2ray.core.app.dns.SimplifiedNameServer.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy + 3, // 27: v2ray.core.app.dns.SimplifiedNameServer.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy + 0, // 28: v2ray.core.app.dns.NameServer.PriorityDomain.type:type_name -> v2ray.core.app.dns.DomainMatchingType + 17, // 29: v2ray.core.app.dns.Config.HostsEntry.value:type_name -> v2ray.core.common.net.IPOrDomain + 0, // 30: v2ray.core.app.dns.SimplifiedNameServer.PriorityDomain.type:type_name -> v2ray.core.app.dns.DomainMatchingType + 31, // [31:31] is the sub-list for method output_type + 31, // [31:31] is the sub-list for method input_type + 31, // [31:31] is the sub-list for extension type_name + 31, // [31:31] is the sub-list for extension extendee + 0, // [0:31] is the sub-list for field type_name } func init() { file_app_dns_config_proto_init() } @@ -1277,12 +1588,14 @@ func file_app_dns_config_proto_init() { } } } + file_app_dns_config_proto_msgTypes[0].OneofWrappers = []interface{}{} + file_app_dns_config_proto_msgTypes[5].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_app_dns_config_proto_rawDesc, - NumEnums: 2, + NumEnums: 4, NumMessages: 11, NumExtensions: 0, NumServices: 0, diff --git a/app/dns/config.proto b/app/dns/config.proto index 21e16d6f2..9e137da59 100644 --- a/app/dns/config.proto +++ b/app/dns/config.proto @@ -15,7 +15,7 @@ import "common/protoext/extensions.proto"; message NameServer { v2ray.core.common.net.Endpoint address = 1; bytes client_ip = 5; - bool skipFallback = 6; + string tag = 7; message PriorityDomain { DomainMatchingType type = 1; @@ -30,6 +30,13 @@ message NameServer { repeated PriorityDomain prioritized_domain = 2; repeated v2ray.core.app.router.routercommon.GeoIP geoip = 3; repeated OriginalRule original_rules = 4; + + // Deprecated. Use fallback_strategy. + bool skipFallback = 6 [deprecated = true]; + + optional QueryStrategy query_strategy = 8; + optional CacheStrategy cache_strategy = 9; + optional FallbackStrategy fallback_strategy = 10; } enum DomainMatchingType { @@ -45,6 +52,16 @@ enum QueryStrategy { USE_IP6 = 2; } +enum CacheStrategy { + CacheEnabled = 0; + CacheDisabled = 1; +} + +enum FallbackStrategy { + Enabled = 0; + Disabled = 1; + DisabledIfAnyMatch = 2; +} message HostMapping { DomainMatchingType type = 1; @@ -82,13 +99,23 @@ message Config { reserved 7; // DisableCache disables DNS cache - bool disableCache = 8; + // Deprecated. Use cache_strategy. + bool disableCache = 8 [deprecated = true]; + // Deprecated. Use fallback_strategy. + bool disableFallback = 10 [deprecated = true]; + + // Deprecated. Use fallback_strategy. + bool disableFallbackIfMatch = 11 [deprecated = true]; + + // Default query strategy (IPv4, IPv6, or both) for each name server. QueryStrategy query_strategy = 9; - bool disableFallback = 10; + // Default cache strategy for each name server. + CacheStrategy cache_strategy = 12; - bool disableFallbackIfMatch = 11; + // Default fallback strategy for each name server. + FallbackStrategy fallback_strategy = 13; } @@ -121,13 +148,23 @@ message SimplifiedConfig { reserved 7; // DisableCache disables DNS cache - bool disableCache = 8; + // Deprecated. Use cache_strategy. + bool disableCache = 8 [deprecated = true]; + // Deprecated. Use fallback_strategy. + bool disableFallback = 10 [deprecated = true]; + + // Deprecated. Use fallback_strategy. + bool disableFallbackIfMatch = 11 [deprecated = true]; + + // Default query strategy (IPv4, IPv6, or both) for each name server. QueryStrategy query_strategy = 9; - bool disableFallback = 10; + // Default cache strategy for each name server. + CacheStrategy cache_strategy = 12; - bool disableFallbackIfMatch = 11; + // Default fallback strategy for each name server. + FallbackStrategy fallback_strategy = 13; } @@ -145,7 +182,7 @@ message SimplifiedHostMapping { message SimplifiedNameServer { v2ray.core.common.net.Endpoint address = 1; string client_ip = 5; - bool skipFallback = 6; + string tag = 7; message PriorityDomain { DomainMatchingType type = 1; @@ -160,4 +197,11 @@ message SimplifiedNameServer { repeated PriorityDomain prioritized_domain = 2; repeated v2ray.core.app.router.routercommon.GeoIP geoip = 3; repeated OriginalRule original_rules = 4; -} \ No newline at end of file + + // Deprecated. Use fallback_strategy. + bool skipFallback = 6 [deprecated = true]; + + optional QueryStrategy query_strategy = 8; + optional CacheStrategy cache_strategy = 9; + optional FallbackStrategy fallback_strategy = 10; +} diff --git a/app/dns/dns.go b/app/dns/dns.go index feca7c64d..5603e57b0 100644 --- a/app/dns/dns.go +++ b/app/dns/dns.go @@ -28,16 +28,13 @@ import ( // DNS is a DNS rely server. type DNS struct { sync.Mutex - tag string - disableCache bool - disableFallback bool - disableFallbackIfMatch bool - ipOption *dns.IPOption - hosts *StaticHosts - clients []*Client - ctx context.Context - domainMatcher strmatcher.IndexMatcher - matcherInfos []DomainMatcherInfo + ipOption dns.IPOption + hosts *StaticHosts + clients []*Client + ctx context.Context + clientTags map[string]bool + domainMatcher strmatcher.IndexMatcher + matcherInfos []DomainMatcherInfo } // DomainMatcherInfo contains information attached to index returned by Server.domainMatcher @@ -48,88 +45,31 @@ type DomainMatcherInfo struct { // New creates a new DNS server with given configuration. func New(ctx context.Context, config *Config) (*DNS, error) { - var tag string - if len(config.Tag) > 0 { - tag = config.Tag - } else { - tag = generateRandomTag() - } - - var clientIP net.IP - switch len(config.ClientIp) { - case 0, net.IPv4len, net.IPv6len: - clientIP = net.IP(config.ClientIp) - default: - return nil, newError("unexpected client IP length ", len(config.ClientIp)) - } - - var ipOption *dns.IPOption - switch config.QueryStrategy { - case QueryStrategy_USE_IP: - ipOption = &dns.IPOption{ - IPv4Enable: true, - IPv6Enable: true, - FakeEnable: false, - } - case QueryStrategy_USE_IP4: - ipOption = &dns.IPOption{ - IPv4Enable: true, - IPv6Enable: false, - FakeEnable: false, - } - case QueryStrategy_USE_IP6: - ipOption = &dns.IPOption{ - IPv4Enable: false, - IPv6Enable: true, - FakeEnable: false, - } - } - + // Create static hosts hosts, err := NewStaticHosts(config.StaticHosts, config.Hosts) if err != nil { return nil, newError("failed to create hosts").Base(err) } + // Create name servers from legacy configs clients := []*Client{} - domainRuleCount := 0 - for _, ns := range config.NameServer { - domainRuleCount += len(ns.PrioritizedDomain) - } - - // MatcherInfos is ensured to cover the maximum index domainMatcher could return, where matcher's index starts from 1 - matcherInfos := make([]DomainMatcherInfo, domainRuleCount+1) - domainMatcher := &strmatcher.LinearIndexMatcher{} - geoipContainer := router.GeoIPMatcherContainer{} - for _, endpoint := range config.NameServers { features.PrintDeprecatedFeatureWarning("simple DNS server") - client, err := NewSimpleClient(ctx, endpoint, clientIP) + client, err := NewClient(ctx, &NameServer{Address: endpoint}, config) if err != nil { return nil, newError("failed to create client").Base(err) } clients = append(clients, client) } - for _, ns := range config.NameServer { - clientIdx := len(clients) - updateDomain := func(domainRule strmatcher.Matcher, originalRuleIdx int, matcherInfos []DomainMatcherInfo) error { - midx := domainMatcher.Add(domainRule) - matcherInfos[midx] = DomainMatcherInfo{ - clientIdx: uint16(clientIdx), - domainRuleIdx: uint16(originalRuleIdx), - } - return nil - } - - myClientIP := clientIP - switch len(ns.ClientIp) { - case net.IPv4len, net.IPv6len: - myClientIP = net.IP(ns.ClientIp) - } - client, err := NewClient(ctx, ns, myClientIP, geoipContainer, &matcherInfos, updateDomain) + // Create name servers + nsClientMap := map[int]int{} + for nsIdx, ns := range config.NameServer { + client, err := NewClient(ctx, ns, config) if err != nil { return nil, newError("failed to create client").Base(err) } + nsClientMap[nsIdx] = len(clients) clients = append(clients, client) } @@ -138,20 +78,94 @@ func New(ctx context.Context, config *Config) (*DNS, error) { clients = append(clients, NewLocalDNSClient()) } + // Establish members related to global DNS state + domainMatcher, matcherInfos, err := establishDomainRules(config, clients, nsClientMap) + if err != nil { + return nil, err + } + 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{ - tag: tag, - hosts: hosts, - ipOption: ipOption, - clients: clients, - ctx: ctx, - domainMatcher: domainMatcher, - matcherInfos: matcherInfos, - disableCache: config.DisableCache, - disableFallback: config.DisableFallback, - disableFallbackIfMatch: config.DisableFallbackIfMatch, + ipOption: toIPOption(config.QueryStrategy), + hosts: hosts, + clients: clients, + ctx: ctx, + clientTags: clientTags, + domainMatcher: domainMatcher, + matcherInfos: matcherInfos, }, nil } +func establishDomainRules(config *Config, clients []*Client, nsClientMap map[int]int) (strmatcher.IndexMatcher, []DomainMatcherInfo, error) { + domainRuleCount := 0 + for _, ns := range config.NameServer { + domainRuleCount += len(ns.PrioritizedDomain) + } + // MatcherInfos is ensured to cover the maximum index domainMatcher could return, where matcher's index starts from 1 + matcherInfos := make([]DomainMatcherInfo, domainRuleCount+1) + domainMatcher := &strmatcher.LinearIndexMatcher{} + for nsIdx, ns := range config.NameServer { + clientIdx := nsClientMap[nsIdx] + var rules []string + ruleCurr := 0 + ruleIter := 0 + for _, domain := range ns.PrioritizedDomain { + domainRule, err := toStrMatcher(domain.Type, domain.Domain) + if err != nil { + return nil, nil, newError("failed to create prioritized domain").Base(err).AtWarning() + } + originalRuleIdx := ruleCurr + if ruleCurr < len(ns.OriginalRules) { + rule := ns.OriginalRules[ruleCurr] + if ruleCurr >= len(rules) { + rules = append(rules, rule.Rule) + } + ruleIter++ + if ruleIter >= int(rule.Size) { + ruleIter = 0 + ruleCurr++ + } + } else { // No original rule, generate one according to current domain matcher (majorly for compatibility with tests) + rules = append(rules, domainRule.String()) + ruleCurr++ + } + midx := domainMatcher.Add(domainRule) + matcherInfos[midx] = DomainMatcherInfo{ + clientIdx: uint16(clientIdx), + domainRuleIdx: uint16(originalRuleIdx), + } + if err != nil { + return nil, nil, newError("failed to create prioritized domain").Base(err).AtWarning() + } + } + clients[clientIdx].domains = rules + } + return domainMatcher, matcherInfos, nil +} + +func establishExpectedIPs(config *Config, clients []*Client, nsClientMap map[int]int) error { + geoipContainer := router.GeoIPMatcherContainer{} + for nsIdx, ns := range config.NameServer { + clientIdx := nsClientMap[nsIdx] + var matchers []*router.GeoIPMatcher + for _, geoip := range ns.Geoip { + matcher, err := geoipContainer.Add(geoip) + if err != nil { + return newError("failed to create ip matcher").Base(err).AtWarning() + } + matchers = append(matchers, matcher) + } + clients[clientIdx].expectIPs = matchers + } + return nil +} + // Type implements common.HasType. func (*DNS) Type() interface{} { return dns.ClientType() @@ -170,32 +184,28 @@ func (s *DNS) Close() error { // IsOwnLink implements proxy.dns.ownLinkVerifier func (s *DNS) IsOwnLink(ctx context.Context) bool { inbound := session.InboundFromContext(ctx) - return inbound != nil && inbound.Tag == s.tag + return inbound != nil && s.clientTags[inbound.Tag] } // LookupIP implements dns.Client. func (s *DNS) LookupIP(domain string) ([]net.IP, error) { - return s.lookupIPInternal(domain, *s.ipOption) + return s.lookupIPInternal(domain, s.ipOption) } // LookupIPv4 implements dns.IPv4Lookup. func (s *DNS) LookupIPv4(domain string) ([]net.IP, error) { - if !s.ipOption.IPv4Enable { - return nil, dns.ErrEmptyResponse + if option := s.ipOption.With(dns.IPOption{IPv4Enable: true}); option.IsValid() { + return s.lookupIPInternal(domain, option) } - o := *s.ipOption - o.IPv6Enable = false - return s.lookupIPInternal(domain, o) + return nil, dns.ErrEmptyResponse } // LookupIPv6 implements dns.IPv6Lookup. func (s *DNS) LookupIPv6(domain string) ([]net.IP, error) { - if !s.ipOption.IPv6Enable { - return nil, dns.ErrEmptyResponse + if option := s.ipOption.With(dns.IPOption{IPv6Enable: true}); option.IsValid() { + return s.lookupIPInternal(domain, option) } - o := *s.ipOption - o.IPv4Enable = false - return s.lookupIPInternal(domain, o) + return nil, dns.ErrEmptyResponse } func (s *DNS) lookupIPInternal(domain string, option dns.IPOption) ([]net.IP, error) { @@ -222,22 +232,19 @@ func (s *DNS) lookupIPInternal(domain string, option dns.IPOption) ([]net.IP, er // Name servers lookup errs := []error{} - ctx := session.ContextWithInbound(s.ctx, &session.Inbound{Tag: s.tag}) - for _, client := range s.sortClients(domain) { - if !option.FakeEnable && strings.EqualFold(client.Name(), "FakeDNS") { - newError("skip DNS resolution for domain ", domain, " at server ", client.Name()).AtDebug().WriteToLog() - continue - } - ips, err := client.QueryIP(ctx, domain, option, s.disableCache) + for _, client := range s.sortClients(domain, option) { + ips, err := client.QueryIP(s.ctx, domain, option) if len(ips) > 0 { return ips, nil } if err != nil { - newError("failed to lookup ip for domain ", domain, " at server ", client.Name()).Base(err).WriteToLog() errs = append(errs, err) } + if err != dns.ErrEmptyResponse { // ErrEmptyResponse is not seen as failure, so no failed log + newError("failed to lookup ip for domain ", domain, " at server ", client.Name()).Base(err).WriteToLog() + } if err != context.Canceled && err != context.DeadlineExceeded && err != errExpectedIPNonMatch { - return nil, err + return nil, err // Continues lookup for certain errors } } @@ -246,7 +253,7 @@ func (s *DNS) lookupIPInternal(domain string, option dns.IPOption) ([]net.IP, er // GetIPOption implements ClientWithIPOption. func (s *DNS) GetIPOption() *dns.IPOption { - return s.ipOption + return &s.ipOption } // SetQueryOption implements ClientWithIPOption. @@ -260,51 +267,52 @@ func (s *DNS) SetFakeDNSOption(isFakeEnable bool) { s.ipOption.FakeEnable = isFakeEnable } -func (s *DNS) sortClients(domain string) []*Client { +func (s *DNS) sortClients(domain string, option dns.IPOption) []*Client { clients := make([]*Client, 0, len(s.clients)) clientUsed := make([]bool, len(s.clients)) clientNames := make([]string, 0, len(s.clients)) domainRules := []string{} // Priority domain matching - hasMatch := false for _, match := range s.domainMatcher.Match(domain) { info := s.matcherInfos[match] client := s.clients[info.clientIdx] domainRule := client.domains[info.domainRuleIdx] domainRules = append(domainRules, fmt.Sprintf("%s(DNS idx:%d)", domainRule, info.clientIdx)) - if clientUsed[info.clientIdx] { + switch { + case clientUsed[info.clientIdx]: + continue + case !option.FakeEnable && strings.EqualFold(client.Name(), "FakeDNS"): continue } clientUsed[info.clientIdx] = true clients = append(clients, client) clientNames = append(clientNames, client.Name()) - hasMatch = true } - if !(s.disableFallback || s.disableFallbackIfMatch && hasMatch) { - // Default round-robin query - for idx, client := range s.clients { - if clientUsed[idx] || client.skipFallback { - continue - } - clientUsed[idx] = true - clients = append(clients, client) - clientNames = append(clientNames, client.Name()) + // Default round-robin query + hasDomainMatch := len(clients) > 0 + for idx, client := range s.clients { + switch { + case clientUsed[idx]: + continue + case !option.FakeEnable && strings.EqualFold(client.Name(), "FakeDNS"): + continue + case client.fallbackStrategy == FallbackStrategy_Disabled: + continue + case client.fallbackStrategy == FallbackStrategy_DisabledIfAnyMatch && hasDomainMatch: + continue } + clientUsed[idx] = true + clients = append(clients, client) + clientNames = append(clientNames, client.Name()) } if len(domainRules) > 0 { newError("domain ", domain, " matches following rules: ", domainRules).AtDebug().WriteToLog() } if len(clientNames) > 0 { - newError("domain ", domain, " will use DNS in order: ", clientNames).AtDebug().WriteToLog() - } - - if len(clients) == 0 { - clients = append(clients, s.clients[0]) - clientNames = append(clientNames, s.clients[0].Name()) - newError("domain ", domain, " will use the first DNS: ", clientNames).AtDebug().WriteToLog() + newError("domain ", domain, " will use DNS in order: ", clientNames, " ", toReqTypes(option)).AtDebug().WriteToLog() } return clients @@ -354,10 +362,14 @@ func init() { for _, v := range simplifiedConfig.NameServer { nameserver := &NameServer{ - Address: v.Address, - ClientIp: net.ParseIP(v.ClientIp), - SkipFallback: v.SkipFallback, - Geoip: v.Geoip, + Address: v.Address, + ClientIp: net.ParseIP(v.ClientIp), + Tag: v.Tag, + QueryStrategy: v.QueryStrategy, + CacheStrategy: v.CacheStrategy, + FallbackStrategy: v.FallbackStrategy, + SkipFallback: v.SkipFallback, + Geoip: v.Geoip, } for _, prioritizedDomain := range v.PrioritizedDomain { nameserver.PrioritizedDomain = append(nameserver.PrioritizedDomain, &NameServer_PriorityDomain{ @@ -369,13 +381,17 @@ func init() { } fullConfig := &Config{ - NameServer: nameservers, - ClientIp: net.ParseIP(simplifiedConfig.ClientIp), - StaticHosts: simplifiedConfig.StaticHosts, - Tag: simplifiedConfig.Tag, - DisableCache: simplifiedConfig.DisableCache, - QueryStrategy: simplifiedConfig.QueryStrategy, - DisableFallback: simplifiedConfig.DisableFallback, + StaticHosts: simplifiedConfig.StaticHosts, + NameServer: nameservers, + ClientIp: net.ParseIP(simplifiedConfig.ClientIp), + Tag: simplifiedConfig.Tag, + QueryStrategy: simplifiedConfig.QueryStrategy, + CacheStrategy: simplifiedConfig.CacheStrategy, + FallbackStrategy: simplifiedConfig.FallbackStrategy, + // Deprecated flags + DisableCache: simplifiedConfig.DisableCache, + DisableFallback: simplifiedConfig.DisableFallback, + DisableFallbackIfMatch: simplifiedConfig.DisableFallbackIfMatch, } return common.CreateObject(ctx, fullConfig) })) diff --git a/app/dns/nameserver.go b/app/dns/nameserver.go index a47a7e82b..1af0844b4 100644 --- a/app/dns/nameserver.go +++ b/app/dns/nameserver.go @@ -10,7 +10,8 @@ import ( "github.com/v2fly/v2ray-core/v5/app/router" "github.com/v2fly/v2ray-core/v5/common/errors" "github.com/v2fly/v2ray-core/v5/common/net" - "github.com/v2fly/v2ray-core/v5/common/strmatcher" + "github.com/v2fly/v2ray-core/v5/common/session" + "github.com/v2fly/v2ray-core/v5/features" "github.com/v2fly/v2ray-core/v5/features/dns" "github.com/v2fly/v2ray-core/v5/features/routing" ) @@ -25,11 +26,16 @@ type Server interface { // Client is the interface for DNS client. type Client struct { - server Server - clientIP net.IP - skipFallback bool - domains []string - expectIPs []*router.GeoIPMatcher + server Server + clientIP net.IP + tag string + + queryStrategy dns.IPOption + cacheStrategy CacheStrategy + fallbackStrategy FallbackStrategy + + domains []string + expectIPs []*router.GeoIPMatcher } var errExpectedIPNonMatch = errors.New("expectIPs not match") @@ -68,117 +74,79 @@ func NewServer(dest net.Destination, dispatcher routing.Dispatcher) (Server, err } // NewClient creates a DNS client managing a name server with client IP, domain rules and expected IPs. -func NewClient(ctx context.Context, ns *NameServer, clientIP net.IP, container router.GeoIPMatcherContainer, matcherInfos *[]DomainMatcherInfo, updateDomainRule func(strmatcher.Matcher, int, []DomainMatcherInfo) error) (*Client, error) { +func NewClient(ctx context.Context, ns *NameServer, dns *Config) (*Client, error) { client := &Client{} + // Create DNS server instance err := core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) 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() } - - // Priotize local domains with specific TLDs or without any dot to local DNS - if _, isLocalDNS := server.(*LocalNameServer); isLocalDNS { - ns.PrioritizedDomain = append(ns.PrioritizedDomain, localTLDsAndDotlessDomains...) - ns.OriginalRules = append(ns.OriginalRules, localTLDsAndDotlessDomainsRule) - // The following lines is a solution to avoid core panics(rule index out of range) when setting `localhost` DNS client in config. - // Because the `localhost` DNS client will apend len(localTLDsAndDotlessDomains) rules into matcherInfos to match `geosite:private` default rule. - // But `matcherInfos` has no enough length to add rules, which leads to core panics (rule index out of range). - // To avoid this, the length of `matcherInfos` must be equal to the expected, so manually append it with Golang default zero value first for later modification. - // Related issues: - // https://github.com/v2fly/v2ray-core/issues/529 - // https://github.com/v2fly/v2ray-core/issues/719 - for i := 0; i < len(localTLDsAndDotlessDomains); i++ { - *matcherInfos = append(*matcherInfos, DomainMatcherInfo{ - clientIdx: uint16(0), - domainRuleIdx: uint16(0), - }) - } - } - - // Establish domain rules - var rules []string - ruleCurr := 0 - ruleIter := 0 - for _, domain := range ns.PrioritizedDomain { - domainRule, err := toStrMatcher(domain.Type, domain.Domain) - if err != nil { - return newError("failed to create prioritized domain").Base(err).AtWarning() - } - originalRuleIdx := ruleCurr - if ruleCurr < len(ns.OriginalRules) { - rule := ns.OriginalRules[ruleCurr] - if ruleCurr >= len(rules) { - rules = append(rules, rule.Rule) - } - ruleIter++ - if ruleIter >= int(rule.Size) { - ruleIter = 0 - ruleCurr++ - } - } else { // No original rule, generate one according to current domain matcher (majorly for compatibility with tests) - rules = append(rules, domainRule.String()) - ruleCurr++ - } - err = updateDomainRule(domainRule, originalRuleIdx, *matcherInfos) - if err != nil { - return newError("failed to create prioritized domain").Base(err).AtWarning() - } - } - - // Establish expected IPs - var matchers []*router.GeoIPMatcher - for _, geoip := range ns.Geoip { - matcher, err := container.Add(geoip) - if err != nil { - return newError("failed to create ip matcher").Base(err).AtWarning() - } - matchers = append(matchers, matcher) - } - - if len(clientIP) > 0 { - switch ns.Address.Address.GetAddress().(type) { - case *net.IPOrDomain_Domain: - newError("DNS: client ", ns.Address.Address.GetDomain(), " uses clientIP ", clientIP.String()).AtInfo().WriteToLog() - case *net.IPOrDomain_Ip: - newError("DNS: client ", ns.Address.Address.GetIp(), " uses clientIP ", clientIP.String()).AtInfo().WriteToLog() - } - } - client.server = server - client.clientIP = clientIP - client.skipFallback = ns.SkipFallback - client.domains = rules - client.expectIPs = matchers return nil }) - return client, err -} + if err != nil { + return nil, err + } -// NewSimpleClient creates a DNS client with a simple destination. -func NewSimpleClient(ctx context.Context, endpoint *net.Endpoint, clientIP net.IP) (*Client, error) { - client := &Client{} - err := core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error { - server, err := NewServer(endpoint.AsDestination(), dispatcher) - if err != nil { - return newError("failed to create nameserver").Base(err).AtWarning() + // Initialize fields with default values + if len(ns.Tag) == 0 { + ns.Tag = dns.Tag + if len(ns.Tag) == 0 { + ns.Tag = generateRandomTag() } - client.server = server - client.clientIP = clientIP - return nil - }) - - if len(clientIP) > 0 { - switch endpoint.Address.GetAddress().(type) { - case *net.IPOrDomain_Domain: - newError("DNS: client ", endpoint.Address.GetDomain(), " uses clientIP ", clientIP.String()).AtInfo().WriteToLog() - case *net.IPOrDomain_Ip: - newError("DNS: client ", endpoint.Address.GetIp(), " uses clientIP ", clientIP.String()).AtInfo().WriteToLog() + } + if len(ns.ClientIp) == 0 { + ns.ClientIp = dns.ClientIp + } + if ns.QueryStrategy == nil { + ns.QueryStrategy = &dns.QueryStrategy + } + if ns.CacheStrategy == nil { + ns.CacheStrategy = new(CacheStrategy) + switch { + case dns.CacheStrategy != CacheStrategy_CacheEnabled: + *ns.CacheStrategy = dns.CacheStrategy + case dns.DisableCache: + features.PrintDeprecatedFeatureWarning("DNS disableCache settings") + *ns.CacheStrategy = CacheStrategy_CacheDisabled + } + } + if ns.FallbackStrategy == nil { + ns.FallbackStrategy = new(FallbackStrategy) + switch { + case ns.SkipFallback: + features.PrintDeprecatedFeatureWarning("DNS server skipFallback settings") + *ns.FallbackStrategy = FallbackStrategy_Disabled + case dns.FallbackStrategy != FallbackStrategy_Enabled: + *ns.FallbackStrategy = dns.FallbackStrategy + case dns.DisableFallback: + features.PrintDeprecatedFeatureWarning("DNS disableFallback settings") + *ns.FallbackStrategy = FallbackStrategy_Disabled + case dns.DisableFallbackIfMatch: + features.PrintDeprecatedFeatureWarning("DNS disableFallbackIfMatch settings") + *ns.FallbackStrategy = FallbackStrategy_DisabledIfAnyMatch } } - return client, err + // Priotize local domains with specific TLDs or without any dot to local DNS + if strings.EqualFold(ns.Address.Address.GetDomain(), "localhost") { + ns.PrioritizedDomain = append(ns.PrioritizedDomain, localTLDsAndDotlessDomains...) + ns.OriginalRules = append(ns.OriginalRules, localTLDsAndDotlessDomainsRule) + } + + if len(ns.ClientIp) > 0 { + newError("DNS: client ", ns.Address.Address.AsAddress(), " uses clientIP ", net.IP(ns.ClientIp).String()).AtInfo().WriteToLog() + } + + client.clientIP = ns.ClientIp + client.tag = ns.Tag + client.queryStrategy = toIPOption(*ns.QueryStrategy) + client.cacheStrategy = *ns.CacheStrategy + client.fallbackStrategy = *ns.FallbackStrategy + return client, nil } // Name returns the server name the client manages. @@ -187,9 +155,17 @@ func (c *Client) Name() string { } // QueryIP send DNS query to the name server with the client's IP. -func (c *Client) QueryIP(ctx context.Context, domain string, option dns.IPOption, disableCache bool) ([]net.IP, error) { +func (c *Client) QueryIP(ctx context.Context, domain string, option dns.IPOption) ([]net.IP, error) { + queryOption := option.With(c.queryStrategy) + if !queryOption.IsValid() { + newError(c.server.Name(), " returns empty answer: ", domain, ". ", toReqTypes(option)).AtInfo().WriteToLog() + return nil, dns.ErrEmptyResponse + } + disableCache := c.cacheStrategy == CacheStrategy_CacheDisabled + + ctx = session.ContextWithInbound(ctx, &session.Inbound{Tag: c.tag}) ctx, cancel := context.WithTimeout(ctx, 4*time.Second) - ips, err := c.server.QueryIP(ctx, domain, c.clientIP, option, disableCache) + ips, err := c.server.QueryIP(ctx, domain, c.clientIP, queryOption, disableCache) cancel() if err != nil { diff --git a/features/dns/client.go b/features/dns/client.go index e421aacbf..5fa5e2aa8 100644 --- a/features/dns/client.go +++ b/features/dns/client.go @@ -14,6 +14,18 @@ type IPOption struct { FakeEnable bool } +func (opt IPOption) With(other IPOption) IPOption { + return IPOption{ + IPv4Enable: opt.IPv4Enable && other.IPv4Enable, + IPv6Enable: opt.IPv6Enable && other.IPv6Enable, + FakeEnable: opt.FakeEnable && other.FakeEnable, + } +} + +func (opt IPOption) IsValid() bool { + return opt.IPv4Enable || opt.IPv6Enable +} + // Client is a V2Ray feature for querying DNS information. // // v2ray:api:stable diff --git a/infra/conf/synthetic/dns/dns.go b/infra/conf/synthetic/dns/dns.go index 07ff9c7d0..fc2c0dd33 100644 --- a/infra/conf/synthetic/dns/dns.go +++ b/infra/conf/synthetic/dns/dns.go @@ -18,12 +18,16 @@ import ( ) type NameServerConfig struct { - Address *cfgcommon.Address - ClientIP *cfgcommon.Address - Port uint16 - SkipFallback bool - Domains []string - ExpectIPs cfgcommon.StringList + Address *cfgcommon.Address + ClientIP *cfgcommon.Address + Port uint16 + Tag string + QueryStrategy string + CacheStrategy string + FallbackStrategy string + SkipFallback bool + Domains []string + ExpectIPs cfgcommon.StringList cfgctx context.Context } @@ -36,17 +40,25 @@ func (c *NameServerConfig) UnmarshalJSON(data []byte) error { } var advanced struct { - Address *cfgcommon.Address `json:"address"` - ClientIP *cfgcommon.Address `json:"clientIp"` - Port uint16 `json:"port"` - SkipFallback bool `json:"skipFallback"` - Domains []string `json:"domains"` - ExpectIPs cfgcommon.StringList `json:"expectIps"` + Address *cfgcommon.Address `json:"address"` + ClientIP *cfgcommon.Address `json:"clientIp"` + Port uint16 `json:"port"` + Tag string `json:"tag"` + QueryStrategy string `json:"queryStrategy"` + CacheStrategy string `json:"cacheStrategy"` + FallbackStrategy string `json:"fallbackStrategy"` + SkipFallback bool `json:"skipFallback"` + Domains []string `json:"domains"` + ExpectIPs cfgcommon.StringList `json:"expectIps"` } if err := json.Unmarshal(data, &advanced); err == nil { c.Address = advanced.Address c.ClientIP = advanced.ClientIP c.Port = advanced.Port + c.Tag = advanced.Tag + c.QueryStrategy = advanced.QueryStrategy + c.CacheStrategy = advanced.CacheStrategy + c.FallbackStrategy = advanced.FallbackStrategy c.SkipFallback = advanced.SkipFallback c.Domains = advanced.Domains c.ExpectIPs = advanced.ExpectIPs @@ -117,6 +129,40 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) { myClientIP = []byte(c.ClientIP.IP()) } + queryStrategy := new(dns.QueryStrategy) + switch strings.ToLower(c.QueryStrategy) { + case "useip", "use_ip", "use-ip": + *queryStrategy = dns.QueryStrategy_USE_IP + case "useip4", "useipv4", "use_ip4", "use_ipv4", "use_ip_v4", "use-ip4", "use-ipv4", "use-ip-v4": + *queryStrategy = dns.QueryStrategy_USE_IP4 + case "useip6", "useipv6", "use_ip6", "use_ipv6", "use_ip_v6", "use-ip6", "use-ipv6", "use-ip-v6": + *queryStrategy = dns.QueryStrategy_USE_IP6 + default: + queryStrategy = nil + } + + cacheStrategy := new(dns.CacheStrategy) + switch strings.ToLower(c.CacheStrategy) { + case "enabled": + *cacheStrategy = dns.CacheStrategy_CacheEnabled + case "disabled": + *cacheStrategy = dns.CacheStrategy_CacheDisabled + default: + cacheStrategy = nil + } + + fallbackStrategy := new(dns.FallbackStrategy) + switch strings.ToLower(c.FallbackStrategy) { + case "enabled": + *fallbackStrategy = dns.FallbackStrategy_Enabled + case "disabled": + *fallbackStrategy = dns.FallbackStrategy_Disabled + case "disabledifanymatch", "disabled_if_any_match", "disabled-if-any-match": + *fallbackStrategy = dns.FallbackStrategy_DisabledIfAnyMatch + default: + fallbackStrategy = nil + } + return &dns.NameServer{ Address: &net.Endpoint{ Network: net.Network_UDP, @@ -124,7 +170,11 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) { Port: uint32(c.Port), }, ClientIp: myClientIP, + Tag: c.Tag, SkipFallback: c.SkipFallback, + QueryStrategy: queryStrategy, + CacheStrategy: cacheStrategy, + FallbackStrategy: fallbackStrategy, PrioritizedDomain: domains, Geoip: geoipList, OriginalRules: originalRules, @@ -145,6 +195,8 @@ type DNSConfig struct { // nolint: revive ClientIP *cfgcommon.Address `json:"clientIp"` Tag string `json:"tag"` QueryStrategy string `json:"queryStrategy"` + CacheStrategy string `json:"cacheStrategy"` + FallbackStrategy string `json:"fallbackStrategy"` DisableCache bool `json:"disableCache"` DisableFallback bool `json:"disableFallback"` DisableFallbackIfMatch bool `json:"disableFallbackIfMatch"` @@ -245,6 +297,24 @@ func (c *DNSConfig) Build() (*dns.Config, error) { config.QueryStrategy = dns.QueryStrategy_USE_IP6 } + config.CacheStrategy = dns.CacheStrategy_CacheEnabled + switch strings.ToLower(c.CacheStrategy) { + case "enabled": + config.CacheStrategy = dns.CacheStrategy_CacheEnabled + case "disabled": + config.CacheStrategy = dns.CacheStrategy_CacheDisabled + } + + config.FallbackStrategy = dns.FallbackStrategy_Enabled + switch strings.ToLower(c.FallbackStrategy) { + case "enabled": + config.FallbackStrategy = dns.FallbackStrategy_Enabled + case "disabled": + config.FallbackStrategy = dns.FallbackStrategy_Disabled + case "disabledifanymatch", "disabled_if_any_match", "disabled-if-any-match": + config.FallbackStrategy = dns.FallbackStrategy_DisabledIfAnyMatch + } + for _, server := range c.Servers { server.cfgctx = c.cfgctx ns, err := server.Build()