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

support per-domain prioritized name server

This commit is contained in:
Darien Raymond 2018-08-24 21:51:03 +02:00
parent b45ff351c3
commit f227e85b54
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
7 changed files with 354 additions and 85 deletions

View File

@ -16,33 +16,130 @@ var _ = math.Inf
// proto package needs to be updated. // proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Config_HostMapping_Type int32 type DomainMatchingType int32
const ( const (
Config_HostMapping_Full Config_HostMapping_Type = 0 DomainMatchingType_Full DomainMatchingType = 0
Config_HostMapping_SubDomain Config_HostMapping_Type = 1 DomainMatchingType_Subdomain DomainMatchingType = 1
DomainMatchingType_Keyword DomainMatchingType = 2
) )
var Config_HostMapping_Type_name = map[int32]string{ var DomainMatchingType_name = map[int32]string{
0: "Full", 0: "Full",
1: "SubDomain", 1: "Subdomain",
2: "Keyword",
} }
var Config_HostMapping_Type_value = map[string]int32{ var DomainMatchingType_value = map[string]int32{
"Full": 0, "Full": 0,
"SubDomain": 1, "Subdomain": 1,
"Keyword": 2,
} }
func (x Config_HostMapping_Type) String() string { func (x DomainMatchingType) String() string {
return proto.EnumName(Config_HostMapping_Type_name, int32(x)) return proto.EnumName(DomainMatchingType_name, int32(x))
} }
func (Config_HostMapping_Type) EnumDescriptor() ([]byte, []int) { func (DomainMatchingType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_config_b3d430ec01af18aa, []int{0, 1, 0} return fileDescriptor_config_6f85f947d5116df4, []int{0}
}
type NameServer struct {
Address *net.Endpoint `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
PrioritizedDomain []*NameServer_PriorityDomain `protobuf:"bytes,2,rep,name=prioritized_domain,json=prioritizedDomain,proto3" json:"prioritized_domain,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *NameServer) Reset() { *m = NameServer{} }
func (m *NameServer) String() string { return proto.CompactTextString(m) }
func (*NameServer) ProtoMessage() {}
func (*NameServer) Descriptor() ([]byte, []int) {
return fileDescriptor_config_6f85f947d5116df4, []int{0}
}
func (m *NameServer) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NameServer.Unmarshal(m, b)
}
func (m *NameServer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_NameServer.Marshal(b, m, deterministic)
}
func (dst *NameServer) XXX_Merge(src proto.Message) {
xxx_messageInfo_NameServer.Merge(dst, src)
}
func (m *NameServer) XXX_Size() int {
return xxx_messageInfo_NameServer.Size(m)
}
func (m *NameServer) XXX_DiscardUnknown() {
xxx_messageInfo_NameServer.DiscardUnknown(m)
}
var xxx_messageInfo_NameServer proto.InternalMessageInfo
func (m *NameServer) GetAddress() *net.Endpoint {
if m != nil {
return m.Address
}
return nil
}
func (m *NameServer) GetPrioritizedDomain() []*NameServer_PriorityDomain {
if m != nil {
return m.PrioritizedDomain
}
return nil
}
type NameServer_PriorityDomain struct {
Type DomainMatchingType `protobuf:"varint,1,opt,name=type,proto3,enum=v2ray.core.app.dns.DomainMatchingType" json:"type,omitempty"`
Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *NameServer_PriorityDomain) Reset() { *m = NameServer_PriorityDomain{} }
func (m *NameServer_PriorityDomain) String() string { return proto.CompactTextString(m) }
func (*NameServer_PriorityDomain) ProtoMessage() {}
func (*NameServer_PriorityDomain) Descriptor() ([]byte, []int) {
return fileDescriptor_config_6f85f947d5116df4, []int{0, 0}
}
func (m *NameServer_PriorityDomain) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NameServer_PriorityDomain.Unmarshal(m, b)
}
func (m *NameServer_PriorityDomain) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_NameServer_PriorityDomain.Marshal(b, m, deterministic)
}
func (dst *NameServer_PriorityDomain) XXX_Merge(src proto.Message) {
xxx_messageInfo_NameServer_PriorityDomain.Merge(dst, src)
}
func (m *NameServer_PriorityDomain) XXX_Size() int {
return xxx_messageInfo_NameServer_PriorityDomain.Size(m)
}
func (m *NameServer_PriorityDomain) XXX_DiscardUnknown() {
xxx_messageInfo_NameServer_PriorityDomain.DiscardUnknown(m)
}
var xxx_messageInfo_NameServer_PriorityDomain proto.InternalMessageInfo
func (m *NameServer_PriorityDomain) GetType() DomainMatchingType {
if m != nil {
return m.Type
}
return DomainMatchingType_Full
}
func (m *NameServer_PriorityDomain) GetDomain() string {
if m != nil {
return m.Domain
}
return ""
} }
type Config struct { type Config struct {
// Nameservers used by this DNS. Only traditional UDP servers are support at the moment. // Nameservers used by this DNS. Only traditional UDP servers are support at the moment.
// A special value 'localhost' as a domain address can be set to use DNS on local system. // A special value 'localhost' as a domain address can be set to use DNS on local system.
NameServers []*net.Endpoint `protobuf:"bytes,1,rep,name=NameServers,proto3" json:"NameServers,omitempty"` NameServers []*net.Endpoint `protobuf:"bytes,1,rep,name=NameServers,proto3" json:"NameServers,omitempty"` // Deprecated: Do not use.
// NameServer list used by this DNS client.
NameServer []*NameServer `protobuf:"bytes,5,rep,name=name_server,json=nameServer,proto3" json:"name_server,omitempty"`
// Static hosts. Domain to IP. // Static hosts. Domain to IP.
// Deprecated. Use static_hosts. // Deprecated. Use static_hosts.
Hosts map[string]*net.IPOrDomain `protobuf:"bytes,2,rep,name=Hosts,proto3" json:"Hosts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Deprecated: Do not use. Hosts map[string]*net.IPOrDomain `protobuf:"bytes,2,rep,name=Hosts,proto3" json:"Hosts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Deprecated: Do not use.
@ -58,7 +155,7 @@ func (m *Config) Reset() { *m = Config{} }
func (m *Config) String() string { return proto.CompactTextString(m) } func (m *Config) String() string { return proto.CompactTextString(m) }
func (*Config) ProtoMessage() {} func (*Config) ProtoMessage() {}
func (*Config) Descriptor() ([]byte, []int) { func (*Config) Descriptor() ([]byte, []int) {
return fileDescriptor_config_b3d430ec01af18aa, []int{0} return fileDescriptor_config_6f85f947d5116df4, []int{1}
} }
func (m *Config) XXX_Unmarshal(b []byte) error { func (m *Config) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Config.Unmarshal(m, b) return xxx_messageInfo_Config.Unmarshal(m, b)
@ -78,6 +175,7 @@ func (m *Config) XXX_DiscardUnknown() {
var xxx_messageInfo_Config proto.InternalMessageInfo var xxx_messageInfo_Config proto.InternalMessageInfo
// Deprecated: Do not use.
func (m *Config) GetNameServers() []*net.Endpoint { func (m *Config) GetNameServers() []*net.Endpoint {
if m != nil { if m != nil {
return m.NameServers return m.NameServers
@ -85,6 +183,13 @@ func (m *Config) GetNameServers() []*net.Endpoint {
return nil return nil
} }
func (m *Config) GetNameServer() []*NameServer {
if m != nil {
return m.NameServer
}
return nil
}
// Deprecated: Do not use. // Deprecated: Do not use.
func (m *Config) GetHosts() map[string]*net.IPOrDomain { func (m *Config) GetHosts() map[string]*net.IPOrDomain {
if m != nil { if m != nil {
@ -108,19 +213,19 @@ func (m *Config) GetStaticHosts() []*Config_HostMapping {
} }
type Config_HostMapping struct { type Config_HostMapping struct {
Type Config_HostMapping_Type `protobuf:"varint,1,opt,name=type,proto3,enum=v2ray.core.app.dns.Config_HostMapping_Type" json:"type,omitempty"` Type DomainMatchingType `protobuf:"varint,1,opt,name=type,proto3,enum=v2ray.core.app.dns.DomainMatchingType" json:"type,omitempty"`
Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"` Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"`
Ip [][]byte `protobuf:"bytes,3,rep,name=ip,proto3" json:"ip,omitempty"` Ip [][]byte `protobuf:"bytes,3,rep,name=ip,proto3" json:"ip,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
} }
func (m *Config_HostMapping) Reset() { *m = Config_HostMapping{} } func (m *Config_HostMapping) Reset() { *m = Config_HostMapping{} }
func (m *Config_HostMapping) String() string { return proto.CompactTextString(m) } func (m *Config_HostMapping) String() string { return proto.CompactTextString(m) }
func (*Config_HostMapping) ProtoMessage() {} func (*Config_HostMapping) ProtoMessage() {}
func (*Config_HostMapping) Descriptor() ([]byte, []int) { func (*Config_HostMapping) Descriptor() ([]byte, []int) {
return fileDescriptor_config_b3d430ec01af18aa, []int{0, 1} return fileDescriptor_config_6f85f947d5116df4, []int{1, 1}
} }
func (m *Config_HostMapping) XXX_Unmarshal(b []byte) error { func (m *Config_HostMapping) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Config_HostMapping.Unmarshal(m, b) return xxx_messageInfo_Config_HostMapping.Unmarshal(m, b)
@ -140,11 +245,11 @@ func (m *Config_HostMapping) XXX_DiscardUnknown() {
var xxx_messageInfo_Config_HostMapping proto.InternalMessageInfo var xxx_messageInfo_Config_HostMapping proto.InternalMessageInfo
func (m *Config_HostMapping) GetType() Config_HostMapping_Type { func (m *Config_HostMapping) GetType() DomainMatchingType {
if m != nil { if m != nil {
return m.Type return m.Type
} }
return Config_HostMapping_Full return DomainMatchingType_Full
} }
func (m *Config_HostMapping) GetDomain() string { func (m *Config_HostMapping) GetDomain() string {
@ -162,42 +267,51 @@ func (m *Config_HostMapping) GetIp() [][]byte {
} }
func init() { func init() {
proto.RegisterType((*NameServer)(nil), "v2ray.core.app.dns.NameServer")
proto.RegisterType((*NameServer_PriorityDomain)(nil), "v2ray.core.app.dns.NameServer.PriorityDomain")
proto.RegisterType((*Config)(nil), "v2ray.core.app.dns.Config") proto.RegisterType((*Config)(nil), "v2ray.core.app.dns.Config")
proto.RegisterMapType((map[string]*net.IPOrDomain)(nil), "v2ray.core.app.dns.Config.HostsEntry") proto.RegisterMapType((map[string]*net.IPOrDomain)(nil), "v2ray.core.app.dns.Config.HostsEntry")
proto.RegisterType((*Config_HostMapping)(nil), "v2ray.core.app.dns.Config.HostMapping") proto.RegisterType((*Config_HostMapping)(nil), "v2ray.core.app.dns.Config.HostMapping")
proto.RegisterEnum("v2ray.core.app.dns.Config_HostMapping_Type", Config_HostMapping_Type_name, Config_HostMapping_Type_value) proto.RegisterEnum("v2ray.core.app.dns.DomainMatchingType", DomainMatchingType_name, DomainMatchingType_value)
} }
func init() { func init() {
proto.RegisterFile("v2ray.com/core/app/dns/config.proto", fileDescriptor_config_b3d430ec01af18aa) proto.RegisterFile("v2ray.com/core/app/dns/config.proto", fileDescriptor_config_6f85f947d5116df4)
} }
var fileDescriptor_config_b3d430ec01af18aa = []byte{ var fileDescriptor_config_6f85f947d5116df4 = []byte{
// 416 bytes of a gzipped FileDescriptorProto // 516 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xdd, 0x6a, 0x14, 0x31, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0xd1, 0x6e, 0xd3, 0x3e,
0x14, 0xc7, 0xcd, 0xcc, 0x76, 0xe9, 0x9e, 0x59, 0xcb, 0x92, 0x8b, 0x32, 0xac, 0x17, 0x5d, 0x2b, 0x18, 0xc5, 0xff, 0x49, 0xda, 0x6e, 0xfd, 0xd2, 0x7f, 0x55, 0x7c, 0x31, 0x55, 0x45, 0x82, 0x32,
0xea, 0x40, 0x21, 0x03, 0xa3, 0xa0, 0x78, 0x53, 0xfa, 0x25, 0xee, 0x85, 0x5a, 0x52, 0xf1, 0x42, 0xc4, 0xa8, 0x40, 0x38, 0x52, 0x40, 0x02, 0x7a, 0x33, 0xb1, 0xad, 0x88, 0x0a, 0x0d, 0xaa, 0x0c,
0x2f, 0x4a, 0x3a, 0x89, 0x35, 0xb8, 0x73, 0x12, 0x92, 0xec, 0xc2, 0x3c, 0x89, 0xef, 0xe0, 0xab, 0x71, 0x01, 0x48, 0x95, 0x17, 0x9b, 0xce, 0xa2, 0xb1, 0x8d, 0xed, 0x16, 0x85, 0x37, 0x40, 0xbc,
0xf9, 0x12, 0xb2, 0x89, 0xe2, 0xa2, 0x16, 0x7b, 0x37, 0x1f, 0xff, 0xdf, 0xf9, 0xfd, 0x73, 0x08, 0x09, 0x4f, 0x89, 0x6a, 0x77, 0xb4, 0xb0, 0x0e, 0xb8, 0xe1, 0xae, 0x76, 0xcf, 0xef, 0x3b, 0x27,
0x3c, 0x58, 0x35, 0x4e, 0xf4, 0xac, 0x35, 0x5d, 0xdd, 0x1a, 0xa7, 0x6a, 0x61, 0x6d, 0x2d, 0xd1, 0xe7, 0x4b, 0xe0, 0xe6, 0x3c, 0xd5, 0xa4, 0xc4, 0xb9, 0x2c, 0x92, 0x5c, 0x6a, 0x96, 0x10, 0xa5,
0xd7, 0xad, 0xc1, 0x4f, 0xfa, 0x9a, 0x59, 0x67, 0x82, 0xa1, 0xf4, 0x57, 0xc8, 0x29, 0x26, 0xac, 0x12, 0x2a, 0x4c, 0x92, 0x4b, 0xf1, 0x9e, 0x4f, 0xb0, 0xd2, 0xd2, 0x4a, 0x84, 0xce, 0x45, 0x9a,
0x65, 0x12, 0xfd, 0xf4, 0xf1, 0x1f, 0x60, 0x6b, 0xba, 0xce, 0x60, 0x8d, 0x2a, 0xd4, 0x42, 0x4a, 0x61, 0xa2, 0x14, 0xa6, 0xc2, 0x74, 0x6e, 0xff, 0x02, 0xe6, 0xb2, 0x28, 0xa4, 0x48, 0x04, 0xb3,
0xa7, 0xbc, 0x4f, 0xf0, 0xf4, 0xe0, 0xe6, 0xa0, 0x54, 0x3e, 0x68, 0x14, 0x41, 0x1b, 0x4c, 0xe1, 0x09, 0xa1, 0x54, 0x33, 0x63, 0x3c, 0xdc, 0xb9, 0x7b, 0xb9, 0x90, 0x32, 0x63, 0xb9, 0x20, 0x96,
0xfd, 0xef, 0x39, 0x0c, 0x4f, 0xa2, 0x9a, 0x1e, 0x41, 0xf1, 0x46, 0x74, 0xea, 0x42, 0xb9, 0x95, 0x4b, 0xe1, 0xc5, 0xbb, 0x5f, 0x43, 0x80, 0x17, 0xa4, 0x60, 0x27, 0x4c, 0xcf, 0x99, 0x46, 0x8f,
0x72, 0xbe, 0x24, 0xb3, 0xbc, 0x2a, 0x9a, 0x3d, 0xb6, 0x51, 0x25, 0x4d, 0x62, 0xa8, 0x02, 0x3b, 0x61, 0x6b, 0x39, 0xac, 0x1d, 0x74, 0x83, 0x5e, 0x9c, 0x5e, 0xc7, 0x6b, 0x51, 0xfc, 0x24, 0x2c,
0x43, 0x69, 0x8d, 0xc6, 0xc0, 0x37, 0x19, 0x7a, 0x08, 0x5b, 0xaf, 0x8c, 0x0f, 0xbe, 0xcc, 0x22, 0x98, 0xc5, 0x03, 0x41, 0x95, 0xe4, 0xc2, 0x66, 0xe7, 0x7a, 0xf4, 0x0e, 0x90, 0xd2, 0x5c, 0x6a,
0xfc, 0x90, 0xfd, 0x7d, 0x0e, 0x96, 0x6c, 0x2c, 0xe6, 0xce, 0x30, 0xb8, 0xfe, 0x38, 0x2b, 0x09, 0x6e, 0xf9, 0x67, 0x46, 0xc7, 0x54, 0x16, 0x84, 0x8b, 0x76, 0xd8, 0x8d, 0x7a, 0x71, 0x7a, 0x0f,
0x4f, 0x1c, 0xbd, 0x07, 0xa3, 0x76, 0xa1, 0x15, 0x86, 0x4b, 0x6d, 0xcb, 0x7c, 0x46, 0xaa, 0x31, 0x5f, 0x7c, 0x20, 0xbc, 0xb2, 0xc5, 0x23, 0x0f, 0x96, 0x47, 0x0e, 0xca, 0xae, 0xac, 0x0d, 0xf2,
0xdf, 0x4e, 0x1f, 0xe6, 0x96, 0xce, 0x61, 0xec, 0x83, 0x08, 0xba, 0xbd, 0xfc, 0x1c, 0x25, 0x83, 0x57, 0x1d, 0x0a, 0xcd, 0x9f, 0x45, 0xa8, 0x0f, 0x15, 0x5b, 0x2a, 0xe6, 0x72, 0x36, 0xd3, 0xbd,
0x28, 0x79, 0xf4, 0x1f, 0xc9, 0x6b, 0x61, 0xad, 0xc6, 0x6b, 0x5e, 0x24, 0x36, 0x7a, 0xa6, 0x1f, 0x4d, 0x0e, 0x5e, 0x79, 0x4c, 0x6c, 0x7e, 0xc6, 0xc5, 0xe4, 0x55, 0xa9, 0x58, 0xe6, 0x18, 0xb4,
0x01, 0x7e, 0x17, 0xa0, 0x13, 0xc8, 0xbf, 0xa8, 0xbe, 0x24, 0x33, 0x52, 0x8d, 0xf8, 0xfa, 0x91, 0x03, 0xb5, 0x1f, 0xf9, 0x82, 0x5e, 0x3d, 0x5b, 0x9e, 0x76, 0xbf, 0x54, 0xa0, 0x76, 0xe8, 0x16,
0x3e, 0x83, 0xad, 0x95, 0x58, 0x2c, 0x55, 0x99, 0xcd, 0x48, 0x55, 0x34, 0xf7, 0x6f, 0xd8, 0xc2, 0x81, 0x06, 0x10, 0xaf, 0x02, 0x2e, 0xda, 0x88, 0xfe, 0xa2, 0x8d, 0x83, 0xb0, 0x1d, 0x64, 0xeb,
0xfc, 0xfc, 0xad, 0x3b, 0x35, 0x9d, 0xd0, 0xc8, 0x53, 0xfe, 0x45, 0xf6, 0x9c, 0x4c, 0xbf, 0x12, 0x1c, 0xda, 0x87, 0x58, 0x90, 0x82, 0x8d, 0x8d, 0x3b, 0xb7, 0xab, 0x6e, 0xcc, 0xb5, 0xdf, 0xd7,
0x28, 0x36, 0xcc, 0xf4, 0x10, 0x06, 0xa1, 0xb7, 0x2a, 0xce, 0xdf, 0x69, 0x0e, 0x6e, 0xd7, 0x97, 0x91, 0x81, 0x58, 0x6d, 0x64, 0x1f, 0xaa, 0xcf, 0xa4, 0xb1, 0x66, 0xd9, 0xe4, 0xad, 0x4d, 0xa8,
0xbd, 0xeb, 0xad, 0xe2, 0x11, 0xa4, 0xbb, 0x30, 0x94, 0xd1, 0x12, 0xeb, 0x8c, 0xf8, 0xcf, 0x37, 0x8f, 0x8c, 0x9d, 0x6e, 0x20, 0xac, 0x2e, 0x5d, 0x0e, 0xcf, 0xa1, 0xab, 0x50, 0xcf, 0xa7, 0x9c,
0xba, 0x03, 0x59, 0x5c, 0x53, 0x5e, 0x8d, 0x79, 0xa6, 0xed, 0xfe, 0x1e, 0x0c, 0xd6, 0x14, 0xdd, 0x09, 0x3b, 0xe6, 0xaa, 0x1d, 0x75, 0x83, 0x5e, 0x23, 0xdb, 0xf6, 0x17, 0x43, 0x85, 0x86, 0xd0,
0x86, 0xc1, 0xcb, 0xe5, 0x62, 0x31, 0xb9, 0x43, 0xef, 0xc2, 0xe8, 0x62, 0x79, 0x95, 0x2a, 0x4e, 0x30, 0x96, 0x58, 0x9e, 0x8f, 0xcf, 0x9c, 0x49, 0xc5, 0x99, 0xec, 0xfd, 0xc1, 0xe4, 0x98, 0x28,
0xc8, 0xf1, 0x53, 0xd8, 0x6d, 0x4d, 0xf7, 0x8f, 0x02, 0xe7, 0xe4, 0x43, 0x2e, 0xd1, 0x7f, 0xcb, 0xc5, 0xc5, 0x24, 0x8b, 0x3d, 0xeb, 0x7c, 0x3a, 0x6f, 0x01, 0x56, 0x01, 0x50, 0x0b, 0xa2, 0x0f,
0xe8, 0xfb, 0x86, 0x8b, 0x9e, 0x9d, 0xac, 0xff, 0x1d, 0x59, 0xcb, 0x4e, 0xd1, 0x5f, 0x0d, 0xe3, 0xac, 0x74, 0xcb, 0xa9, 0x67, 0x8b, 0x9f, 0xe8, 0x21, 0x54, 0xe7, 0x64, 0x3a, 0x63, 0xae, 0xf2,
0x55, 0x79, 0xf2, 0x23, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x30, 0x09, 0xcd, 0xbb, 0x02, 0x00, 0x00, 0x38, 0xbd, 0x71, 0x49, 0x95, 0xc3, 0xd1, 0x4b, 0xbd, 0x7c, 0x0d, 0xbc, 0xbe, 0x1f, 0x3e, 0x0a,
0x3a, 0x1f, 0x21, 0x5e, 0x33, 0xfe, 0x17, 0xbb, 0x47, 0x4d, 0x08, 0x5d, 0x41, 0x51, 0xaf, 0x91,
0x85, 0x5c, 0xdd, 0xe9, 0x03, 0xba, 0x38, 0x03, 0x6d, 0x43, 0xe5, 0xe9, 0x6c, 0x3a, 0x6d, 0xfd,
0x87, 0xfe, 0x87, 0xfa, 0xc9, 0xec, 0xd4, 0xc3, 0xad, 0x00, 0xc5, 0xb0, 0xf5, 0x9c, 0x95, 0x9f,
0xa4, 0xa6, 0xad, 0xf0, 0xe0, 0x01, 0xec, 0xe4, 0xb2, 0xd8, 0x10, 0x6b, 0x14, 0xbc, 0x89, 0xa8,
0x30, 0xdf, 0x42, 0xf4, 0x3a, 0xcd, 0x48, 0x89, 0x0f, 0x17, 0xff, 0x3d, 0x51, 0x0a, 0x1f, 0x09,
0x73, 0x5a, 0x73, 0x9f, 0xe4, 0xfd, 0xef, 0x01, 0x00, 0x00, 0xff, 0xff, 0x78, 0xfa, 0x21, 0x21,
0x23, 0x04, 0x00, 0x00,
} }

View File

@ -9,10 +9,30 @@ option java_multiple_files = true;
import "v2ray.com/core/common/net/address.proto"; import "v2ray.com/core/common/net/address.proto";
import "v2ray.com/core/common/net/destination.proto"; import "v2ray.com/core/common/net/destination.proto";
message NameServer {
v2ray.core.common.net.Endpoint address = 1;
message PriorityDomain {
DomainMatchingType type = 1;
string domain = 2;
}
repeated PriorityDomain prioritized_domain = 2;
}
enum DomainMatchingType {
Full = 0;
Subdomain = 1;
Keyword = 2;
}
message Config { message Config {
// Nameservers used by this DNS. Only traditional UDP servers are support at the moment. // Nameservers used by this DNS. Only traditional UDP servers are support at the moment.
// A special value 'localhost' as a domain address can be set to use DNS on local system. // A special value 'localhost' as a domain address can be set to use DNS on local system.
repeated v2ray.core.common.net.Endpoint NameServers = 1; repeated v2ray.core.common.net.Endpoint NameServers = 1 [deprecated = true];
// NameServer list used by this DNS client.
repeated NameServer name_server = 5;
// Static hosts. Domain to IP. // Static hosts. Domain to IP.
// Deprecated. Use static_hosts. // Deprecated. Use static_hosts.
@ -22,12 +42,7 @@ message Config {
bytes client_ip = 3; bytes client_ip = 3;
message HostMapping { message HostMapping {
enum Type { DomainMatchingType type = 1;
Full = 0;
SubDomain = 1;
}
Type type = 1;
string domain = 2; string domain = 2;
repeated bytes ip = 3; repeated bytes ip = 3;
} }

View File

@ -11,9 +11,22 @@ type StaticHosts struct {
matchers *strmatcher.MatcherGroup matchers *strmatcher.MatcherGroup
} }
var typeMap = map[Config_HostMapping_Type]strmatcher.Type{ var typeMap = map[DomainMatchingType]strmatcher.Type{
Config_HostMapping_Full: strmatcher.Full, DomainMatchingType_Full: strmatcher.Full,
Config_HostMapping_SubDomain: strmatcher.Domain, DomainMatchingType_Subdomain: strmatcher.Domain,
DomainMatchingType_Keyword: strmatcher.Substr,
}
func toStrMatcher(t DomainMatchingType, domain string) (strmatcher.Matcher, error) {
strMType, f := typeMap[t]
if !f {
return nil, newError("unknown mapping type", t).AtWarning()
}
matcher, err := strMType.New(domain)
if err != nil {
return nil, newError("failed to create str matcher").Base(err)
}
return matcher, nil
} }
func NewStaticHosts(hosts []*Config_HostMapping, legacy map[string]*net.IPOrDomain) (*StaticHosts, error) { func NewStaticHosts(hosts []*Config_HostMapping, legacy map[string]*net.IPOrDomain) (*StaticHosts, error) {
@ -39,11 +52,7 @@ func NewStaticHosts(hosts []*Config_HostMapping, legacy map[string]*net.IPOrDoma
} }
for _, mapping := range hosts { for _, mapping := range hosts {
strMType, f := typeMap[mapping.Type] matcher, err := toStrMatcher(mapping.Type, mapping.Domain)
if !f {
return nil, newError("unknown mapping type", mapping.Type).AtWarning()
}
matcher, err := strMType.New(mapping.Domain)
if err != nil { if err != nil {
return nil, newError("failed to create domain matcher").Base(err) return nil, newError("failed to create domain matcher").Base(err)
} }

View File

@ -12,14 +12,14 @@ func TestStaticHosts(t *testing.T) {
pb := []*Config_HostMapping{ pb := []*Config_HostMapping{
{ {
Type: Config_HostMapping_Full, Type: DomainMatchingType_Full,
Domain: "v2ray.com", Domain: "v2ray.com",
Ip: [][]byte{ Ip: [][]byte{
{1, 1, 1, 1}, {1, 1, 1, 1},
}, },
}, },
{ {
Type: Config_HostMapping_SubDomain, Type: DomainMatchingType_Subdomain,
Domain: "v2ray.cn", Domain: "v2ray.cn",
Ip: [][]byte{ Ip: [][]byte{
{2, 2, 2, 2}, {2, 2, 2, 2},

View File

@ -6,7 +6,7 @@ import (
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
) )
type NameServer interface { type NameServerInterface interface {
QueryIP(ctx context.Context, domain string) ([]net.IP, error) QueryIP(ctx context.Context, domain string) ([]net.IP, error)
} }

View File

@ -10,18 +10,21 @@ import (
"v2ray.com/core" "v2ray.com/core"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/strmatcher"
) )
type Server struct { type Server struct {
sync.Mutex sync.Mutex
hosts *StaticHosts hosts *StaticHosts
servers []NameServer servers []NameServerInterface
clientIP net.IP clientIP net.IP
domainMatcher strmatcher.IndexMatcher
domainIndexMap map[uint32]uint32
} }
func New(ctx context.Context, config *Config) (*Server, error) { func New(ctx context.Context, config *Config) (*Server, error) {
server := &Server{ server := &Server{
servers: make([]NameServer, len(config.NameServers)), servers: make([]NameServerInterface, 0, len(config.NameServers)+len(config.NameServer)),
} }
if len(config.ClientIp) > 0 { if len(config.ClientIp) > 0 {
if len(config.ClientIp) != 4 && len(config.ClientIp) != 16 { if len(config.ClientIp) != 4 && len(config.ClientIp) != 16 {
@ -41,20 +44,52 @@ func New(ctx context.Context, config *Config) (*Server, error) {
return nil, newError("unable to register DNSClient.").Base(err) return nil, newError("unable to register DNSClient.").Base(err)
} }
for idx, destPB := range config.NameServers { addNameServer := func(endpoint *net.Endpoint) int {
address := destPB.Address.AsAddress() address := endpoint.Address.AsAddress()
if address.Family().IsDomain() && address.Domain() == "localhost" { if address.Family().IsDomain() && address.Domain() == "localhost" {
server.servers[idx] = NewLocalNameServer() server.servers = append(server.servers, NewLocalNameServer())
} else { } else {
dest := destPB.AsDestination() dest := endpoint.AsDestination()
if dest.Network == net.Network_Unknown { if dest.Network == net.Network_Unknown {
dest.Network = net.Network_UDP dest.Network = net.Network_UDP
} }
if dest.Network == net.Network_UDP { if dest.Network == net.Network_UDP {
server.servers[idx] = NewClassicNameServer(dest, v.Dispatcher(), server.clientIP) server.servers = append(server.servers, NewClassicNameServer(dest, v.Dispatcher(), server.clientIP))
} }
} }
return len(server.servers) - 1
} }
for _, destPB := range config.NameServers {
addNameServer(destPB)
}
if len(config.NameServer) > 0 {
domainMatcher := &strmatcher.MatcherGroup{}
domainIndexMap := make(map[uint32]uint32)
for _, ns := range config.NameServer {
idx := addNameServer(ns.Address)
for _, domain := range ns.PrioritizedDomain {
matcher, err := toStrMatcher(domain.Type, domain.Domain)
if err != nil {
return nil, newError("failed to create proritized domain").Base(err).AtWarning()
}
midx := domainMatcher.Add(matcher)
domainIndexMap[midx] = uint32(idx)
}
}
if domainMatcher.Size() > 64 {
server.domainMatcher = strmatcher.NewCachedMatcherGroup(domainMatcher)
} else {
server.domainMatcher = domainMatcher
}
server.domainIndexMap = domainIndexMap
}
if len(config.NameServers) == 0 { if len(config.NameServers) == 0 {
server.servers = append(server.servers, NewLocalNameServer()) server.servers = append(server.servers, NewLocalNameServer())
} }
@ -72,22 +107,41 @@ func (s *Server) Close() error {
return nil return nil
} }
func (s *Server) queryIPTimeout(server NameServerInterface, domain string) ([]net.IP, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*4)
ips, err := server.QueryIP(ctx, domain)
cancel()
return ips, err
}
func (s *Server) LookupIP(domain string) ([]net.IP, error) { func (s *Server) LookupIP(domain string) ([]net.IP, error) {
if ip := s.hosts.LookupIP(domain); len(ip) > 0 { if ip := s.hosts.LookupIP(domain); len(ip) > 0 {
return ip, nil return ip, nil
} }
var lastErr error var lastErr error
for _, server := range s.servers { if s.domainMatcher != nil {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*4) idx := s.domainMatcher.Match(domain)
ips, err := server.QueryIP(ctx, domain) if idx > 0 {
cancel() ns := s.servers[idx]
if err != nil { ips, err := s.queryIPTimeout(ns, domain)
lastErr = err if len(ips) > 0 {
return ips, nil
}
if err != nil {
lastErr = err
}
} }
}
for _, server := range s.servers {
ips, err := s.queryIPTimeout(server, domain)
if len(ips) > 0 { if len(ips) > 0 {
return ips, nil return ips, nil
} }
if err != nil {
lastErr = err
}
} }
return nil, newError("returning nil for domain ", domain).Base(lastErr) return nil, newError("returning nil for domain ", domain).Base(lastErr)

View File

@ -2,6 +2,7 @@ package dns_test
import ( import (
"testing" "testing"
"time"
"v2ray.com/core" "v2ray.com/core"
"v2ray.com/core/app/dispatcher" "v2ray.com/core/app/dispatcher"
@ -98,3 +99,79 @@ func TestUDPServer(t *testing.T) {
assert(len(ips), Equals, 1) assert(len(ips), Equals, 1)
assert([]byte(ips[0]), Equals, []byte{8, 8, 8, 8}) assert([]byte(ips[0]), Equals, []byte{8, 8, 8, 8})
} }
func TestPrioritizedDomain(t *testing.T) {
assert := With(t)
port := udp.PickPort()
dnsServer := dns.Server{
Addr: "127.0.0.1:" + port.String(),
Net: "udp",
Handler: &staticHandler{},
UDPSize: 1200,
}
go dnsServer.ListenAndServe()
config := &core.Config{
App: []*serial.TypedMessage{
serial.ToTypedMessage(&Config{
NameServers: []*net.Endpoint{
{
Network: net.Network_UDP,
Address: &net.IPOrDomain{
Address: &net.IPOrDomain_Ip{
Ip: []byte{127, 0, 0, 1},
},
},
Port: 9999, /* unreachable */
},
},
NameServer: []*NameServer{
{
Address: &net.Endpoint{
Network: net.Network_UDP,
Address: &net.IPOrDomain{
Address: &net.IPOrDomain_Ip{
Ip: []byte{127, 0, 0, 1},
},
},
Port: uint32(port),
},
PrioritizedDomain: []*NameServer_PriorityDomain{
{
Type: DomainMatchingType_Full,
Domain: "google.com",
},
},
},
},
}),
serial.ToTypedMessage(&dispatcher.Config{}),
serial.ToTypedMessage(&proxyman.OutboundConfig{}),
serial.ToTypedMessage(&policy.Config{}),
},
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
},
}
v, err := core.New(config)
assert(err, IsNil)
client := v.DNSClient()
startTime := time.Now()
ips, err := client.LookupIP("google.com")
assert(err, IsNil)
assert(len(ips), Equals, 1)
assert([]byte(ips[0]), Equals, []byte{8, 8, 8, 8})
endTime := time.Now()
if startTime.After(endTime.Add(time.Second * 2)) {
t.Error("DNS query doesn't finish in 2 seconds.")
}
}