From a3c6cc6aa81f6a6cbe3d9181b408759e680b346d Mon Sep 17 00:00:00 2001 From: LjhAUMEM Date: Mon, 5 Oct 2026 16:07:19 +0800 Subject: [PATCH] XDNS finalmask: Default values for `types`; `name`->`names`; `type`+`addr`->`addrs` (#7090) https://github.com/XTLS/Xray-core/pull/7090#issuecomment-5989883544 https://github.com/XTLS/Xray-core/pull/7090#issuecomment-5988755551 https://github.com/XTLS/Xray-core/pull/7089#issuecomment-5987266008 --- infra/conf/transport_finalmask.go | 96 +++++----- transport/internet/finalmask/xdns/client.go | 3 + .../internet/finalmask/xdns/config.pb.go | 181 +++++++----------- .../internet/finalmask/xdns/config.proto | 15 +- transport/internet/finalmask/xdns/resolver.go | 19 +- .../internet/finalmask/xdns/resolver_tcp.go | 2 +- .../internet/finalmask/xdns/resolver_udp.go | 2 +- transport/internet/finalmask/xdns/server.go | 3 + 8 files changed, 135 insertions(+), 186 deletions(-) diff --git a/infra/conf/transport_finalmask.go b/infra/conf/transport_finalmask.go index 69a69b5f2..7eeab9b08 100644 --- a/infra/conf/transport_finalmask.go +++ b/infra/conf/transport_finalmask.go @@ -15,7 +15,6 @@ import ( googleuuid "github.com/google/uuid" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/net" - "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/transport/internet/finalmask/fragment" "github.com/xtls/xray-core/transport/internet/finalmask/header/custom" "github.com/xtls/xray-core/transport/internet/finalmask/mkcp/aes128gcm" @@ -792,37 +791,15 @@ func (c *Sudoku) Build() (proto.Message, error) { } type XDNSDomain struct { - Name string `json:"name"` - LenLimit int32 `json:"lenLimit"` - LabelLimit int32 `json:"labelLimit"` - Types []int32 `json:"types"` - Edns0 int32 `json:"edns0"` + Names []string `json:"names"` + LenLimit int32 `json:"lenLimit"` + LabelLimit int32 `json:"labelLimit"` + Types []int32 `json:"types"` + Edns0 int32 `json:"edns0"` } -type XDNSResolverTCP struct { - Addr string `json:"addr"` -} - -func (c *XDNSResolverTCP) Build() (proto.Message, error) { - return &xdns.TCPResolverProto{Addr: c.Addr}, nil -} - -type XDNSResolverUDP struct { - Addr string `json:"addr"` -} - -func (c *XDNSResolverUDP) Build() (proto.Message, error) { - return &xdns.UDPResolverProto{Addr: c.Addr}, nil -} - -var xdnsLoader = NewJSONConfigLoader(ConfigCreatorCache{ - "tcp": func() interface{} { return new(XDNSResolverTCP) }, - "udp": func() interface{} { return new(XDNSResolverUDP) }, -}, "type", "settings") - type XDNSResolver struct { - Type string `json:"type"` - Settings json.RawMessage `json:"settings"` + Addrs []string `json:"addrs"` } type XDNS struct { @@ -833,7 +810,7 @@ type XDNS struct { func (c *XDNS) Build() (proto.Message, error) { var domains []*xdns.DomainProto - var resolvers []*serial.TypedMessage + var resolvers []*xdns.ResolverProto for i := range c.Domains { if c.Domains[i].LenLimit == 0 { c.Domains[i].LenLimit = 255 @@ -841,33 +818,46 @@ func (c *XDNS) Build() (proto.Message, error) { if c.Domains[i].LabelLimit == 0 { c.Domains[i].LabelLimit = 63 } - types := make([]uint16, 0, len(c.Domains[i].Types)) - for j := range c.Domains[i].Types { - types = append(types, uint16(c.Domains[i].Types[j])) + for j := range c.Domains[i].Names { + domain, err := xdns.NewDomain(c.Domains[i].Names[j], int(c.Domains[i].LenLimit), int(c.Domains[i].LabelLimit), []uint16{1, 5, 16, 28}, uint16(c.Domains[i].Edns0)) + if err != nil { + return nil, err + } + errors.LogInfo(context.Background(), domain.Show()) + domains = append(domains, &xdns.DomainProto{ + Name: c.Domains[i].Names[j], + LenLimit: c.Domains[i].LenLimit, + LabelLimit: c.Domains[i].LabelLimit, + Types: c.Domains[i].Types, + Edns0: c.Domains[i].Edns0, + }) } - domain, err := xdns.NewDomain(c.Domains[i].Name, int(c.Domains[i].LenLimit), int(c.Domains[i].LabelLimit), types, uint16(c.Domains[i].Edns0)) - if err != nil { - return nil, err - } - errors.LogInfo(context.Background(), domain.Show()) - domains = append(domains, &xdns.DomainProto{ - Name: c.Domains[i].Name, - LenLimit: c.Domains[i].LenLimit, - LabelLimit: c.Domains[i].LabelLimit, - Types: c.Domains[i].Types, - Edns0: c.Domains[i].Edns0, - }) } for i := range c.Resolvers { - config, err := xdnsLoader.LoadWithID(c.Resolvers[i].Settings, c.Resolvers[i].Type) - if err != nil { - return nil, err + for j := range c.Resolvers[i].Addrs { + var u *url.URL + var e error + if !strings.Contains(c.Resolvers[i].Addrs[j], "://") { + u, e = url.Parse("udp://" + c.Resolvers[i].Addrs[j]) + } else { + u, e = url.Parse(c.Resolvers[i].Addrs[j]) + } + if e != nil { + return nil, e + } + switch u.Scheme { + case "tcp", "udp": + default: + return nil, errors.New("invalid protocol") + } + var host, port string + host = u.Hostname() + port = u.Port() + if port == "" { + port = "53" + } + resolvers = append(resolvers, &xdns.ResolverProto{Type: u.Scheme, Addr: net.JoinHostPort(host, port)}) } - pm, err := config.(interface{ Build() (proto.Message, error) }).Build() - if err != nil { - return nil, err - } - resolvers = append(resolvers, serial.ToTypedMessage(pm)) } if c.ExtraPoll < 0 || c.ExtraPoll > 3 { return nil, errors.New("c.ExtraPoll < 0 || c.ExtraPoll > 3") diff --git a/transport/internet/finalmask/xdns/client.go b/transport/internet/finalmask/xdns/client.go index d454a8ccd..73b265e5a 100644 --- a/transport/internet/finalmask/xdns/client.go +++ b/transport/internet/finalmask/xdns/client.go @@ -70,6 +70,9 @@ func NewClient(c *Config, dialer *finalmask.Dialer) (net.PacketConn, error) { for j := range c.Domains[i].Types { types = append(types, uint16(c.Domains[i].Types[j])) } + if len(types) == 0 { + types = []uint16{16} + } domain, err := NewDomain(c.Domains[i].Name, int(c.Domains[i].LenLimit), int(c.Domains[i].LabelLimit), types, uint16(c.Domains[i].Edns0)) if err != nil { return nil, err diff --git a/transport/internet/finalmask/xdns/config.pb.go b/transport/internet/finalmask/xdns/config.pb.go index 7db693f98..9ef86ba4e 100644 --- a/transport/internet/finalmask/xdns/config.pb.go +++ b/transport/internet/finalmask/xdns/config.pb.go @@ -7,7 +7,7 @@ package xdns import ( - serial "github.com/xtls/xray-core/common/serial" + _ "github.com/xtls/xray-core/common/serial" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -98,10 +98,62 @@ func (x *DomainProto) GetEdns0() int32 { return 0 } +type ResolverProto struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Addr string `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResolverProto) Reset() { + *x = ResolverProto{} + mi := &file_transport_internet_finalmask_xdns_config_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResolverProto) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResolverProto) ProtoMessage() {} + +func (x *ResolverProto) ProtoReflect() protoreflect.Message { + mi := &file_transport_internet_finalmask_xdns_config_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResolverProto.ProtoReflect.Descriptor instead. +func (*ResolverProto) Descriptor() ([]byte, []int) { + return file_transport_internet_finalmask_xdns_config_proto_rawDescGZIP(), []int{1} +} + +func (x *ResolverProto) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *ResolverProto) GetAddr() string { + if x != nil { + return x.Addr + } + return "" +} + type Config struct { state protoimpl.MessageState `protogen:"open.v1"` Domains []*DomainProto `protobuf:"bytes,1,rep,name=domains,proto3" json:"domains,omitempty"` - Resolvers []*serial.TypedMessage `protobuf:"bytes,2,rep,name=resolvers,proto3" json:"resolvers,omitempty"` + Resolvers []*ResolverProto `protobuf:"bytes,2,rep,name=resolvers,proto3" json:"resolvers,omitempty"` ExtraPoll int32 `protobuf:"varint,3,opt,name=extra_poll,json=extraPoll,proto3" json:"extra_poll,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -109,7 +161,7 @@ type Config struct { func (x *Config) Reset() { *x = Config{} - mi := &file_transport_internet_finalmask_xdns_config_proto_msgTypes[1] + mi := &file_transport_internet_finalmask_xdns_config_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -121,7 +173,7 @@ func (x *Config) String() string { func (*Config) ProtoMessage() {} func (x *Config) ProtoReflect() protoreflect.Message { - mi := &file_transport_internet_finalmask_xdns_config_proto_msgTypes[1] + mi := &file_transport_internet_finalmask_xdns_config_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -134,7 +186,7 @@ func (x *Config) ProtoReflect() protoreflect.Message { // Deprecated: Use Config.ProtoReflect.Descriptor instead. func (*Config) Descriptor() ([]byte, []int) { - return file_transport_internet_finalmask_xdns_config_proto_rawDescGZIP(), []int{1} + return file_transport_internet_finalmask_xdns_config_proto_rawDescGZIP(), []int{2} } func (x *Config) GetDomains() []*DomainProto { @@ -144,7 +196,7 @@ func (x *Config) GetDomains() []*DomainProto { return nil } -func (x *Config) GetResolvers() []*serial.TypedMessage { +func (x *Config) GetResolvers() []*ResolverProto { if x != nil { return x.Resolvers } @@ -158,94 +210,6 @@ func (x *Config) GetExtraPoll() int32 { return 0 } -type TCPResolverProto struct { - state protoimpl.MessageState `protogen:"open.v1"` - Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *TCPResolverProto) Reset() { - *x = TCPResolverProto{} - mi := &file_transport_internet_finalmask_xdns_config_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *TCPResolverProto) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TCPResolverProto) ProtoMessage() {} - -func (x *TCPResolverProto) ProtoReflect() protoreflect.Message { - mi := &file_transport_internet_finalmask_xdns_config_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TCPResolverProto.ProtoReflect.Descriptor instead. -func (*TCPResolverProto) Descriptor() ([]byte, []int) { - return file_transport_internet_finalmask_xdns_config_proto_rawDescGZIP(), []int{2} -} - -func (x *TCPResolverProto) GetAddr() string { - if x != nil { - return x.Addr - } - return "" -} - -type UDPResolverProto struct { - state protoimpl.MessageState `protogen:"open.v1"` - Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *UDPResolverProto) Reset() { - *x = UDPResolverProto{} - mi := &file_transport_internet_finalmask_xdns_config_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *UDPResolverProto) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UDPResolverProto) ProtoMessage() {} - -func (x *UDPResolverProto) ProtoReflect() protoreflect.Message { - mi := &file_transport_internet_finalmask_xdns_config_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UDPResolverProto.ProtoReflect.Descriptor instead. -func (*UDPResolverProto) Descriptor() ([]byte, []int) { - return file_transport_internet_finalmask_xdns_config_proto_rawDescGZIP(), []int{3} -} - -func (x *UDPResolverProto) GetAddr() string { - if x != nil { - return x.Addr - } - return "" -} - var File_transport_internet_finalmask_xdns_config_proto protoreflect.FileDescriptor const file_transport_internet_finalmask_xdns_config_proto_rawDesc = "" + @@ -257,16 +221,15 @@ const file_transport_internet_finalmask_xdns_config_proto_rawDesc = "" + "\vlabel_limit\x18\x03 \x01(\x05R\n" + "labelLimit\x12\x14\n" + "\x05types\x18\x04 \x03(\x05R\x05types\x12\x14\n" + - "\x05edns0\x18\x05 \x01(\x05R\x05edns0\"\xb6\x01\n" + + "\x05edns0\x18\x05 \x01(\x05R\x05edns0\"7\n" + + "\rResolverProto\x12\x12\n" + + "\x04type\x18\x01 \x01(\tR\x04type\x12\x12\n" + + "\x04addr\x18\x02 \x01(\tR\x04addr\"\xcb\x01\n" + "\x06Config\x12M\n" + - "\adomains\x18\x01 \x03(\v23.xray.transport.internet.finalmask.xdns.DomainProtoR\adomains\x12>\n" + - "\tresolvers\x18\x02 \x03(\v2 .xray.common.serial.TypedMessageR\tresolvers\x12\x1d\n" + + "\adomains\x18\x01 \x03(\v23.xray.transport.internet.finalmask.xdns.DomainProtoR\adomains\x12S\n" + + "\tresolvers\x18\x02 \x03(\v25.xray.transport.internet.finalmask.xdns.ResolverProtoR\tresolvers\x12\x1d\n" + "\n" + - "extra_poll\x18\x03 \x01(\x05R\textraPoll\"&\n" + - "\x10TCPResolverProto\x12\x12\n" + - "\x04addr\x18\x01 \x01(\tR\x04addr\"&\n" + - "\x10UDPResolverProto\x12\x12\n" + - "\x04addr\x18\x01 \x01(\tR\x04addrB\x94\x01\n" + + "extra_poll\x18\x03 \x01(\x05R\textraPollB\x94\x01\n" + "*com.xray.transport.internet.finalmask.xdnsP\x01Z;github.com/xtls/xray-core/transport/internet/finalmask/xdns\xaa\x02&Xray.Transport.Internet.Finalmask.Xdnsb\x06proto3" var ( @@ -281,17 +244,15 @@ func file_transport_internet_finalmask_xdns_config_proto_rawDescGZIP() []byte { return file_transport_internet_finalmask_xdns_config_proto_rawDescData } -var file_transport_internet_finalmask_xdns_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_transport_internet_finalmask_xdns_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_transport_internet_finalmask_xdns_config_proto_goTypes = []any{ - (*DomainProto)(nil), // 0: xray.transport.internet.finalmask.xdns.DomainProto - (*Config)(nil), // 1: xray.transport.internet.finalmask.xdns.Config - (*TCPResolverProto)(nil), // 2: xray.transport.internet.finalmask.xdns.TCPResolverProto - (*UDPResolverProto)(nil), // 3: xray.transport.internet.finalmask.xdns.UDPResolverProto - (*serial.TypedMessage)(nil), // 4: xray.common.serial.TypedMessage + (*DomainProto)(nil), // 0: xray.transport.internet.finalmask.xdns.DomainProto + (*ResolverProto)(nil), // 1: xray.transport.internet.finalmask.xdns.ResolverProto + (*Config)(nil), // 2: xray.transport.internet.finalmask.xdns.Config } var file_transport_internet_finalmask_xdns_config_proto_depIdxs = []int32{ 0, // 0: xray.transport.internet.finalmask.xdns.Config.domains:type_name -> xray.transport.internet.finalmask.xdns.DomainProto - 4, // 1: xray.transport.internet.finalmask.xdns.Config.resolvers:type_name -> xray.common.serial.TypedMessage + 1, // 1: xray.transport.internet.finalmask.xdns.Config.resolvers:type_name -> xray.transport.internet.finalmask.xdns.ResolverProto 2, // [2:2] is the sub-list for method output_type 2, // [2:2] is the sub-list for method input_type 2, // [2:2] is the sub-list for extension type_name @@ -310,7 +271,7 @@ func file_transport_internet_finalmask_xdns_config_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_transport_internet_finalmask_xdns_config_proto_rawDesc), len(file_transport_internet_finalmask_xdns_config_proto_rawDesc)), NumEnums: 0, - NumMessages: 4, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, diff --git a/transport/internet/finalmask/xdns/config.proto b/transport/internet/finalmask/xdns/config.proto index 1e464cb2d..e60ce8aba 100644 --- a/transport/internet/finalmask/xdns/config.proto +++ b/transport/internet/finalmask/xdns/config.proto @@ -16,16 +16,13 @@ message DomainProto { int32 edns0 = 5; } +message ResolverProto { + string type = 1; + string addr = 2; +} + message Config { repeated DomainProto domains = 1; - repeated xray.common.serial.TypedMessage resolvers = 2; + repeated ResolverProto resolvers = 2; int32 extra_poll = 3; -} - -message TCPResolverProto { - string addr = 1; -} - -message UDPResolverProto { - string addr = 1; } \ No newline at end of file diff --git a/transport/internet/finalmask/xdns/resolver.go b/transport/internet/finalmask/xdns/resolver.go index 279af5053..628dafbca 100644 --- a/transport/internet/finalmask/xdns/resolver.go +++ b/transport/internet/finalmask/xdns/resolver.go @@ -4,7 +4,6 @@ import ( "errors" "net" - "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/transport/internet/finalmask" ) @@ -15,17 +14,13 @@ type Resolver interface { Close() } -func NewResolver(proto *serial.TypedMessage, dialer *finalmask.Dialer) (Resolver, error) { - config, err := proto.GetInstance() - if err != nil { - return nil, err - } - switch v := config.(type) { - case *TCPResolverProto: - return NewTCPResolver(v, dialer) - case *UDPResolverProto: - return NewUDPResolver(v, dialer) +func NewResolver(config *ResolverProto, dialer *finalmask.Dialer) (Resolver, error) { + switch config.Type { + case "tcp": + return NewTCPResolver(config, dialer) + case "udp": + return NewUDPResolver(config, dialer) default: - return nil, errors.New("unknown proto") + return nil, errors.New("unknown type") } } diff --git a/transport/internet/finalmask/xdns/resolver_tcp.go b/transport/internet/finalmask/xdns/resolver_tcp.go index 0d0d2d845..871daa6db 100644 --- a/transport/internet/finalmask/xdns/resolver_tcp.go +++ b/transport/internet/finalmask/xdns/resolver_tcp.go @@ -24,7 +24,7 @@ type TCPResolver struct { mu sync.Mutex } -func NewTCPResolver(config *TCPResolverProto, dialer *finalmask.Dialer) (Resolver, error) { +func NewTCPResolver(config *ResolverProto, dialer *finalmask.Dialer) (Resolver, error) { dest, err := net.ParseDestination("tcp:" + config.Addr) if err != nil { return nil, err diff --git a/transport/internet/finalmask/xdns/resolver_udp.go b/transport/internet/finalmask/xdns/resolver_udp.go index 43c35007c..ca4750927 100644 --- a/transport/internet/finalmask/xdns/resolver_udp.go +++ b/transport/internet/finalmask/xdns/resolver_udp.go @@ -22,7 +22,7 @@ type UDPResolver struct { mu sync.Mutex } -func NewUDPResolver(config *UDPResolverProto, dialer *finalmask.Dialer) (Resolver, error) { +func NewUDPResolver(config *ResolverProto, dialer *finalmask.Dialer) (Resolver, error) { dest, err := net.ParseDestination("udp:" + config.Addr) if err != nil { return nil, err diff --git a/transport/internet/finalmask/xdns/server.go b/transport/internet/finalmask/xdns/server.go index c7506f5f3..e5b2efbad 100644 --- a/transport/internet/finalmask/xdns/server.go +++ b/transport/internet/finalmask/xdns/server.go @@ -52,6 +52,9 @@ func NewServer(c *Config, raw net.PacketConn) (net.PacketConn, error) { for j := range c.Domains[i].Types { types = append(types, uint16(c.Domains[i].Types[j])) } + if len(types) == 0 { + types = []uint16{1, 5, 16, 28} + } domain, err := NewDomain(c.Domains[i].Name, int(c.Domains[i].LenLimit), int(c.Domains[i].LabelLimit), types, uint16(c.Domains[i].Edns0)) if err != nil { return nil, err