Browse Source

Freedom xdomain strategy (#2719)

* 统一 `domainStrategy` 行为.

* aliases NG.

* 化简.

* 调整.

* Let it crash.

* Update proto

---------

Co-authored-by: rui0572 <[email protected]>
yuhan6665 1 year ago
parent
commit
d9fd3f8eb1
70 changed files with 201 additions and 117 deletions
  1. 1 1
      app/commander/config.pb.go
  2. 1 1
      app/dispatcher/config.pb.go
  3. 1 1
      app/dns/config.pb.go
  4. 1 1
      app/dns/fakedns/fakedns.pb.go
  5. 1 1
      app/log/command/config.pb.go
  6. 1 1
      app/log/config.pb.go
  7. 1 1
      app/metrics/config.pb.go
  8. 1 1
      app/observatory/command/command.pb.go
  9. 1 1
      app/observatory/config.pb.go
  10. 1 1
      app/policy/config.pb.go
  11. 1 1
      app/proxyman/command/command.pb.go
  12. 1 1
      app/proxyman/config.pb.go
  13. 1 1
      app/reverse/config.pb.go
  14. 1 1
      app/router/command/command.pb.go
  15. 1 1
      app/router/config.pb.go
  16. 1 1
      app/stats/command/command.pb.go
  17. 1 1
      app/stats/config.pb.go
  18. 1 1
      common/log/log.pb.go
  19. 1 1
      common/net/address.pb.go
  20. 1 1
      common/net/destination.pb.go
  21. 1 1
      common/net/network.pb.go
  22. 1 1
      common/net/port.pb.go
  23. 1 1
      common/protocol/headers.pb.go
  24. 1 1
      common/protocol/server_spec.pb.go
  25. 1 1
      common/protocol/user.pb.go
  26. 1 1
      common/serial/typed_message.pb.go
  27. 1 1
      core/config.pb.go
  28. 21 4
      infra/conf/freedom.go
  29. 1 1
      proxy/blackhole/config.pb.go
  30. 1 1
      proxy/dns/config.pb.go
  31. 1 1
      proxy/dokodemo/config.pb.go
  32. 41 2
      proxy/freedom/config.go
  33. 53 26
      proxy/freedom/config.pb.go
  34. 7 0
      proxy/freedom/config.proto
  35. 14 20
      proxy/freedom/freedom.go
  36. 1 1
      proxy/http/config.pb.go
  37. 1 1
      proxy/loopback/config.pb.go
  38. 1 1
      proxy/shadowsocks/config.pb.go
  39. 1 1
      proxy/shadowsocks_2022/config.pb.go
  40. 1 1
      proxy/socks/config.pb.go
  41. 1 1
      proxy/trojan/config.pb.go
  42. 1 1
      proxy/vless/account.pb.go
  43. 1 1
      proxy/vless/encoding/addons.pb.go
  44. 1 1
      proxy/vless/inbound/config.pb.go
  45. 1 1
      proxy/vless/outbound/config.pb.go
  46. 1 1
      proxy/vmess/account.pb.go
  47. 1 1
      proxy/vmess/inbound/config.pb.go
  48. 1 1
      proxy/vmess/outbound/config.pb.go
  49. 1 1
      proxy/wireguard/config.pb.go
  50. 1 1
      transport/global/config.pb.go
  51. 1 1
      transport/internet/config.pb.go
  52. 1 1
      transport/internet/domainsocket/config.pb.go
  53. 1 1
      transport/internet/grpc/config.pb.go
  54. 1 1
      transport/internet/grpc/encoding/stream.pb.go
  55. 1 1
      transport/internet/headers/dns/config.pb.go
  56. 1 1
      transport/internet/headers/http/config.pb.go
  57. 1 1
      transport/internet/headers/noop/config.pb.go
  58. 1 1
      transport/internet/headers/srtp/config.pb.go
  59. 1 1
      transport/internet/headers/tls/config.pb.go
  60. 1 1
      transport/internet/headers/utp/config.pb.go
  61. 1 1
      transport/internet/headers/wechat/config.pb.go
  62. 1 1
      transport/internet/headers/wireguard/config.pb.go
  63. 1 1
      transport/internet/http/config.pb.go
  64. 1 1
      transport/internet/kcp/config.pb.go
  65. 1 1
      transport/internet/quic/config.pb.go
  66. 1 1
      transport/internet/reality/config.pb.go
  67. 1 1
      transport/internet/tcp/config.pb.go
  68. 1 1
      transport/internet/tls/config.pb.go
  69. 1 1
      transport/internet/udp/config.pb.go
  70. 1 1
      transport/internet/websocket/config.pb.go

+ 1 - 1
app/commander/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/commander/config.proto
 

+ 1 - 1
app/dispatcher/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/dispatcher/config.proto
 

+ 1 - 1
app/dns/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/dns/config.proto
 

+ 1 - 1
app/dns/fakedns/fakedns.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/dns/fakedns/fakedns.proto
 

+ 1 - 1
app/log/command/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/log/command/config.proto
 

+ 1 - 1
app/log/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/log/config.proto
 

+ 1 - 1
app/metrics/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/metrics/config.proto
 

+ 1 - 1
app/observatory/command/command.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/observatory/command/command.proto
 

+ 1 - 1
app/observatory/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/observatory/config.proto
 

+ 1 - 1
app/policy/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/policy/config.proto
 

+ 1 - 1
app/proxyman/command/command.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/proxyman/command/command.proto
 

+ 1 - 1
app/proxyman/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/proxyman/config.proto
 

+ 1 - 1
app/reverse/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/reverse/config.proto
 

+ 1 - 1
app/router/command/command.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/router/command/command.proto
 

+ 1 - 1
app/router/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/router/config.proto
 

+ 1 - 1
app/stats/command/command.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/stats/command/command.proto
 

+ 1 - 1
app/stats/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: app/stats/config.proto
 

+ 1 - 1
common/log/log.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: common/log/log.proto
 

+ 1 - 1
common/net/address.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: common/net/address.proto
 

+ 1 - 1
common/net/destination.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: common/net/destination.proto
 

+ 1 - 1
common/net/network.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: common/net/network.proto
 

+ 1 - 1
common/net/port.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: common/net/port.proto
 

+ 1 - 1
common/protocol/headers.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: common/protocol/headers.proto
 

+ 1 - 1
common/protocol/server_spec.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: common/protocol/server_spec.proto
 

+ 1 - 1
common/protocol/user.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: common/protocol/user.proto
 

+ 1 - 1
common/serial/typed_message.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: common/serial/typed_message.proto
 

+ 1 - 1
core/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: core/config.proto
 

+ 21 - 4
infra/conf/freedom.go

@@ -28,14 +28,31 @@ type Fragment struct {
 // Build implements Buildable
 func (c *FreedomConfig) Build() (proto.Message, error) {
 	config := new(freedom.Config)
-	config.DomainStrategy = freedom.Config_AS_IS
 	switch strings.ToLower(c.DomainStrategy) {
-	case "useip", "use_ip", "use-ip":
+	case "asis", "":
+		config.DomainStrategy = freedom.Config_AS_IS
+	case "useip":
 		config.DomainStrategy = freedom.Config_USE_IP
-	case "useip4", "useipv4", "use_ip4", "use_ipv4", "use_ip_v4", "use-ip4", "use-ipv4", "use-ip-v4":
+	case "useipv4":
 		config.DomainStrategy = freedom.Config_USE_IP4
-	case "useip6", "useipv6", "use_ip6", "use_ipv6", "use_ip_v6", "use-ip6", "use-ipv6", "use-ip-v6":
+	case "useipv6":
 		config.DomainStrategy = freedom.Config_USE_IP6
+	case "useipv4v6":
+		config.DomainStrategy = freedom.Config_USE_IP46
+	case "useipv6v4":
+		config.DomainStrategy = freedom.Config_USE_IP64
+	case "forceip":
+		config.DomainStrategy = freedom.Config_FORCE_IP
+	case "forceipv4":
+		config.DomainStrategy = freedom.Config_FORCE_IP4
+	case "forceipv6":
+		config.DomainStrategy = freedom.Config_FORCE_IP6
+	case "forceipv4v6":
+		config.DomainStrategy = freedom.Config_FORCE_IP46
+	case "forceipv6v4":
+		config.DomainStrategy = freedom.Config_FORCE_IP64
+	default:
+		return nil, newError("unsupported domain strategy: ", c.DomainStrategy)
 	}
 
 	if c.Fragment != nil {

+ 1 - 1
proxy/blackhole/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/blackhole/config.proto
 

+ 1 - 1
proxy/dns/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/dns/config.proto
 

+ 1 - 1
proxy/dokodemo/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/dokodemo/config.proto
 

+ 41 - 2
proxy/freedom/config.go

@@ -1,5 +1,44 @@
 package freedom
 
-func (c *Config) useIP() bool {
-	return c.DomainStrategy == Config_USE_IP || c.DomainStrategy == Config_USE_IP4 || c.DomainStrategy == Config_USE_IP6
+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
+}
+
+func (c *Config) hasStrategy() bool {
+	return strategy[c.DomainStrategy][0] != 0
+}
+
+func (c *Config) forceIP() bool {
+	return strategy[c.DomainStrategy][0] == 2
+}
+
+func (c *Config) preferIP4() bool {
+	return strategy[c.DomainStrategy][1] == 4 || strategy[c.DomainStrategy][1] == 0
+}
+
+func (c *Config) preferIP6() bool {
+	return strategy[c.DomainStrategy][1] == 6 || strategy[c.DomainStrategy][1] == 0
+}
+
+func (c *Config) hasFallback() bool {
+	return strategy[c.DomainStrategy][2] != 0
+}
+
+func (c *Config) fallbackIP4() bool {
+	return strategy[c.DomainStrategy][2] == 4
+}
+
+func (c *Config) fallbackIP6() bool {
+	return strategy[c.DomainStrategy][2] == 6
 }

+ 53 - 26
proxy/freedom/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/freedom/config.proto
 
@@ -24,25 +24,46 @@ const (
 type Config_DomainStrategy int32
 
 const (
-	Config_AS_IS   Config_DomainStrategy = 0
-	Config_USE_IP  Config_DomainStrategy = 1
-	Config_USE_IP4 Config_DomainStrategy = 2
-	Config_USE_IP6 Config_DomainStrategy = 3
+	Config_AS_IS      Config_DomainStrategy = 0
+	Config_USE_IP     Config_DomainStrategy = 1
+	Config_USE_IP4    Config_DomainStrategy = 2
+	Config_USE_IP6    Config_DomainStrategy = 3
+	Config_USE_IP46   Config_DomainStrategy = 4
+	Config_USE_IP64   Config_DomainStrategy = 5
+	Config_FORCE_IP   Config_DomainStrategy = 6
+	Config_FORCE_IP4  Config_DomainStrategy = 7
+	Config_FORCE_IP6  Config_DomainStrategy = 8
+	Config_FORCE_IP46 Config_DomainStrategy = 9
+	Config_FORCE_IP64 Config_DomainStrategy = 10
 )
 
 // Enum value maps for Config_DomainStrategy.
 var (
 	Config_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",
 	}
 	Config_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,
 	}
 )
 
@@ -314,7 +335,7 @@ var file_proxy_freedom_config_proto_rawDesc = []byte{
 	0x6c, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x69, 0x6e, 0x74,
 	0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x69, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x74, 0x65,
 	0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b,
-	0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x61, 0x78, 0x22, 0xf2, 0x02, 0x0a, 0x06,
+	0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x61, 0x78, 0x22, 0xdb, 0x03, 0x0a, 0x06,
 	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x52, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
 	0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
 	0x29, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x66, 0x72, 0x65,
@@ -333,18 +354,24 @@ var file_proxy_freedom_config_proto_rawDesc = []byte{
 	0x76, 0x65, 0x6c, 0x12, 0x38, 0x0a, 0x08, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x18,
 	0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f,
 	0x78, 0x79, 0x2e, 0x66, 0x72, 0x65, 0x65, 0x64, 0x6f, 0x6d, 0x2e, 0x46, 0x72, 0x61, 0x67, 0x6d,
-	0x65, 0x6e, 0x74, 0x52, 0x08, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x22, 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, 0x58, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f,
-	0x78, 0x79, 0x2e, 0x66, 0x72, 0x65, 0x65, 0x64, 0x6f, 0x6d, 0x50, 0x01, 0x5a, 0x27, 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, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x66, 0x72,
-	0x65, 0x65, 0x64, 0x6f, 0x6d, 0xaa, 0x02, 0x12, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x50, 0x72, 0x6f,
-	0x78, 0x79, 0x2e, 0x46, 0x72, 0x65, 0x65, 0x64, 0x6f, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x33,
+	0x65, 0x6e, 0x74, 0x52, 0x08, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x22, 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, 0x58, 0x0a, 0x16, 0x63, 0x6f, 0x6d,
+	0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x66, 0x72, 0x65, 0x65,
+	0x64, 0x6f, 0x6d, 0x50, 0x01, 0x5a, 0x27, 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, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x66, 0x72, 0x65, 0x65, 0x64, 0x6f, 0x6d, 0xaa, 0x02,
+	0x12, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x46, 0x72, 0x65, 0x65,
+	0x64, 0x6f, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (

+ 7 - 0
proxy/freedom/config.proto

@@ -27,6 +27,13 @@ message Config {
     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;
   }
   DomainStrategy domain_strategy = 1;
   uint32 timeout = 2 [deprecated = true];

+ 14 - 20
proxy/freedom/freedom.go

@@ -73,26 +73,18 @@ func (h *Handler) policy() policy.Session {
 }
 
 func (h *Handler) resolveIP(ctx context.Context, domain string, localAddr net.Address) net.Address {
-	var option dns.IPOption = dns.IPOption{
-		IPv4Enable: true,
-		IPv6Enable: true,
-		FakeEnable: false,
-	}
-	if h.config.DomainStrategy == Config_USE_IP4 || (localAddr != nil && localAddr.Family().IsIPv4()) {
-		option = dns.IPOption{
-			IPv4Enable: true,
-			IPv6Enable: false,
-			FakeEnable: false,
-		}
-	} else if h.config.DomainStrategy == Config_USE_IP6 || (localAddr != nil && localAddr.Family().IsIPv6()) {
-		option = dns.IPOption{
-			IPv4Enable: false,
-			IPv6Enable: true,
-			FakeEnable: false,
+	ips, err := h.dns.LookupIP(domain, dns.IPOption{
+		IPv4Enable: (localAddr == nil || localAddr.Family().IsIPv4()) && h.config.preferIP4(),
+		IPv6Enable: (localAddr == nil || localAddr.Family().IsIPv6()) && h.config.preferIP6(),
+	})
+	{ // Resolve fallback
+		if (len(ips) == 0 || err != nil) && h.config.hasFallback() && localAddr == nil {
+			ips, err = h.dns.LookupIP(domain, dns.IPOption{
+				IPv4Enable: h.config.fallbackIP4(),
+				IPv6Enable: h.config.fallbackIP6(),
+			})
 		}
 	}
-
-	ips, err := h.dns.LookupIP(domain, option)
 	if err != nil {
 		newError("failed to get IP address for domain ", domain).Base(err).WriteToLog(session.ExportIDToError(ctx))
 	}
@@ -142,7 +134,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
 	var conn stat.Connection
 	err := retry.ExponentialBackoff(5, 100).On(func() error {
 		dialDest := destination
-		if h.config.useIP() && dialDest.Address.Family().IsDomain() {
+		if h.config.hasStrategy() && dialDest.Address.Family().IsDomain() {
 			ip := h.resolveIP(ctx, dialDest.Address.Domain(), dialer.Address())
 			if ip != nil {
 				dialDest = net.Destination{
@@ -151,6 +143,8 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
 					Port:    dialDest.Port,
 				}
 				newError("dialing to ", dialDest).WriteToLog(session.ExportIDToError(ctx))
+			} else if h.config.forceIP() {
+				return dns.ErrEmptyResponse
 			}
 		}
 
@@ -325,7 +319,7 @@ func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
 			if w.UDPOverride.Port != 0 {
 				b.UDP.Port = w.UDPOverride.Port
 			}
-			if w.Handler.config.useIP() && b.UDP.Address.Family().IsDomain() {
+			if w.Handler.config.hasStrategy() && b.UDP.Address.Family().IsDomain() {
 				ip := w.Handler.resolveIP(w.Context, b.UDP.Address.Domain(), nil)
 				if ip != nil {
 					b.UDP.Address = ip

+ 1 - 1
proxy/http/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/http/config.proto
 

+ 1 - 1
proxy/loopback/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/loopback/config.proto
 

+ 1 - 1
proxy/shadowsocks/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/shadowsocks/config.proto
 

+ 1 - 1
proxy/shadowsocks_2022/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/shadowsocks_2022/config.proto
 

+ 1 - 1
proxy/socks/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/socks/config.proto
 

+ 1 - 1
proxy/trojan/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/trojan/config.proto
 

+ 1 - 1
proxy/vless/account.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/vless/account.proto
 

+ 1 - 1
proxy/vless/encoding/addons.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/vless/encoding/addons.proto
 

+ 1 - 1
proxy/vless/inbound/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/vless/inbound/config.proto
 

+ 1 - 1
proxy/vless/outbound/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/vless/outbound/config.proto
 

+ 1 - 1
proxy/vmess/account.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/vmess/account.proto
 

+ 1 - 1
proxy/vmess/inbound/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/vmess/inbound/config.proto
 

+ 1 - 1
proxy/vmess/outbound/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/vmess/outbound/config.proto
 

+ 1 - 1
proxy/wireguard/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: proxy/wireguard/config.proto
 

+ 1 - 1
transport/global/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/global/config.proto
 

+ 1 - 1
transport/internet/config.pb.go

@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.31.0
-// 	protoc        v4.24.1
+// 	protoc        v4.23.1
 // source: transport/internet/config.proto
 
 package internet

+ 1 - 1
transport/internet/domainsocket/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/domainsocket/config.proto
 

+ 1 - 1
transport/internet/grpc/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/grpc/config.proto
 

+ 1 - 1
transport/internet/grpc/encoding/stream.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/grpc/encoding/stream.proto
 

+ 1 - 1
transport/internet/headers/dns/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/headers/dns/config.proto
 

+ 1 - 1
transport/internet/headers/http/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/headers/http/config.proto
 

+ 1 - 1
transport/internet/headers/noop/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/headers/noop/config.proto
 

+ 1 - 1
transport/internet/headers/srtp/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/headers/srtp/config.proto
 

+ 1 - 1
transport/internet/headers/tls/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/headers/tls/config.proto
 

+ 1 - 1
transport/internet/headers/utp/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/headers/utp/config.proto
 

+ 1 - 1
transport/internet/headers/wechat/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/headers/wechat/config.proto
 

+ 1 - 1
transport/internet/headers/wireguard/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/headers/wireguard/config.proto
 

+ 1 - 1
transport/internet/http/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/http/config.proto
 

+ 1 - 1
transport/internet/kcp/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/kcp/config.proto
 

+ 1 - 1
transport/internet/quic/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/quic/config.proto
 

+ 1 - 1
transport/internet/reality/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/reality/config.proto
 

+ 1 - 1
transport/internet/tcp/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/tcp/config.proto
 

+ 1 - 1
transport/internet/tls/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/tls/config.proto
 

+ 1 - 1
transport/internet/udp/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/udp/config.proto
 

+ 1 - 1
transport/internet/websocket/config.pb.go

@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.30.0
+// 	protoc-gen-go v1.31.0
 // 	protoc        v4.23.1
 // source: transport/internet/websocket/config.proto