From a0107d296bed003de94bc8ccbf9ca3c7fded2d37 Mon Sep 17 00:00:00 2001 From: rui0572 <125641819+rui0572@users.noreply.github.com> Date: Sun, 7 May 2023 01:33:26 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=9F=E4=B8=80=20`domainStrategy`=20?= =?UTF-8?q?=E8=A1=8C=E4=B8=BA.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- infra/conf/transport_internet.go | 28 ++++++++-- transport/internet/config.go | 43 ++++++++++++++++ transport/internet/config.pb.go | 87 +++++++++++++++++++++----------- transport/internet/config.proto | 7 +++ transport/internet/dialer.go | 34 +++++-------- 5 files changed, 142 insertions(+), 57 deletions(-) diff --git a/infra/conf/transport_internet.go b/infra/conf/transport_internet.go index 0da0fb645290..138baec6deee 100644 --- a/infra/conf/transport_internet.go +++ b/infra/conf/transport_internet.go @@ -617,7 +617,7 @@ type SocketConfig struct { TCPKeepAliveIdle int32 `json:"tcpKeepAliveIdle"` TCPCongestion string `json:"tcpCongestion"` TCPWindowClamp int32 `json:"tcpWindowClamp"` - TCPMaxSeg int32 `json:"tcpMaxSeg"` + TCPMaxSeg int32 `json:"tcpMaxSeg"` TCPUserTimeout int32 `json:"tcpUserTimeout"` V6only bool `json:"v6only"` Interface string `json:"interface"` @@ -652,12 +652,30 @@ func (c *SocketConfig) Build() (*internet.SocketConfig, error) { dStrategy := internet.DomainStrategy_AS_IS switch strings.ToLower(c.DomainStrategy) { - case "useip", "use_ip": + case "asis", "": + dStrategy = internet.DomainStrategy_AS_IS + case "useip": dStrategy = internet.DomainStrategy_USE_IP - case "useip4", "useipv4", "use_ipv4", "use_ip_v4", "use_ip4": + case "useipv4": dStrategy = internet.DomainStrategy_USE_IP4 - case "useip6", "useipv6", "use_ipv6", "use_ip_v6", "use_ip6": + case "useipv6": dStrategy = internet.DomainStrategy_USE_IP6 + case "useipv4v6": + dStrategy = internet.DomainStrategy_USE_IP46 + case "useipv6v4": + dStrategy = internet.DomainStrategy_USE_IP64 + case "forceip": + dStrategy = internet.DomainStrategy_FORCE_IP + case "forceipv4": + dStrategy = internet.DomainStrategy_FORCE_IP4 + case "forceipv6": + dStrategy = internet.DomainStrategy_FORCE_IP6 + case "forceipv4v6": + dStrategy = internet.DomainStrategy_FORCE_IP46 + case "forceipv6v4": + dStrategy = internet.DomainStrategy_FORCE_IP64 + default: + return nil, newError("unsupported domain strategy: ", c.DomainStrategy) } return &internet.SocketConfig{ @@ -671,7 +689,7 @@ func (c *SocketConfig) Build() (*internet.SocketConfig, error) { TcpKeepAliveIdle: c.TCPKeepAliveIdle, TcpCongestion: c.TCPCongestion, TcpWindowClamp: c.TCPWindowClamp, - TcpMaxSeg: c.TCPMaxSeg, + TcpMaxSeg: c.TCPMaxSeg, TcpUserTimeout: c.TCPUserTimeout, V6Only: c.V6only, Interface: c.Interface, diff --git a/transport/internet/config.go b/transport/internet/config.go index a7ff96c65073..6725a9951d1c 100644 --- a/transport/internet/config.go +++ b/transport/internet/config.go @@ -12,6 +12,21 @@ var ( globalTransportSettings []*TransportConfig ) +var strategy = [][]byte{ + // name strategy, prefer, fallback + {0, 0, 0}, // AsIs none, /, / + {1, 0, 0}, // UseIP use, both, none + {1, 4, 0}, // UseIPv4 use, 4, none + {1, 6, 0}, // UseIPv6 use, 6, none + {1, 4, 6}, // UseIPv4v6 use, 4, 6 + {1, 6, 4}, // UseIPv6v4 use, 6, 4 + {2, 0, 0}, // ForceIP force, both, none + {2, 4, 0}, // ForceIPv4 force, 4, none + {2, 6, 0}, // ForceIPv6 force, 6, none + {2, 4, 6}, // ForceIPv4v6 force, 4, 6 + {2, 6, 4}, // ForceIPv6v4 force, 6, 4 +} + const unknownProtocol = "unknown" func transportProtocolToString(protocol TransportProtocol) string { @@ -122,3 +137,31 @@ func (c *ProxyConfig) HasTag() bool { func (m SocketConfig_TProxyMode) IsEnabled() bool { return m != SocketConfig_Off } + +func (s DomainStrategy) hasStrategy() bool { + return strategy[s][0] != 0 +} + +func (s DomainStrategy) forceIP() bool { + return strategy[s][0] == 2 +} + +func (s DomainStrategy) preferIP4() bool { + return strategy[s][1] == 4 || strategy[s][1] == 0 +} + +func (s DomainStrategy) preferIP6() bool { + return strategy[s][1] == 6 || strategy[s][1] == 0 +} + +func (s DomainStrategy) hasFallback() bool { + return strategy[s][2] != 0 +} + +func (s DomainStrategy) fallbackIP4() bool { + return strategy[s][2] == 4 +} + +func (s DomainStrategy) fallbackIP6() bool { + return strategy[s][2] == 6 +} diff --git a/transport/internet/config.pb.go b/transport/internet/config.pb.go index 1d16101c361c..ec37aebf6dce 100644 --- a/transport/internet/config.pb.go +++ b/transport/internet/config.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v4.22.0 +// protoc-gen-go v1.30.0 +// protoc v3.21.12 // source: transport/internet/config.proto package internet @@ -82,25 +82,46 @@ func (TransportProtocol) EnumDescriptor() ([]byte, []int) { type DomainStrategy int32 const ( - DomainStrategy_AS_IS DomainStrategy = 0 - DomainStrategy_USE_IP DomainStrategy = 1 - DomainStrategy_USE_IP4 DomainStrategy = 2 - DomainStrategy_USE_IP6 DomainStrategy = 3 + DomainStrategy_AS_IS DomainStrategy = 0 + DomainStrategy_USE_IP DomainStrategy = 1 + DomainStrategy_USE_IP4 DomainStrategy = 2 + DomainStrategy_USE_IP6 DomainStrategy = 3 + DomainStrategy_USE_IP46 DomainStrategy = 4 + DomainStrategy_USE_IP64 DomainStrategy = 5 + DomainStrategy_FORCE_IP DomainStrategy = 6 + DomainStrategy_FORCE_IP4 DomainStrategy = 7 + DomainStrategy_FORCE_IP6 DomainStrategy = 8 + DomainStrategy_FORCE_IP46 DomainStrategy = 9 + DomainStrategy_FORCE_IP64 DomainStrategy = 10 ) // Enum value maps for DomainStrategy. var ( DomainStrategy_name = map[int32]string{ - 0: "AS_IS", - 1: "USE_IP", - 2: "USE_IP4", - 3: "USE_IP6", + 0: "AS_IS", + 1: "USE_IP", + 2: "USE_IP4", + 3: "USE_IP6", + 4: "USE_IP46", + 5: "USE_IP64", + 6: "FORCE_IP", + 7: "FORCE_IP4", + 8: "FORCE_IP6", + 9: "FORCE_IP46", + 10: "FORCE_IP64", } DomainStrategy_value = map[string]int32{ - "AS_IS": 0, - "USE_IP": 1, - "USE_IP4": 2, - "USE_IP6": 3, + "AS_IS": 0, + "USE_IP": 1, + "USE_IP4": 2, + "USE_IP6": 3, + "USE_IP46": 4, + "USE_IP64": 5, + "FORCE_IP": 6, + "FORCE_IP4": 7, + "FORCE_IP6": 8, + "FORCE_IP46": 9, + "FORCE_IP64": 10, } ) @@ -191,7 +212,7 @@ type TransportConfig struct { // Type of network that this settings supports. // Deprecated. Use the string form below. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in transport/internet/config.proto. Protocol TransportProtocol `protobuf:"varint,1,opt,name=protocol,proto3,enum=xray.transport.internet.TransportProtocol" json:"protocol,omitempty"` // Type of network that this settings supports. ProtocolName string `protobuf:"bytes,3,opt,name=protocol_name,json=protocolName,proto3" json:"protocol_name,omitempty"` @@ -231,7 +252,7 @@ func (*TransportConfig) Descriptor() ([]byte, []int) { return file_transport_internet_config_proto_rawDescGZIP(), []int{0} } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in transport/internet/config.proto. func (x *TransportConfig) GetProtocol() TransportProtocol { if x != nil { return x.Protocol @@ -260,7 +281,7 @@ type StreamConfig struct { // Effective network. Deprecated. Use the string form below. // - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in transport/internet/config.proto. Protocol TransportProtocol `protobuf:"varint,1,opt,name=protocol,proto3,enum=xray.transport.internet.TransportProtocol" json:"protocol,omitempty"` // Effective network. ProtocolName string `protobuf:"bytes,5,opt,name=protocol_name,json=protocolName,proto3" json:"protocol_name,omitempty"` @@ -304,7 +325,7 @@ func (*StreamConfig) Descriptor() ([]byte, []int) { return file_transport_internet_config_proto_rawDescGZIP(), []int{1} } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in transport/internet/config.proto. func (x *StreamConfig) GetProtocol() TransportProtocol { if x != nil { return x.Protocol @@ -690,18 +711,24 @@ var file_transport_internet_config_proto_rawDesc = []byte{ 0x0a, 0x04, 0x4d, 0x4b, 0x43, 0x50, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x04, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x6f, 0x63, 0x6b, 0x65, - 0x74, 0x10, 0x05, 0x2a, 0x41, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, - 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x53, 0x5f, 0x49, 0x53, 0x10, 0x00, - 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, - 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, - 0x5f, 0x49, 0x50, 0x36, 0x10, 0x03, 0x42, 0x67, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x50, 0x01, 0x5a, 0x2c, 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, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0xaa, 0x02, 0x17, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x10, 0x05, 0x2a, 0xa9, 0x01, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, + 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x53, 0x5f, 0x49, 0x53, 0x10, + 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x01, 0x12, 0x0b, 0x0a, + 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, + 0x45, 0x5f, 0x49, 0x50, 0x36, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x53, 0x45, 0x5f, 0x49, + 0x50, 0x34, 0x36, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x36, + 0x34, 0x10, 0x05, 0x12, 0x0c, 0x0a, 0x08, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x10, + 0x06, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x07, + 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x10, 0x08, 0x12, + 0x0e, 0x0a, 0x0a, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x36, 0x10, 0x09, 0x12, + 0x0e, 0x0a, 0x0a, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x34, 0x10, 0x0a, 0x42, + 0x67, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x50, 0x01, + 0x5a, 0x2c, 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, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0xaa, 0x02, + 0x17, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/transport/internet/config.proto b/transport/internet/config.proto index cbfd7b54facf..64a5b0cc81f4 100644 --- a/transport/internet/config.proto +++ b/transport/internet/config.proto @@ -22,6 +22,13 @@ enum DomainStrategy { USE_IP = 1; USE_IP4 = 2; USE_IP6 = 3; + USE_IP46 = 4; + USE_IP64 = 5; + FORCE_IP = 6; + FORCE_IP4 = 7; + FORCE_IP6 = 8; + FORCE_IP46 = 9; + FORCE_IP64 = 10; } message TransportConfig { diff --git a/transport/internet/dialer.go b/transport/internet/dialer.go index d178bdcd6df5..deae4df066dc 100644 --- a/transport/internet/dialer.go +++ b/transport/internet/dialer.go @@ -78,37 +78,27 @@ func lookupIP(domain string, strategy DomainStrategy, localAddr net.Address) ([] return nil, nil } - option := dns.IPOption{ - IPv4Enable: true, - IPv6Enable: true, - FakeEnable: false, - } - - switch { - case strategy == DomainStrategy_USE_IP4 || (localAddr != nil && localAddr.Family().IsIPv4()): - option = dns.IPOption{ - IPv4Enable: true, - IPv6Enable: false, - FakeEnable: false, + ips, err := dnsClient.LookupIP(domain, dns.IPOption{ + IPv4Enable: (localAddr == nil || localAddr.Family().IsIPv4()) && strategy.preferIP4(), + IPv6Enable: (localAddr == nil || localAddr.Family().IsIPv6()) && strategy.preferIP6(), + }) + { // Resolve fallback + if (len(ips) == 0 || err != nil) && strategy.hasFallback() && localAddr == nil { + ips, err = dnsClient.LookupIP(domain, dns.IPOption{ + IPv4Enable: strategy.fallbackIP4(), + IPv6Enable: strategy.fallbackIP6(), + }) } - case strategy == DomainStrategy_USE_IP6 || (localAddr != nil && localAddr.Family().IsIPv6()): - option = dns.IPOption{ - IPv4Enable: false, - IPv6Enable: true, - FakeEnable: false, - } - case strategy == DomainStrategy_AS_IS: - return nil, nil } - return dnsClient.LookupIP(domain, option) + return ips, err } func canLookupIP(ctx context.Context, dst net.Destination, sockopt *SocketConfig) bool { if dst.Address.Family().IsIP() || dnsClient == nil { return false } - return sockopt.DomainStrategy != DomainStrategy_AS_IS + return sockopt.DomainStrategy.hasStrategy() } func redirect(ctx context.Context, dst net.Destination, obt string) net.Conn {