1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-22 01:57:12 -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.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Config_HostMapping_Type int32
type DomainMatchingType int32
const (
Config_HostMapping_Full Config_HostMapping_Type = 0
Config_HostMapping_SubDomain Config_HostMapping_Type = 1
DomainMatchingType_Full DomainMatchingType = 0
DomainMatchingType_Subdomain DomainMatchingType = 1
DomainMatchingType_Keyword DomainMatchingType = 2
)
var Config_HostMapping_Type_name = map[int32]string{
var DomainMatchingType_name = map[int32]string{
0: "Full",
1: "SubDomain",
1: "Subdomain",
2: "Keyword",
}
var Config_HostMapping_Type_value = map[string]int32{
var DomainMatchingType_value = map[string]int32{
"Full": 0,
"SubDomain": 1,
"Subdomain": 1,
"Keyword": 2,
}
func (x Config_HostMapping_Type) String() string {
return proto.EnumName(Config_HostMapping_Type_name, int32(x))
func (x DomainMatchingType) String() string {
return proto.EnumName(DomainMatchingType_name, int32(x))
}
func (Config_HostMapping_Type) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_config_b3d430ec01af18aa, []int{0, 1, 0}
func (DomainMatchingType) EnumDescriptor() ([]byte, []int) {
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 {
// 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.
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.
// 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.
@ -58,7 +155,7 @@ func (m *Config) Reset() { *m = Config{} }
func (m *Config) String() string { return proto.CompactTextString(m) }
func (*Config) ProtoMessage() {}
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 {
return xxx_messageInfo_Config.Unmarshal(m, b)
@ -78,6 +175,7 @@ func (m *Config) XXX_DiscardUnknown() {
var xxx_messageInfo_Config proto.InternalMessageInfo
// Deprecated: Do not use.
func (m *Config) GetNameServers() []*net.Endpoint {
if m != nil {
return m.NameServers
@ -85,6 +183,13 @@ func (m *Config) GetNameServers() []*net.Endpoint {
return nil
}
func (m *Config) GetNameServer() []*NameServer {
if m != nil {
return m.NameServer
}
return nil
}
// Deprecated: Do not use.
func (m *Config) GetHosts() map[string]*net.IPOrDomain {
if m != nil {
@ -108,19 +213,19 @@ func (m *Config) GetStaticHosts() []*Config_HostMapping {
}
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"`
Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"`
Ip [][]byte `protobuf:"bytes,3,rep,name=ip,proto3" json:"ip,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
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"`
Ip [][]byte `protobuf:"bytes,3,rep,name=ip,proto3" json:"ip,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Config_HostMapping) Reset() { *m = Config_HostMapping{} }
func (m *Config_HostMapping) String() string { return proto.CompactTextString(m) }
func (*Config_HostMapping) ProtoMessage() {}
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 {
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
func (m *Config_HostMapping) GetType() Config_HostMapping_Type {
func (m *Config_HostMapping) GetType() DomainMatchingType {
if m != nil {
return m.Type
}
return Config_HostMapping_Full
return DomainMatchingType_Full
}
func (m *Config_HostMapping) GetDomain() string {
@ -162,42 +267,51 @@ func (m *Config_HostMapping) GetIp() [][]byte {
}
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.RegisterMapType((map[string]*net.IPOrDomain)(nil), "v2ray.core.app.dns.Config.HostsEntry")
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() {
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{
// 416 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xdd, 0x6a, 0x14, 0x31,
0x14, 0xc7, 0xcd, 0xcc, 0x76, 0xe9, 0x9e, 0x59, 0xcb, 0x92, 0x8b, 0x32, 0xac, 0x17, 0x5d, 0x2b,
0xea, 0x40, 0x21, 0x03, 0xa3, 0xa0, 0x78, 0x53, 0xfa, 0x25, 0xee, 0x85, 0x5a, 0x52, 0xf1, 0x42,
0x2f, 0x4a, 0x3a, 0x89, 0x35, 0xb8, 0x73, 0x12, 0x92, 0xec, 0xc2, 0x3c, 0x89, 0xef, 0xe0, 0xab,
0xf9, 0x12, 0xb2, 0x89, 0xe2, 0xa2, 0x16, 0x7b, 0x37, 0x1f, 0xff, 0xdf, 0xf9, 0xfd, 0x73, 0x08,
0x3c, 0x58, 0x35, 0x4e, 0xf4, 0xac, 0x35, 0x5d, 0xdd, 0x1a, 0xa7, 0x6a, 0x61, 0x6d, 0x2d, 0xd1,
0xd7, 0xad, 0xc1, 0x4f, 0xfa, 0x9a, 0x59, 0x67, 0x82, 0xa1, 0xf4, 0x57, 0xc8, 0x29, 0x26, 0xac,
0x65, 0x12, 0xfd, 0xf4, 0xf1, 0x1f, 0x60, 0x6b, 0xba, 0xce, 0x60, 0x8d, 0x2a, 0xd4, 0x42, 0x4a,
0xa7, 0xbc, 0x4f, 0xf0, 0xf4, 0xe0, 0xe6, 0xa0, 0x54, 0x3e, 0x68, 0x14, 0x41, 0x1b, 0x4c, 0xe1,
0xfd, 0xef, 0x39, 0x0c, 0x4f, 0xa2, 0x9a, 0x1e, 0x41, 0xf1, 0x46, 0x74, 0xea, 0x42, 0xb9, 0x95,
0x72, 0xbe, 0x24, 0xb3, 0xbc, 0x2a, 0x9a, 0x3d, 0xb6, 0x51, 0x25, 0x4d, 0x62, 0xa8, 0x02, 0x3b,
0x43, 0x69, 0x8d, 0xc6, 0xc0, 0x37, 0x19, 0x7a, 0x08, 0x5b, 0xaf, 0x8c, 0x0f, 0xbe, 0xcc, 0x22,
0xfc, 0x90, 0xfd, 0x7d, 0x0e, 0x96, 0x6c, 0x2c, 0xe6, 0xce, 0x30, 0xb8, 0xfe, 0x38, 0x2b, 0x09,
0x4f, 0x1c, 0xbd, 0x07, 0xa3, 0x76, 0xa1, 0x15, 0x86, 0x4b, 0x6d, 0xcb, 0x7c, 0x46, 0xaa, 0x31,
0xdf, 0x4e, 0x1f, 0xe6, 0x96, 0xce, 0x61, 0xec, 0x83, 0x08, 0xba, 0xbd, 0xfc, 0x1c, 0x25, 0x83,
0x28, 0x79, 0xf4, 0x1f, 0xc9, 0x6b, 0x61, 0xad, 0xc6, 0x6b, 0x5e, 0x24, 0x36, 0x7a, 0xa6, 0x1f,
0x01, 0x7e, 0x17, 0xa0, 0x13, 0xc8, 0xbf, 0xa8, 0xbe, 0x24, 0x33, 0x52, 0x8d, 0xf8, 0xfa, 0x91,
0x3e, 0x83, 0xad, 0x95, 0x58, 0x2c, 0x55, 0x99, 0xcd, 0x48, 0x55, 0x34, 0xf7, 0x6f, 0xd8, 0xc2,
0xfc, 0xfc, 0xad, 0x3b, 0x35, 0x9d, 0xd0, 0xc8, 0x53, 0xfe, 0x45, 0xf6, 0x9c, 0x4c, 0xbf, 0x12,
0x28, 0x36, 0xcc, 0xf4, 0x10, 0x06, 0xa1, 0xb7, 0x2a, 0xce, 0xdf, 0x69, 0x0e, 0x6e, 0xd7, 0x97,
0xbd, 0xeb, 0xad, 0xe2, 0x11, 0xa4, 0xbb, 0x30, 0x94, 0xd1, 0x12, 0xeb, 0x8c, 0xf8, 0xcf, 0x37,
0xba, 0x03, 0x59, 0x5c, 0x53, 0x5e, 0x8d, 0x79, 0xa6, 0xed, 0xfe, 0x1e, 0x0c, 0xd6, 0x14, 0xdd,
0x86, 0xc1, 0xcb, 0xe5, 0x62, 0x31, 0xb9, 0x43, 0xef, 0xc2, 0xe8, 0x62, 0x79, 0x95, 0x2a, 0x4e,
0xc8, 0xf1, 0x53, 0xd8, 0x6d, 0x4d, 0xf7, 0x8f, 0x02, 0xe7, 0xe4, 0x43, 0x2e, 0xd1, 0x7f, 0xcb,
0xe8, 0xfb, 0x86, 0x8b, 0x9e, 0x9d, 0xac, 0xff, 0x1d, 0x59, 0xcb, 0x4e, 0xd1, 0x5f, 0x0d, 0xe3,
0x55, 0x79, 0xf2, 0x23, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x30, 0x09, 0xcd, 0xbb, 0x02, 0x00, 0x00,
var fileDescriptor_config_6f85f947d5116df4 = []byte{
// 516 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0xd1, 0x6e, 0xd3, 0x3e,
0x18, 0xc5, 0xff, 0x49, 0xda, 0x6e, 0xfd, 0xd2, 0x7f, 0x55, 0x7c, 0x31, 0x55, 0x45, 0x82, 0x32,
0xc4, 0xa8, 0x40, 0x38, 0x52, 0x40, 0x02, 0x7a, 0x33, 0xb1, 0xad, 0x88, 0x0a, 0x0d, 0xaa, 0x0c,
0x71, 0x01, 0x48, 0x95, 0x17, 0x9b, 0xce, 0xa2, 0xb1, 0x8d, 0xed, 0x16, 0x85, 0x37, 0x40, 0xbc,
0x09, 0x4f, 0x89, 0x6a, 0x77, 0xb4, 0xb0, 0x0e, 0xb8, 0xe1, 0xae, 0x76, 0xcf, 0xef, 0x3b, 0x27,
0xe7, 0x4b, 0xe0, 0xe6, 0x3c, 0xd5, 0xa4, 0xc4, 0xb9, 0x2c, 0x92, 0x5c, 0x6a, 0x96, 0x10, 0xa5,
0x12, 0x2a, 0x4c, 0x92, 0x4b, 0xf1, 0x9e, 0x4f, 0xb0, 0xd2, 0xd2, 0x4a, 0x84, 0xce, 0x45, 0x9a,
0x61, 0xa2, 0x14, 0xa6, 0xc2, 0x74, 0x6e, 0xff, 0x02, 0xe6, 0xb2, 0x28, 0xa4, 0x48, 0x04, 0xb3,
0x09, 0xa1, 0x54, 0x33, 0x63, 0x3c, 0xdc, 0xb9, 0x7b, 0xb9, 0x90, 0x32, 0x63, 0xb9, 0x20, 0x96,
0x4b, 0xe1, 0xc5, 0xbb, 0x5f, 0x43, 0x80, 0x17, 0xa4, 0x60, 0x27, 0x4c, 0xcf, 0x99, 0x46, 0x8f,
0x61, 0x6b, 0x39, 0xac, 0x1d, 0x74, 0x83, 0x5e, 0x9c, 0x5e, 0xc7, 0x6b, 0x51, 0xfc, 0x24, 0x2c,
0x98, 0xc5, 0x03, 0x41, 0x95, 0xe4, 0xc2, 0x66, 0xe7, 0x7a, 0xf4, 0x0e, 0x90, 0xd2, 0x5c, 0x6a,
0x6e, 0xf9, 0x67, 0x46, 0xc7, 0x54, 0x16, 0x84, 0x8b, 0x76, 0xd8, 0x8d, 0x7a, 0x71, 0x7a, 0x0f,
0x5f, 0x7c, 0x20, 0xbc, 0xb2, 0xc5, 0x23, 0x0f, 0x96, 0x47, 0x0e, 0xca, 0xae, 0xac, 0x0d, 0xf2,
0x57, 0x1d, 0x0a, 0xcd, 0x9f, 0x45, 0xa8, 0x0f, 0x15, 0x5b, 0x2a, 0xe6, 0x72, 0x36, 0xd3, 0xbd,
0x4d, 0x0e, 0x5e, 0x79, 0x4c, 0x6c, 0x7e, 0xc6, 0xc5, 0xe4, 0x55, 0xa9, 0x58, 0xe6, 0x18, 0xb4,
0x03, 0xb5, 0x1f, 0xf9, 0x82, 0x5e, 0x3d, 0x5b, 0x9e, 0x76, 0xbf, 0x54, 0xa0, 0x76, 0xe8, 0x16,
0x81, 0x06, 0x10, 0xaf, 0x02, 0x2e, 0xda, 0x88, 0xfe, 0xa2, 0x8d, 0x83, 0xb0, 0x1d, 0x64, 0xeb,
0x1c, 0xda, 0x87, 0x58, 0x90, 0x82, 0x8d, 0x8d, 0x3b, 0xb7, 0xab, 0x6e, 0xcc, 0xb5, 0xdf, 0xd7,
0x91, 0x81, 0x58, 0x6d, 0x64, 0x1f, 0xaa, 0xcf, 0xa4, 0xb1, 0x66, 0xd9, 0xe4, 0xad, 0x4d, 0xa8,
0x8f, 0x8c, 0x9d, 0x6e, 0x20, 0xac, 0x2e, 0x5d, 0x0e, 0xcf, 0xa1, 0xab, 0x50, 0xcf, 0xa7, 0x9c,
0x09, 0x3b, 0xe6, 0xaa, 0x1d, 0x75, 0x83, 0x5e, 0x23, 0xdb, 0xf6, 0x17, 0x43, 0x85, 0x86, 0xd0,
0x30, 0x96, 0x58, 0x9e, 0x8f, 0xcf, 0x9c, 0x49, 0xc5, 0x99, 0xec, 0xfd, 0xc1, 0xe4, 0x98, 0x28,
0xc5, 0xc5, 0x24, 0x8b, 0x3d, 0xeb, 0x7c, 0x3a, 0x6f, 0x01, 0x56, 0x01, 0x50, 0x0b, 0xa2, 0x0f,
0xac, 0x74, 0xcb, 0xa9, 0x67, 0x8b, 0x9f, 0xe8, 0x21, 0x54, 0xe7, 0x64, 0x3a, 0x63, 0xae, 0xf2,
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/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 {
// 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.
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.
// Deprecated. Use static_hosts.
@ -22,12 +42,7 @@ message Config {
bytes client_ip = 3;
message HostMapping {
enum Type {
Full = 0;
SubDomain = 1;
}
Type type = 1;
DomainMatchingType type = 1;
string domain = 2;
repeated bytes ip = 3;
}

View File

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

View File

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

View File

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

View File

@ -10,18 +10,21 @@ import (
"v2ray.com/core"
"v2ray.com/core/common"
"v2ray.com/core/common/net"
"v2ray.com/core/common/strmatcher"
)
type Server struct {
sync.Mutex
hosts *StaticHosts
servers []NameServer
clientIP net.IP
hosts *StaticHosts
servers []NameServerInterface
clientIP net.IP
domainMatcher strmatcher.IndexMatcher
domainIndexMap map[uint32]uint32
}
func New(ctx context.Context, config *Config) (*Server, error) {
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) != 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)
}
for idx, destPB := range config.NameServers {
address := destPB.Address.AsAddress()
addNameServer := func(endpoint *net.Endpoint) int {
address := endpoint.Address.AsAddress()
if address.Family().IsDomain() && address.Domain() == "localhost" {
server.servers[idx] = NewLocalNameServer()
server.servers = append(server.servers, NewLocalNameServer())
} else {
dest := destPB.AsDestination()
dest := endpoint.AsDestination()
if dest.Network == net.Network_Unknown {
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 {
server.servers = append(server.servers, NewLocalNameServer())
}
@ -72,22 +107,41 @@ func (s *Server) Close() error {
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) {
if ip := s.hosts.LookupIP(domain); len(ip) > 0 {
return ip, nil
}
var lastErr error
for _, server := range s.servers {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*4)
ips, err := server.QueryIP(ctx, domain)
cancel()
if err != nil {
lastErr = err
if s.domainMatcher != nil {
idx := s.domainMatcher.Match(domain)
if idx > 0 {
ns := s.servers[idx]
ips, err := s.queryIPTimeout(ns, domain)
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 {
return ips, nil
}
if err != nil {
lastErr = err
}
}
return nil, newError("returning nil for domain ", domain).Base(lastErr)

View File

@ -2,6 +2,7 @@ package dns_test
import (
"testing"
"time"
"v2ray.com/core"
"v2ray.com/core/app/dispatcher"
@ -98,3 +99,79 @@ func TestUDPServer(t *testing.T) {
assert(len(ips), Equals, 1)
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.")
}
}