diff --git a/infra/conf/transport_internet.go b/infra/conf/transport_internet.go index 9e10feed..e1471bde 100644 --- a/infra/conf/transport_internet.go +++ b/infra/conf/transport_internet.go @@ -654,12 +654,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{ diff --git a/transport/internet/config.go b/transport/internet/config.go index a7ff96c6..6725a995 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 9a5f78e8..9636bfb4 100644 --- a/transport/internet/config.pb.go +++ b/transport/internet/config.pb.go @@ -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, } ) @@ -710,18 +731,24 @@ var file_transport_internet_config_proto_rawDesc = []byte{ 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, + 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 550d00ec..f596d19f 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 d178bdcd..deae4df0 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, + 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(), + }) + } } - switch { - case strategy == DomainStrategy_USE_IP4 || (localAddr != nil && localAddr.Family().IsIPv4()): - option = dns.IPOption{ - IPv4Enable: true, - IPv6Enable: false, - FakeEnable: false, - } - 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 {