mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-11-15 01:09:20 +02:00
feat: add queryStrategy option for DNS
This commit is contained in:
parent
41d3f31447
commit
8382b29922
|
@ -79,6 +79,55 @@ func (DomainMatchingType) EnumDescriptor() ([]byte, []int) {
|
||||||
return file_app_dns_config_proto_rawDescGZIP(), []int{0}
|
return file_app_dns_config_proto_rawDescGZIP(), []int{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type QueryStrategy int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
QueryStrategy_USE_IP QueryStrategy = 0
|
||||||
|
QueryStrategy_USE_IP4 QueryStrategy = 1
|
||||||
|
QueryStrategy_USE_IP6 QueryStrategy = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// Enum value maps for QueryStrategy.
|
||||||
|
var (
|
||||||
|
QueryStrategy_name = map[int32]string{
|
||||||
|
0: "USE_IP",
|
||||||
|
1: "USE_IP4",
|
||||||
|
2: "USE_IP6",
|
||||||
|
}
|
||||||
|
QueryStrategy_value = map[string]int32{
|
||||||
|
"USE_IP": 0,
|
||||||
|
"USE_IP4": 1,
|
||||||
|
"USE_IP6": 2,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (x QueryStrategy) Enum() *QueryStrategy {
|
||||||
|
p := new(QueryStrategy)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x QueryStrategy) String() string {
|
||||||
|
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (QueryStrategy) Descriptor() protoreflect.EnumDescriptor {
|
||||||
|
return file_app_dns_config_proto_enumTypes[1].Descriptor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (QueryStrategy) Type() protoreflect.EnumType {
|
||||||
|
return &file_app_dns_config_proto_enumTypes[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x QueryStrategy) Number() protoreflect.EnumNumber {
|
||||||
|
return protoreflect.EnumNumber(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use QueryStrategy.Descriptor instead.
|
||||||
|
func (QueryStrategy) EnumDescriptor() ([]byte, []int) {
|
||||||
|
return file_app_dns_config_proto_rawDescGZIP(), []int{1}
|
||||||
|
}
|
||||||
|
|
||||||
type NameServer struct {
|
type NameServer struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
|
@ -183,7 +232,8 @@ type Config struct {
|
||||||
// Tag is the inbound tag of DNS client.
|
// Tag is the inbound tag of DNS client.
|
||||||
Tag string `protobuf:"bytes,6,opt,name=tag,proto3" json:"tag,omitempty"`
|
Tag string `protobuf:"bytes,6,opt,name=tag,proto3" json:"tag,omitempty"`
|
||||||
// DisableCache Disable DNS cache
|
// DisableCache Disable DNS cache
|
||||||
DisableCache bool `protobuf:"varint,8,opt,name=disableCache,proto3" json:"disableCache,omitempty"`
|
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=xray.app.dns.QueryStrategy" json:"query_strategy,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Config) Reset() {
|
func (x *Config) Reset() {
|
||||||
|
@ -269,6 +319,13 @@ func (x *Config) GetDisableCache() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *Config) GetQueryStrategy() QueryStrategy {
|
||||||
|
if x != nil {
|
||||||
|
return x.QueryStrategy
|
||||||
|
}
|
||||||
|
return QueryStrategy_USE_IP
|
||||||
|
}
|
||||||
|
|
||||||
type NameServer_PriorityDomain struct {
|
type NameServer_PriorityDomain struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
|
@ -492,7 +549,7 @@ var file_app_dns_config_proto_rawDesc = []byte{
|
||||||
0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x75,
|
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,
|
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,
|
0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69,
|
||||||
0x7a, 0x65, 0x22, 0xc9, 0x04, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3f, 0x0a,
|
0x7a, 0x65, 0x22, 0x8d, 0x05, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3f, 0x0a,
|
||||||
0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03,
|
0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03,
|
||||||
0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
|
0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
|
||||||
0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x02, 0x18,
|
0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x02, 0x18,
|
||||||
|
@ -513,32 +570,39 @@ var file_app_dns_config_proto_rawDesc = []byte{
|
||||||
0x63, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20,
|
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,
|
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,
|
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, 0x1a, 0x55, 0x0a, 0x0a,
|
0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x42, 0x0a, 0x0e,
|
||||||
0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
|
0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x09,
|
||||||
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05,
|
0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e,
|
||||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x78, 0x72,
|
0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
|
||||||
0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50,
|
0x79, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79,
|
||||||
0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
|
0x1a, 0x55, 0x0a, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
|
||||||
0x02, 0x38, 0x01, 0x1a, 0x92, 0x01, 0x0a, 0x0b, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70,
|
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
|
||||||
0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
|
0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||||
0x0e, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73,
|
0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65,
|
||||||
0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54,
|
0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x05, 0x76, 0x61,
|
||||||
0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d,
|
0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x92, 0x01, 0x0a, 0x0b, 0x48, 0x6f, 0x73, 0x74,
|
||||||
0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69,
|
0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18,
|
||||||
0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x02, 0x69,
|
0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70,
|
||||||
0x70, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d,
|
0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68,
|
||||||
0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x69,
|
0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a,
|
||||||
0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x2a, 0x45,
|
0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64,
|
||||||
0x0a, 0x12, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67,
|
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28,
|
||||||
0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x0d,
|
0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64,
|
||||||
0x0a, 0x09, 0x53, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x01, 0x12, 0x0b, 0x0a,
|
0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70,
|
||||||
0x07, 0x4b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65,
|
0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x04, 0x08, 0x07,
|
||||||
0x67, 0x65, 0x78, 0x10, 0x03, 0x42, 0x46, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61,
|
0x10, 0x08, 0x2a, 0x45, 0x0a, 0x12, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63,
|
||||||
0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x50, 0x01, 0x5a, 0x21, 0x67, 0x69, 0x74,
|
0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c,
|
||||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61,
|
0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10,
|
||||||
0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x6e, 0x73, 0xaa, 0x02,
|
0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x10, 0x02, 0x12, 0x09,
|
||||||
0x0c, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44, 0x6e, 0x73, 0x62, 0x06, 0x70,
|
0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x10, 0x03, 0x2a, 0x35, 0x0a, 0x0d, 0x51, 0x75, 0x65,
|
||||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x53,
|
||||||
|
0x45, 0x5f, 0x49, 0x50, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50,
|
||||||
|
0x34, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x10, 0x02,
|
||||||
|
0x42, 0x46, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70,
|
||||||
|
0x2e, 0x64, 0x6e, 0x73, 0x50, 0x01, 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
||||||
|
0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72,
|
||||||
|
0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x6e, 0x73, 0xaa, 0x02, 0x0c, 0x58, 0x72, 0x61, 0x79,
|
||||||
|
0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -553,37 +617,39 @@ func file_app_dns_config_proto_rawDescGZIP() []byte {
|
||||||
return file_app_dns_config_proto_rawDescData
|
return file_app_dns_config_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_app_dns_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
var file_app_dns_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
|
||||||
var file_app_dns_config_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
var file_app_dns_config_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||||
var file_app_dns_config_proto_goTypes = []interface{}{
|
var file_app_dns_config_proto_goTypes = []interface{}{
|
||||||
(DomainMatchingType)(0), // 0: xray.app.dns.DomainMatchingType
|
(DomainMatchingType)(0), // 0: xray.app.dns.DomainMatchingType
|
||||||
(*NameServer)(nil), // 1: xray.app.dns.NameServer
|
(QueryStrategy)(0), // 1: xray.app.dns.QueryStrategy
|
||||||
(*Config)(nil), // 2: xray.app.dns.Config
|
(*NameServer)(nil), // 2: xray.app.dns.NameServer
|
||||||
(*NameServer_PriorityDomain)(nil), // 3: xray.app.dns.NameServer.PriorityDomain
|
(*Config)(nil), // 3: xray.app.dns.Config
|
||||||
(*NameServer_OriginalRule)(nil), // 4: xray.app.dns.NameServer.OriginalRule
|
(*NameServer_PriorityDomain)(nil), // 4: xray.app.dns.NameServer.PriorityDomain
|
||||||
nil, // 5: xray.app.dns.Config.HostsEntry
|
(*NameServer_OriginalRule)(nil), // 5: xray.app.dns.NameServer.OriginalRule
|
||||||
(*Config_HostMapping)(nil), // 6: xray.app.dns.Config.HostMapping
|
nil, // 6: xray.app.dns.Config.HostsEntry
|
||||||
(*net.Endpoint)(nil), // 7: xray.common.net.Endpoint
|
(*Config_HostMapping)(nil), // 7: xray.app.dns.Config.HostMapping
|
||||||
(*router.GeoIP)(nil), // 8: xray.app.router.GeoIP
|
(*net.Endpoint)(nil), // 8: xray.common.net.Endpoint
|
||||||
(*net.IPOrDomain)(nil), // 9: xray.common.net.IPOrDomain
|
(*router.GeoIP)(nil), // 9: xray.app.router.GeoIP
|
||||||
|
(*net.IPOrDomain)(nil), // 10: xray.common.net.IPOrDomain
|
||||||
}
|
}
|
||||||
var file_app_dns_config_proto_depIdxs = []int32{
|
var file_app_dns_config_proto_depIdxs = []int32{
|
||||||
7, // 0: xray.app.dns.NameServer.address:type_name -> xray.common.net.Endpoint
|
8, // 0: xray.app.dns.NameServer.address:type_name -> xray.common.net.Endpoint
|
||||||
3, // 1: xray.app.dns.NameServer.prioritized_domain:type_name -> xray.app.dns.NameServer.PriorityDomain
|
4, // 1: xray.app.dns.NameServer.prioritized_domain:type_name -> xray.app.dns.NameServer.PriorityDomain
|
||||||
8, // 2: xray.app.dns.NameServer.geoip:type_name -> xray.app.router.GeoIP
|
9, // 2: xray.app.dns.NameServer.geoip:type_name -> xray.app.router.GeoIP
|
||||||
4, // 3: xray.app.dns.NameServer.original_rules:type_name -> xray.app.dns.NameServer.OriginalRule
|
5, // 3: xray.app.dns.NameServer.original_rules:type_name -> xray.app.dns.NameServer.OriginalRule
|
||||||
7, // 4: xray.app.dns.Config.NameServers:type_name -> xray.common.net.Endpoint
|
8, // 4: xray.app.dns.Config.NameServers:type_name -> xray.common.net.Endpoint
|
||||||
1, // 5: xray.app.dns.Config.name_server:type_name -> xray.app.dns.NameServer
|
2, // 5: xray.app.dns.Config.name_server:type_name -> xray.app.dns.NameServer
|
||||||
5, // 6: xray.app.dns.Config.Hosts:type_name -> xray.app.dns.Config.HostsEntry
|
6, // 6: xray.app.dns.Config.Hosts:type_name -> xray.app.dns.Config.HostsEntry
|
||||||
6, // 7: xray.app.dns.Config.static_hosts:type_name -> xray.app.dns.Config.HostMapping
|
7, // 7: xray.app.dns.Config.static_hosts:type_name -> xray.app.dns.Config.HostMapping
|
||||||
0, // 8: xray.app.dns.NameServer.PriorityDomain.type:type_name -> xray.app.dns.DomainMatchingType
|
1, // 8: xray.app.dns.Config.query_strategy:type_name -> xray.app.dns.QueryStrategy
|
||||||
9, // 9: xray.app.dns.Config.HostsEntry.value:type_name -> xray.common.net.IPOrDomain
|
0, // 9: xray.app.dns.NameServer.PriorityDomain.type:type_name -> xray.app.dns.DomainMatchingType
|
||||||
0, // 10: xray.app.dns.Config.HostMapping.type:type_name -> xray.app.dns.DomainMatchingType
|
10, // 10: xray.app.dns.Config.HostsEntry.value:type_name -> xray.common.net.IPOrDomain
|
||||||
11, // [11:11] is the sub-list for method output_type
|
0, // 11: xray.app.dns.Config.HostMapping.type:type_name -> xray.app.dns.DomainMatchingType
|
||||||
11, // [11:11] is the sub-list for method input_type
|
12, // [12:12] is the sub-list for method output_type
|
||||||
11, // [11:11] is the sub-list for extension type_name
|
12, // [12:12] is the sub-list for method input_type
|
||||||
11, // [11:11] is the sub-list for extension extendee
|
12, // [12:12] is the sub-list for extension type_name
|
||||||
0, // [0:11] is the sub-list for field type_name
|
12, // [12:12] is the sub-list for extension extendee
|
||||||
|
0, // [0:12] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_app_dns_config_proto_init() }
|
func init() { file_app_dns_config_proto_init() }
|
||||||
|
@ -658,7 +724,7 @@ func file_app_dns_config_proto_init() {
|
||||||
File: protoimpl.DescBuilder{
|
File: protoimpl.DescBuilder{
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_app_dns_config_proto_rawDesc,
|
RawDescriptor: file_app_dns_config_proto_rawDesc,
|
||||||
NumEnums: 1,
|
NumEnums: 2,
|
||||||
NumMessages: 6,
|
NumMessages: 6,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 0,
|
NumServices: 0,
|
||||||
|
|
|
@ -36,6 +36,12 @@ enum DomainMatchingType {
|
||||||
Regex = 3;
|
Regex = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum QueryStrategy {
|
||||||
|
USE_IP = 0;
|
||||||
|
USE_IP4 = 1;
|
||||||
|
USE_IP6 = 2;
|
||||||
|
}
|
||||||
|
|
||||||
message Config {
|
message Config {
|
||||||
// Nameservers used by this DNS. Only traditional UDP servers are support at
|
// 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
|
// the moment. A special value 'localhost' as a domain address can be set to
|
||||||
|
@ -73,5 +79,7 @@ message Config {
|
||||||
reserved 7;
|
reserved 7;
|
||||||
|
|
||||||
// DisableCache Disable DNS cache
|
// DisableCache Disable DNS cache
|
||||||
bool disableCache = 8;
|
bool disableCache = 8;
|
||||||
|
|
||||||
|
QueryStrategy query_strategy = 9;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ type DNS struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
tag string
|
tag string
|
||||||
disableCache bool
|
disableCache bool
|
||||||
|
ipOption *dns.IPOption
|
||||||
hosts *StaticHosts
|
hosts *StaticHosts
|
||||||
clients []*Client
|
clients []*Client
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
@ -54,6 +55,28 @@ func New(ctx context.Context, config *Config) (*DNS, error) {
|
||||||
return nil, newError("unexpected client IP length ", len(config.ClientIp))
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hosts, err := NewStaticHosts(config.StaticHosts, config.Hosts)
|
hosts, err := NewStaticHosts(config.StaticHosts, config.Hosts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("failed to create hosts").Base(err)
|
return nil, newError("failed to create hosts").Base(err)
|
||||||
|
@ -110,6 +133,7 @@ func New(ctx context.Context, config *Config) (*DNS, error) {
|
||||||
return &DNS{
|
return &DNS{
|
||||||
tag: tag,
|
tag: tag,
|
||||||
hosts: hosts,
|
hosts: hosts,
|
||||||
|
ipOption: ipOption,
|
||||||
clients: clients,
|
clients: clients,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
domainMatcher: domainMatcher,
|
domainMatcher: domainMatcher,
|
||||||
|
@ -140,7 +164,33 @@ func (s *DNS) IsOwnLink(ctx context.Context) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LookupIP implements dns.Client.
|
// LookupIP implements dns.Client.
|
||||||
func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, error) {
|
func (s *DNS) LookupIP(domain string) ([]net.IP, error) {
|
||||||
|
return s.lookupIPInternal(domain, dns.IPOption{
|
||||||
|
IPv4Enable: true,
|
||||||
|
IPv6Enable: true,
|
||||||
|
FakeEnable: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupIPv4 implements dns.IPv4Lookup.
|
||||||
|
func (s *DNS) LookupIPv4(domain string) ([]net.IP, error) {
|
||||||
|
return s.lookupIPInternal(domain, dns.IPOption{
|
||||||
|
IPv4Enable: true,
|
||||||
|
IPv6Enable: false,
|
||||||
|
FakeEnable: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupIPv6 implements dns.IPv6Lookup.
|
||||||
|
func (s *DNS) LookupIPv6(domain string) ([]net.IP, error) {
|
||||||
|
return s.lookupIPInternal(domain, dns.IPOption{
|
||||||
|
IPv4Enable: false,
|
||||||
|
IPv6Enable: true,
|
||||||
|
FakeEnable: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DNS) lookupIPInternal(domain string, option dns.IPOption) ([]net.IP, error) {
|
||||||
if domain == "" {
|
if domain == "" {
|
||||||
return nil, newError("empty domain name")
|
return nil, newError("empty domain name")
|
||||||
}
|
}
|
||||||
|
@ -188,6 +238,22 @@ func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, error) {
|
||||||
return nil, newError("returning nil for domain ", domain).Base(errors.Combine(errs...))
|
return nil, newError("returning nil for domain ", domain).Base(errors.Combine(errs...))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetIPOption implements ClientWithIPOption.
|
||||||
|
func (s *DNS) GetIPOption() *dns.IPOption {
|
||||||
|
return s.ipOption
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetQueryOption implements ClientWithIPOption.
|
||||||
|
func (s *DNS) SetQueryOption(isIPv4Enable, isIPv6Enable bool) {
|
||||||
|
s.ipOption.IPv4Enable = isIPv4Enable
|
||||||
|
s.ipOption.IPv6Enable = isIPv6Enable
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFakeDNSOption implements ClientWithIPOption.
|
||||||
|
func (s *DNS) SetFakeDNSOption(isFakeEnable bool) {
|
||||||
|
s.ipOption.FakeEnable = isFakeEnable
|
||||||
|
}
|
||||||
|
|
||||||
func (s *DNS) sortClients(domain string) []*Client {
|
func (s *DNS) sortClients(domain string) []*Client {
|
||||||
clients := make([]*Client, 0, len(s.clients))
|
clients := make([]*Client, 0, len(s.clients))
|
||||||
clientUsed := make([]bool, len(s.clients))
|
clientUsed := make([]bool, len(s.clients))
|
||||||
|
|
|
@ -154,11 +154,7 @@ func TestUDPServerSubnet(t *testing.T) {
|
||||||
|
|
||||||
client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
|
client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
|
||||||
|
|
||||||
ips, err := client.LookupIP("google.com", feature_dns.IPOption{
|
ips, err := client.LookupIP("google.com")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -213,11 +209,7 @@ func TestUDPServer(t *testing.T) {
|
||||||
client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
|
client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
|
||||||
|
|
||||||
{
|
{
|
||||||
ips, err := client.LookupIP("google.com", feature_dns.IPOption{
|
ips, err := client.LookupIP("google.com")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -228,11 +220,7 @@ func TestUDPServer(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ips, err := client.LookupIP("facebook.com", feature_dns.IPOption{
|
ips, err := client.LookupIP("facebook.com")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -243,11 +231,7 @@ func TestUDPServer(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
_, err := client.LookupIP("notexist.google.com", feature_dns.IPOption{
|
_, err := client.LookupIP("notexist.google.com")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("nil error")
|
t.Fatal("nil error")
|
||||||
}
|
}
|
||||||
|
@ -257,11 +241,8 @@ func TestUDPServer(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ips, err := client.LookupIP("ipv4only.google.com", feature_dns.IPOption{
|
clientv6 := client.(feature_dns.IPv6Lookup)
|
||||||
IPv4Enable: false,
|
ips, err := clientv6.LookupIPv6("ipv4only.google.com")
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != feature_dns.ErrEmptyResponse {
|
if err != feature_dns.ErrEmptyResponse {
|
||||||
t.Fatal("error: ", err)
|
t.Fatal("error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -273,11 +254,7 @@ func TestUDPServer(t *testing.T) {
|
||||||
dnsServer.Shutdown()
|
dnsServer.Shutdown()
|
||||||
|
|
||||||
{
|
{
|
||||||
ips, err := client.LookupIP("google.com", feature_dns.IPOption{
|
ips, err := client.LookupIP("google.com")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -354,11 +331,7 @@ func TestPrioritizedDomain(t *testing.T) {
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
|
|
||||||
{
|
{
|
||||||
ips, err := client.LookupIP("google.com", feature_dns.IPOption{
|
ips, err := client.LookupIP("google.com")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -417,12 +390,9 @@ func TestUDPServerIPv6(t *testing.T) {
|
||||||
common.Must(err)
|
common.Must(err)
|
||||||
|
|
||||||
client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
|
client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
|
||||||
|
client6 := client.(feature_dns.IPv6Lookup)
|
||||||
{
|
{
|
||||||
ips, err := client.LookupIP("ipv6.google.com", feature_dns.IPOption{
|
ips, err := client6.LookupIPv6("ipv6.google.com")
|
||||||
IPv4Enable: false,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -485,11 +455,7 @@ func TestStaticHostDomain(t *testing.T) {
|
||||||
client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
|
client := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)
|
||||||
|
|
||||||
{
|
{
|
||||||
ips, err := client.LookupIP("example.com", feature_dns.IPOption{
|
ips, err := client.LookupIP("example.com")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -596,11 +562,7 @@ func TestIPMatch(t *testing.T) {
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
|
|
||||||
{
|
{
|
||||||
ips, err := client.LookupIP("google.com", feature_dns.IPOption{
|
ips, err := client.LookupIP("google.com")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -719,11 +681,7 @@ func TestLocalDomain(t *testing.T) {
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
|
|
||||||
{ // Will match dotless:
|
{ // Will match dotless:
|
||||||
ips, err := client.LookupIP("hostname", feature_dns.IPOption{
|
ips, err := client.LookupIP("hostname")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -734,11 +692,7 @@ func TestLocalDomain(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Will match domain:local
|
{ // Will match domain:local
|
||||||
ips, err := client.LookupIP("hostname.local", feature_dns.IPOption{
|
ips, err := client.LookupIP("hostname.local")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -749,11 +703,7 @@ func TestLocalDomain(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Will match static ip
|
{ // Will match static ip
|
||||||
ips, err := client.LookupIP("hostnamestatic", feature_dns.IPOption{
|
ips, err := client.LookupIP("hostnamestatic")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -764,11 +714,7 @@ func TestLocalDomain(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Will match domain replacing
|
{ // Will match domain replacing
|
||||||
ips, err := client.LookupIP("hostnamealias", feature_dns.IPOption{
|
ips, err := client.LookupIP("hostnamealias")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -779,11 +725,7 @@ func TestLocalDomain(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Will match dotless:localhost, but not expectIPs: 127.0.0.2, 127.0.0.3, then matches at dotless:
|
{ // Will match dotless:localhost, but not expectIPs: 127.0.0.2, 127.0.0.3, then matches at dotless:
|
||||||
ips, err := client.LookupIP("localhost", feature_dns.IPOption{
|
ips, err := client.LookupIP("localhost")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -794,11 +736,7 @@ func TestLocalDomain(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Will match dotless:localhost, and expectIPs: 127.0.0.2, 127.0.0.3
|
{ // Will match dotless:localhost, and expectIPs: 127.0.0.2, 127.0.0.3
|
||||||
ips, err := client.LookupIP("localhost-a", feature_dns.IPOption{
|
ips, err := client.LookupIP("localhost-a")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -809,11 +747,7 @@ func TestLocalDomain(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Will match dotless:localhost, and expectIPs: 127.0.0.2, 127.0.0.3
|
{ // Will match dotless:localhost, and expectIPs: 127.0.0.2, 127.0.0.3
|
||||||
ips, err := client.LookupIP("localhost-b", feature_dns.IPOption{
|
ips, err := client.LookupIP("localhost-b")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -824,11 +758,7 @@ func TestLocalDomain(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Will match dotless:
|
{ // Will match dotless:
|
||||||
ips, err := client.LookupIP("Mijia Cloud", feature_dns.IPOption{
|
ips, err := client.LookupIP("Mijia Cloud")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -990,11 +920,7 @@ func TestMultiMatchPrioritizedDomain(t *testing.T) {
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
|
|
||||||
{ // Will match server 1,2 and server 1 returns expected ip
|
{ // Will match server 1,2 and server 1 returns expected ip
|
||||||
ips, err := client.LookupIP("google.com", feature_dns.IPOption{
|
ips, err := client.LookupIP("google.com")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -1005,11 +931,8 @@ func TestMultiMatchPrioritizedDomain(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Will match server 1,2 and server 1 returns unexpected ip, then server 2 returns expected one
|
{ // Will match server 1,2 and server 1 returns unexpected ip, then server 2 returns expected one
|
||||||
ips, err := client.LookupIP("ipv6.google.com", feature_dns.IPOption{
|
clientv4 := client.(feature_dns.IPv4Lookup)
|
||||||
IPv4Enable: true,
|
ips, err := clientv4.LookupIPv4("ipv6.google.com")
|
||||||
IPv6Enable: false,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -1020,11 +943,7 @@ func TestMultiMatchPrioritizedDomain(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Will match server 3,1,2 and server 3 returns expected one
|
{ // Will match server 3,1,2 and server 3 returns expected one
|
||||||
ips, err := client.LookupIP("api.google.com", feature_dns.IPOption{
|
ips, err := client.LookupIP("api.google.com")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
@ -1035,11 +954,7 @@ func TestMultiMatchPrioritizedDomain(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Will match server 4,3,1,2 and server 4 returns expected one
|
{ // Will match server 4,3,1,2 and server 4 returns expected one
|
||||||
ips, err := client.LookupIP("v2.api.google.com", feature_dns.IPOption{
|
ips, err := client.LookupIP("v2.api.google.com")
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("unexpected error: ", err)
|
t.Fatal("unexpected error: ", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,23 @@ type LocalNameServer struct {
|
||||||
|
|
||||||
// QueryIP implements Server.
|
// QueryIP implements Server.
|
||||||
func (s *LocalNameServer) QueryIP(_ context.Context, domain string, _ net.IP, option dns.IPOption, _ bool) ([]net.IP, error) {
|
func (s *LocalNameServer) QueryIP(_ context.Context, domain string, _ net.IP, option dns.IPOption, _ bool) ([]net.IP, error) {
|
||||||
if option.IPv4Enable || option.IPv6Enable {
|
var ips []net.IP
|
||||||
return s.client.LookupIP(domain, option)
|
var err error
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case option.IPv4Enable && option.IPv6Enable:
|
||||||
|
ips, err = s.client.LookupIP(domain)
|
||||||
|
case option.IPv4Enable:
|
||||||
|
ips, err = s.client.LookupIPv4(domain)
|
||||||
|
case option.IPv6Enable:
|
||||||
|
ips, err = s.client.LookupIPv6(domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, newError("neither IPv4 nor IPv6 is enabled")
|
if len(ips) > 0 {
|
||||||
|
newError("Localhost got answer: ", domain, " -> ", ips).AtInfo().WriteToLog()
|
||||||
|
}
|
||||||
|
|
||||||
|
return ips, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name implements Server.
|
// Name implements Server.
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common"
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
"github.com/xtls/xray-core/common/session"
|
"github.com/xtls/xray-core/common/session"
|
||||||
"github.com/xtls/xray-core/features/dns"
|
|
||||||
"github.com/xtls/xray-core/features/outbound"
|
"github.com/xtls/xray-core/features/outbound"
|
||||||
routing_session "github.com/xtls/xray-core/features/routing/session"
|
routing_session "github.com/xtls/xray-core/features/routing/session"
|
||||||
"github.com/xtls/xray-core/testing/mocks"
|
"github.com/xtls/xray-core/testing/mocks"
|
||||||
|
@ -116,11 +115,7 @@ func TestIPOnDemand(t *testing.T) {
|
||||||
defer mockCtl.Finish()
|
defer mockCtl.Finish()
|
||||||
|
|
||||||
mockDNS := mocks.NewDNSClient(mockCtl)
|
mockDNS := mocks.NewDNSClient(mockCtl)
|
||||||
mockDNS.EXPECT().LookupIP(gomock.Eq("example.com"), dns.IPOption{
|
mockDNS.EXPECT().LookupIP(gomock.Eq("example.com")).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
}).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()
|
|
||||||
|
|
||||||
r := new(Router)
|
r := new(Router)
|
||||||
common.Must(r.Init(config, mockDNS, nil))
|
common.Must(r.Init(config, mockDNS, nil))
|
||||||
|
@ -155,11 +150,7 @@ func TestIPIfNonMatchDomain(t *testing.T) {
|
||||||
defer mockCtl.Finish()
|
defer mockCtl.Finish()
|
||||||
|
|
||||||
mockDNS := mocks.NewDNSClient(mockCtl)
|
mockDNS := mocks.NewDNSClient(mockCtl)
|
||||||
mockDNS.EXPECT().LookupIP(gomock.Eq("example.com"), dns.IPOption{
|
mockDNS.EXPECT().LookupIP(gomock.Eq("example.com")).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
}).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()
|
|
||||||
|
|
||||||
r := new(Router)
|
r := new(Router)
|
||||||
common.Must(r.Init(config, mockDNS, nil))
|
common.Must(r.Init(config, mockDNS, nil))
|
||||||
|
|
|
@ -21,7 +21,35 @@ type Client interface {
|
||||||
features.Feature
|
features.Feature
|
||||||
|
|
||||||
// LookupIP returns IP address for the given domain. IPs may contain IPv4 and/or IPv6 addresses.
|
// LookupIP returns IP address for the given domain. IPs may contain IPv4 and/or IPv6 addresses.
|
||||||
LookupIP(domain string, option IPOption) ([]net.IP, error)
|
LookupIP(domain string) ([]net.IP, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPv4Lookup is an optional feature for querying IPv4 addresses only.
|
||||||
|
//
|
||||||
|
// xray:api:beta
|
||||||
|
type IPv4Lookup interface {
|
||||||
|
LookupIPv4(domain string) ([]net.IP, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPv6Lookup is an optional feature for querying IPv6 addresses only.
|
||||||
|
//
|
||||||
|
// xray:api:beta
|
||||||
|
type IPv6Lookup interface {
|
||||||
|
LookupIPv6(domain string) ([]net.IP, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientWithIPOption is an optional feature for querying DNS information.
|
||||||
|
//
|
||||||
|
// xray:api:beta
|
||||||
|
type ClientWithIPOption interface {
|
||||||
|
// GetIPOption returns IPOption for the DNS client.
|
||||||
|
GetIPOption() *IPOption
|
||||||
|
|
||||||
|
// SetQueryOption sets IPv4Enable and IPv6Enable for the DNS client.
|
||||||
|
SetQueryOption(isIPv4Enable, isIPv6Enable bool)
|
||||||
|
|
||||||
|
// SetFakeDNSOption sets FakeEnable option for DNS client.
|
||||||
|
SetFakeDNSOption(isFakeEnable bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientType returns the type of Client interface. Can be used for implementing common.HasType.
|
// ClientType returns the type of Client interface. Can be used for implementing common.HasType.
|
||||||
|
|
|
@ -20,41 +20,59 @@ func (*Client) Start() error { return nil }
|
||||||
func (*Client) Close() error { return nil }
|
func (*Client) Close() error { return nil }
|
||||||
|
|
||||||
// LookupIP implements Client.
|
// LookupIP implements Client.
|
||||||
func (*Client) LookupIP(host string, option dns.IPOption) ([]net.IP, error) {
|
func (*Client) LookupIP(host string) ([]net.IP, error) {
|
||||||
ips, err := net.LookupIP(host)
|
ips, err := net.LookupIP(host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
parsedIPs := make([]net.IP, 0, len(ips))
|
parsedIPs := make([]net.IP, 0, len(ips))
|
||||||
ipv4 := make([]net.IP, 0, len(ips))
|
|
||||||
ipv6 := make([]net.IP, 0, len(ips))
|
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
parsed := net.IPAddress(ip)
|
parsed := net.IPAddress(ip)
|
||||||
if parsed != nil {
|
if parsed != nil {
|
||||||
parsedIPs = append(parsedIPs, parsed.IP())
|
parsedIPs = append(parsedIPs, parsed.IP())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if len(parsedIPs) == 0 {
|
||||||
|
return nil, dns.ErrEmptyResponse
|
||||||
|
}
|
||||||
|
return parsedIPs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupIPv4 implements IPv4Lookup.
|
||||||
|
func (c *Client) LookupIPv4(host string) ([]net.IP, error) {
|
||||||
|
ips, err := c.LookupIP(host)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ipv4 := make([]net.IP, 0, len(ips))
|
||||||
|
for _, ip := range ips {
|
||||||
if len(ip) == net.IPv4len {
|
if len(ip) == net.IPv4len {
|
||||||
ipv4 = append(ipv4, ip)
|
ipv4 = append(ipv4, ip)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if len(ipv4) == 0 {
|
||||||
|
return nil, dns.ErrEmptyResponse
|
||||||
|
}
|
||||||
|
return ipv4, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupIPv6 implements IPv6Lookup.
|
||||||
|
func (c *Client) LookupIPv6(host string) ([]net.IP, error) {
|
||||||
|
ips, err := c.LookupIP(host)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ipv6 := make([]net.IP, 0, len(ips))
|
||||||
|
for _, ip := range ips {
|
||||||
if len(ip) == net.IPv6len {
|
if len(ip) == net.IPv6len {
|
||||||
ipv6 = append(ipv6, ip)
|
ipv6 = append(ipv6, ip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch {
|
if len(ipv6) == 0 {
|
||||||
case option.IPv4Enable && option.IPv6Enable:
|
return nil, dns.ErrEmptyResponse
|
||||||
if len(parsedIPs) > 0 {
|
|
||||||
return parsedIPs, nil
|
|
||||||
}
|
|
||||||
case option.IPv4Enable:
|
|
||||||
if len(ipv4) > 0 {
|
|
||||||
return ipv4, nil
|
|
||||||
}
|
|
||||||
case option.IPv6Enable:
|
|
||||||
if len(ipv6) > 0 {
|
|
||||||
return ipv6, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil, dns.ErrEmptyResponse
|
|
||||||
|
return ipv6, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// New create a new dns.Client that queries localhost for DNS.
|
// New create a new dns.Client that queries localhost for DNS.
|
||||||
|
|
|
@ -26,11 +26,35 @@ func (ctx *ResolvableContext) GetTargetIPs() []net.IP {
|
||||||
}
|
}
|
||||||
|
|
||||||
if domain := ctx.GetTargetDomain(); len(domain) != 0 {
|
if domain := ctx.GetTargetDomain(); len(domain) != 0 {
|
||||||
ips, err := ctx.dnsClient.LookupIP(domain, dns.IPOption{
|
var lookupFunc func(string) ([]net.IP, error) = ctx.dnsClient.LookupIP
|
||||||
|
ipOption := &dns.IPOption{
|
||||||
IPv4Enable: true,
|
IPv4Enable: true,
|
||||||
IPv6Enable: true,
|
IPv6Enable: true,
|
||||||
FakeEnable: false,
|
}
|
||||||
})
|
|
||||||
|
if c, ok := ctx.dnsClient.(dns.ClientWithIPOption); ok {
|
||||||
|
ipOption = c.GetIPOption()
|
||||||
|
c.SetFakeDNSOption(false) // Skip FakeDNS.
|
||||||
|
} else {
|
||||||
|
newError("ctx.dnsClient doesn't implement ClientWithIPOption").AtDebug().WriteToLog()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case ipOption.IPv4Enable && !ipOption.IPv6Enable:
|
||||||
|
if lookupIPv4, ok := ctx.dnsClient.(dns.IPv4Lookup); ok {
|
||||||
|
lookupFunc = lookupIPv4.LookupIPv4
|
||||||
|
} else {
|
||||||
|
newError("ctx.dnsClient doesn't implement IPv4Lookup. Use LookupIP instead.").AtDebug().WriteToLog()
|
||||||
|
}
|
||||||
|
case !ipOption.IPv4Enable && ipOption.IPv6Enable:
|
||||||
|
if lookupIPv6, ok := ctx.dnsClient.(dns.IPv6Lookup); ok {
|
||||||
|
lookupFunc = lookupIPv6.LookupIPv6
|
||||||
|
} else {
|
||||||
|
newError("ctx.dnsClient doesn't implement IPv6Lookup. Use LookupIP instead.").AtDebug().WriteToLog()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ips, err := lookupFunc(domain)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ctx.resolvedIPs = ips
|
ctx.resolvedIPs = ips
|
||||||
return ips
|
return ips
|
||||||
|
|
|
@ -108,11 +108,12 @@ var typeMap = map[router.Domain_Type]dns.DomainMatchingType{
|
||||||
|
|
||||||
// DNSConfig is a JSON serializable object for dns.Config.
|
// DNSConfig is a JSON serializable object for dns.Config.
|
||||||
type DNSConfig struct {
|
type DNSConfig struct {
|
||||||
Servers []*NameServerConfig `json:"servers"`
|
Servers []*NameServerConfig `json:"servers"`
|
||||||
Hosts map[string]*Address `json:"hosts"`
|
Hosts map[string]*Address `json:"hosts"`
|
||||||
ClientIP *Address `json:"clientIp"`
|
ClientIP *Address `json:"clientIp"`
|
||||||
Tag string `json:"tag"`
|
Tag string `json:"tag"`
|
||||||
DisableCache bool `json:"disableCache"`
|
QueryStrategy string `json:"queryStrategy"`
|
||||||
|
DisableCache bool `json:"disableCache"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func getHostMapping(addr *Address) *dns.Config_HostMapping {
|
func getHostMapping(addr *Address) *dns.Config_HostMapping {
|
||||||
|
@ -141,6 +142,16 @@ func (c *DNSConfig) Build() (*dns.Config, error) {
|
||||||
config.ClientIp = []byte(c.ClientIP.IP())
|
config.ClientIp = []byte(c.ClientIP.IP())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.QueryStrategy = dns.QueryStrategy_USE_IP
|
||||||
|
switch strings.ToLower(c.QueryStrategy) {
|
||||||
|
case "useip", "use_ip", "use-ip":
|
||||||
|
config.QueryStrategy = dns.QueryStrategy_USE_IP
|
||||||
|
case "useip4", "useipv4", "use_ip4", "use_ipv4", "use_ip_v4", "use-ip4", "use-ipv4", "use-ip-v4":
|
||||||
|
config.QueryStrategy = dns.QueryStrategy_USE_IP4
|
||||||
|
case "useip6", "useipv6", "use_ip6", "use_ipv6", "use_ip_v6", "use-ip6", "use-ipv6", "use-ip-v6":
|
||||||
|
config.QueryStrategy = dns.QueryStrategy_USE_IP6
|
||||||
|
}
|
||||||
|
|
||||||
for _, server := range c.Servers {
|
for _, server := range c.Servers {
|
||||||
ns, err := server.Build()
|
ns, err := server.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -77,7 +77,9 @@ func TestDNSConfigParsing(t *testing.T) {
|
||||||
"keyword:google": "8.8.8.8",
|
"keyword:google": "8.8.8.8",
|
||||||
"regexp:.*\\.com": "8.8.4.4"
|
"regexp:.*\\.com": "8.8.4.4"
|
||||||
},
|
},
|
||||||
"clientIp": "10.0.0.1"
|
"clientIp": "10.0.0.1",
|
||||||
|
"queryStrategy": "UseIPv4",
|
||||||
|
"disableCache": true
|
||||||
}`,
|
}`,
|
||||||
Parser: parserCreator(),
|
Parser: parserCreator(),
|
||||||
Output: &dns.Config{
|
Output: &dns.Config{
|
||||||
|
@ -133,7 +135,9 @@ func TestDNSConfigParsing(t *testing.T) {
|
||||||
Ip: [][]byte{{8, 8, 4, 4}},
|
Ip: [][]byte{{8, 8, 4, 4}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ClientIp: []byte{10, 0, 0, 1},
|
ClientIp: []byte{10, 0, 0, 1},
|
||||||
|
QueryStrategy: dns.QueryStrategy_USE_IP4,
|
||||||
|
DisableCache: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -22,11 +22,11 @@ func (c *FreedomConfig) Build() (proto.Message, error) {
|
||||||
config := new(freedom.Config)
|
config := new(freedom.Config)
|
||||||
config.DomainStrategy = freedom.Config_AS_IS
|
config.DomainStrategy = freedom.Config_AS_IS
|
||||||
switch strings.ToLower(c.DomainStrategy) {
|
switch strings.ToLower(c.DomainStrategy) {
|
||||||
case "useip", "use_ip":
|
case "useip", "use_ip", "use-ip":
|
||||||
config.DomainStrategy = freedom.Config_USE_IP
|
config.DomainStrategy = freedom.Config_USE_IP
|
||||||
case "useip4", "useipv4", "use_ipv4", "use_ip_v4", "use_ip4":
|
case "useip4", "useipv4", "use_ip4", "use_ipv4", "use_ip_v4", "use-ip4", "use-ipv4", "use-ip-v4":
|
||||||
config.DomainStrategy = freedom.Config_USE_IP4
|
config.DomainStrategy = freedom.Config_USE_IP4
|
||||||
case "useip6", "useipv6", "use_ipv6", "use_ip_v6", "use_ip6":
|
case "useip6", "useipv6", "use_ip6", "use_ipv6", "use_ip_v6", "use-ip6", "use-ipv6", "use-ip-v6":
|
||||||
config.DomainStrategy = freedom.Config_USE_IP6
|
config.DomainStrategy = freedom.Config_USE_IP6
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,12 +37,27 @@ type ownLinkVerifier interface {
|
||||||
|
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
client dns.Client
|
client dns.Client
|
||||||
|
ipv4Lookup dns.IPv4Lookup
|
||||||
|
ipv6Lookup dns.IPv6Lookup
|
||||||
ownLinkVerifier ownLinkVerifier
|
ownLinkVerifier ownLinkVerifier
|
||||||
server net.Destination
|
server net.Destination
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) Init(config *Config, dnsClient dns.Client) error {
|
func (h *Handler) Init(config *Config, dnsClient dns.Client) error {
|
||||||
h.client = dnsClient
|
h.client = dnsClient
|
||||||
|
|
||||||
|
if ipv4lookup, ok := dnsClient.(dns.IPv4Lookup); ok {
|
||||||
|
h.ipv4Lookup = ipv4lookup
|
||||||
|
} else {
|
||||||
|
return newError("dns.Client doesn't implement IPv4Lookup")
|
||||||
|
}
|
||||||
|
|
||||||
|
if ipv6lookup, ok := dnsClient.(dns.IPv6Lookup); ok {
|
||||||
|
h.ipv6Lookup = ipv6lookup
|
||||||
|
} else {
|
||||||
|
return newError("dns.Client doesn't implement IPv6Lookup")
|
||||||
|
}
|
||||||
|
|
||||||
if v, ok := dnsClient.(ownLinkVerifier); ok {
|
if v, ok := dnsClient.(ownLinkVerifier); ok {
|
||||||
h.ownLinkVerifier = v
|
h.ownLinkVerifier = v
|
||||||
}
|
}
|
||||||
|
@ -199,19 +214,18 @@ func (h *Handler) handleIPQuery(id uint16, qType dnsmessage.Type, domain string,
|
||||||
|
|
||||||
var ttl uint32 = 600
|
var ttl uint32 = 600
|
||||||
|
|
||||||
|
// Do NOT skip FakeDNS
|
||||||
|
if c, ok := h.client.(dns.ClientWithIPOption); ok {
|
||||||
|
c.SetFakeDNSOption(true)
|
||||||
|
} else {
|
||||||
|
newError("dns.Client doesn't implement ClientWithIPOption")
|
||||||
|
}
|
||||||
|
|
||||||
switch qType {
|
switch qType {
|
||||||
case dnsmessage.TypeA:
|
case dnsmessage.TypeA:
|
||||||
ips, err = h.client.LookupIP(domain, dns.IPOption{
|
ips, err = h.ipv4Lookup.LookupIPv4(domain)
|
||||||
IPv4Enable: true,
|
|
||||||
IPv6Enable: false,
|
|
||||||
FakeEnable: true,
|
|
||||||
})
|
|
||||||
case dnsmessage.TypeAAAA:
|
case dnsmessage.TypeAAAA:
|
||||||
ips, err = h.client.LookupIP(domain, dns.IPOption{
|
ips, err = h.ipv6Lookup.LookupIPv6(domain)
|
||||||
IPv4Enable: false,
|
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: true,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rcode := dns.RCodeFromError(err)
|
rcode := dns.RCodeFromError(err)
|
||||||
|
|
|
@ -59,26 +59,24 @@ func (h *Handler) policy() policy.Session {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) resolveIP(ctx context.Context, domain string, localAddr net.Address) net.Address {
|
func (h *Handler) resolveIP(ctx context.Context, domain string, localAddr net.Address) net.Address {
|
||||||
var option dns.IPOption = dns.IPOption{
|
if c, ok := h.dns.(dns.ClientWithIPOption); ok {
|
||||||
IPv4Enable: true,
|
c.SetFakeDNSOption(false) // Skip FakeDNS
|
||||||
IPv6Enable: true,
|
} else {
|
||||||
FakeEnable: false,
|
newError("DNS client doesn't implement ClientWithIPOption")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lookupFunc func(string) ([]net.IP, error) = h.dns.LookupIP
|
||||||
if h.config.DomainStrategy == Config_USE_IP4 || (localAddr != nil && localAddr.Family().IsIPv4()) {
|
if h.config.DomainStrategy == Config_USE_IP4 || (localAddr != nil && localAddr.Family().IsIPv4()) {
|
||||||
option = dns.IPOption{
|
if lookupIPv4, ok := h.dns.(dns.IPv4Lookup); ok {
|
||||||
IPv4Enable: true,
|
lookupFunc = lookupIPv4.LookupIPv4
|
||||||
IPv6Enable: false,
|
|
||||||
FakeEnable: false,
|
|
||||||
}
|
}
|
||||||
} else if h.config.DomainStrategy == Config_USE_IP6 || (localAddr != nil && localAddr.Family().IsIPv6()) {
|
} else if h.config.DomainStrategy == Config_USE_IP6 || (localAddr != nil && localAddr.Family().IsIPv6()) {
|
||||||
option = dns.IPOption{
|
if lookupIPv6, ok := h.dns.(dns.IPv6Lookup); ok {
|
||||||
IPv4Enable: false,
|
lookupFunc = lookupIPv6.LookupIPv6
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ips, err := h.dns.LookupIP(domain, option)
|
ips, err := lookupFunc(domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
newError("failed to get IP address for domain ", domain).Base(err).WriteToLog(session.ExportIDToError(ctx))
|
newError("failed to get IP address for domain ", domain).Base(err).WriteToLog(session.ExportIDToError(ctx))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +1,40 @@
|
||||||
// Code generated by MockGen. DO NOT EDIT.
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
// Source: github.com/xtls/xray-core/features/dns (interfaces: Client)
|
// Source: github.com/xray/xray-core/v4/features/dns (interfaces: Client)
|
||||||
|
|
||||||
// Package mocks is a generated GoMock package.
|
// Package mocks is a generated GoMock package.
|
||||||
package mocks
|
package mocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
gomock "github.com/golang/mock/gomock"
|
|
||||||
dns "github.com/xtls/xray-core/features/dns"
|
|
||||||
net "net"
|
net "net"
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
|
|
||||||
|
gomock "github.com/golang/mock/gomock"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DNSClient is a mock of Client interface
|
// DNSClient is a mock of Client interface.
|
||||||
type DNSClient struct {
|
type DNSClient struct {
|
||||||
ctrl *gomock.Controller
|
ctrl *gomock.Controller
|
||||||
recorder *DNSClientMockRecorder
|
recorder *DNSClientMockRecorder
|
||||||
}
|
}
|
||||||
|
|
||||||
// DNSClientMockRecorder is the mock recorder for DNSClient
|
// DNSClientMockRecorder is the mock recorder for DNSClient.
|
||||||
type DNSClientMockRecorder struct {
|
type DNSClientMockRecorder struct {
|
||||||
mock *DNSClient
|
mock *DNSClient
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSClient creates a new mock instance
|
// NewDNSClient creates a new mock instance.
|
||||||
func NewDNSClient(ctrl *gomock.Controller) *DNSClient {
|
func NewDNSClient(ctrl *gomock.Controller) *DNSClient {
|
||||||
mock := &DNSClient{ctrl: ctrl}
|
mock := &DNSClient{ctrl: ctrl}
|
||||||
mock.recorder = &DNSClientMockRecorder{mock}
|
mock.recorder = &DNSClientMockRecorder{mock}
|
||||||
return mock
|
return mock
|
||||||
}
|
}
|
||||||
|
|
||||||
// EXPECT returns an object that allows the caller to indicate expected use
|
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||||
func (m *DNSClient) EXPECT() *DNSClientMockRecorder {
|
func (m *DNSClient) EXPECT() *DNSClientMockRecorder {
|
||||||
return m.recorder
|
return m.recorder
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close mocks base method
|
// Close mocks base method.
|
||||||
func (m *DNSClient) Close() error {
|
func (m *DNSClient) Close() error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "Close")
|
ret := m.ctrl.Call(m, "Close")
|
||||||
|
@ -42,28 +42,28 @@ func (m *DNSClient) Close() error {
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close indicates an expected call of Close
|
// Close indicates an expected call of Close.
|
||||||
func (mr *DNSClientMockRecorder) Close() *gomock.Call {
|
func (mr *DNSClientMockRecorder) Close() *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*DNSClient)(nil).Close))
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*DNSClient)(nil).Close))
|
||||||
}
|
}
|
||||||
|
|
||||||
// LookupIP mocks base method
|
// LookupIP mocks base method.
|
||||||
func (m *DNSClient) LookupIP(arg0 string, arg1 dns.IPOption) ([]net.IP, error) {
|
func (m *DNSClient) LookupIP(arg0 string) ([]net.IP, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "LookupIP", arg0, arg1)
|
ret := m.ctrl.Call(m, "LookupIP", arg0)
|
||||||
ret0, _ := ret[0].([]net.IP)
|
ret0, _ := ret[0].([]net.IP)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// LookupIP indicates an expected call of LookupIP
|
// LookupIP indicates an expected call of LookupIP.
|
||||||
func (mr *DNSClientMockRecorder) LookupIP(arg0, arg1 interface{}) *gomock.Call {
|
func (mr *DNSClientMockRecorder) LookupIP(arg0 interface{}) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LookupIP", reflect.TypeOf((*DNSClient)(nil).LookupIP), arg0, arg1)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LookupIP", reflect.TypeOf((*DNSClient)(nil).LookupIP), arg0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start mocks base method
|
// Start mocks base method.
|
||||||
func (m *DNSClient) Start() error {
|
func (m *DNSClient) Start() error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "Start")
|
ret := m.ctrl.Call(m, "Start")
|
||||||
|
@ -71,13 +71,13 @@ func (m *DNSClient) Start() error {
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start indicates an expected call of Start
|
// Start indicates an expected call of Start.
|
||||||
func (mr *DNSClientMockRecorder) Start() *gomock.Call {
|
func (mr *DNSClientMockRecorder) Start() *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*DNSClient)(nil).Start))
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*DNSClient)(nil).Start))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type mocks base method
|
// Type mocks base method.
|
||||||
func (m *DNSClient) Type() interface{} {
|
func (m *DNSClient) Type() interface{} {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "Type")
|
ret := m.ctrl.Call(m, "Type")
|
||||||
|
@ -85,7 +85,7 @@ func (m *DNSClient) Type() interface{} {
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type indicates an expected call of Type
|
// Type indicates an expected call of Type.
|
||||||
func (mr *DNSClientMockRecorder) Type() *gomock.Call {
|
func (mr *DNSClientMockRecorder) Type() *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Type", reflect.TypeOf((*DNSClient)(nil).Type))
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Type", reflect.TypeOf((*DNSClient)(nil).Type))
|
||||||
|
|
|
@ -63,30 +63,27 @@ func (d *DefaultSystemDialer) lookupIP(domain string, strategy DomainStrategy, l
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var option = dns.IPOption{
|
if c, ok := d.dns.(dns.ClientWithIPOption); ok {
|
||||||
IPv4Enable: true,
|
c.SetFakeDNSOption(false) // Skip FakeDNS
|
||||||
IPv6Enable: true,
|
} else {
|
||||||
FakeEnable: false,
|
newError("DNS client doesn't implement ClientWithIPOption")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lookupFunc func(string) ([]net.IP, error) = d.dns.LookupIP
|
||||||
switch {
|
switch {
|
||||||
case strategy == DomainStrategy_USE_IP4 || (localAddr != nil && localAddr.Family().IsIPv4()):
|
case strategy == DomainStrategy_USE_IP4 || (localAddr != nil && localAddr.Family().IsIPv4()):
|
||||||
option = dns.IPOption{
|
if lookupIPv4, ok := d.dns.(dns.IPv4Lookup); ok {
|
||||||
IPv4Enable: true,
|
lookupFunc = lookupIPv4.LookupIPv4
|
||||||
IPv6Enable: false,
|
|
||||||
FakeEnable: false,
|
|
||||||
}
|
}
|
||||||
case strategy == DomainStrategy_USE_IP6 || (localAddr != nil && localAddr.Family().IsIPv6()):
|
case strategy == DomainStrategy_USE_IP6 || (localAddr != nil && localAddr.Family().IsIPv6()):
|
||||||
option = dns.IPOption{
|
if lookupIPv6, ok := d.dns.(dns.IPv6Lookup); ok {
|
||||||
IPv4Enable: false,
|
lookupFunc = lookupIPv6.LookupIPv6
|
||||||
IPv6Enable: true,
|
|
||||||
FakeEnable: false,
|
|
||||||
}
|
}
|
||||||
case strategy == DomainStrategy_AS_IS:
|
case strategy == DomainStrategy_AS_IS:
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return d.dns.LookupIP(domain, option)
|
return lookupFunc(domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DefaultSystemDialer) doLookupIP(ctx context.Context, dst net.Destination, sockopt *SocketConfig) bool {
|
func (d *DefaultSystemDialer) doLookupIP(ctx context.Context, dst net.Destination, sockopt *SocketConfig) bool {
|
||||||
|
|
Loading…
Reference in New Issue