Browse Source

Improve resolve action

世界 8 months ago
parent
commit
6249f076c6

+ 2 - 2
docs/configuration/dns/rule_action.md

@@ -16,7 +16,7 @@ icon: material/new-box
   "server": "",
   "server": "",
   "strategy": "",
   "strategy": "",
   "disable_cache": false,
   "disable_cache": false,
-  "rewrite_ttl": 0,
+  "rewrite_ttl": null,
   "client_subnet": null
   "client_subnet": null
 }
 }
 ```
 ```
@@ -49,7 +49,7 @@ Append a `edns0-subnet` OPT extra record with the specified IP prefix to every q
 
 
 If value is an IP address instead of prefix, `/32` or `/128` will be appended automatically.
 If value is an IP address instead of prefix, `/32` or `/128` will be appended automatically.
 
 
-Will overrides `dns.client_subnet` and `servers.[].client_subnet`.
+Will overrides `dns.client_subnet`.
 
 
 ### route-options
 ### route-options
 
 

+ 2 - 2
docs/configuration/dns/rule_action.zh.md

@@ -17,7 +17,7 @@ icon: material/new-box
 
 
   "strategy": "",
   "strategy": "",
   "disable_cache": false,
   "disable_cache": false,
-  "rewrite_ttl": 0,
+  "rewrite_ttl": null,
   "client_subnet": null
   "client_subnet": null
 }
 }
 ```
 ```
@@ -50,7 +50,7 @@ icon: material/new-box
 
 
 如果值是 IP 地址而不是前缀,则会自动附加 `/32` 或 `/128`。
 如果值是 IP 地址而不是前缀,则会自动附加 `/32` 或 `/128`。
 
 
-将覆盖 `dns.client_subnet` 与 `servers.[].client_subnet`。
+将覆盖 `dns.client_subnet`.
 
 
 ### route-options
 ### route-options
 
 

+ 32 - 4
docs/configuration/route/rule_action.md

@@ -5,7 +5,10 @@ icon: material/new-box
 !!! quote "Changes in sing-box 1.12.0"
 !!! quote "Changes in sing-box 1.12.0"
 
 
     :material-plus: [tls_fragment](#tls_fragment)  
     :material-plus: [tls_fragment](#tls_fragment)  
-    :material-plus: [tls_fragment_fallback_delay](#tls_fragment_fallback_delay)
+    :material-plus: [tls_fragment_fallback_delay](#tls_fragment_fallback_delay)  
+    :material-plus: [resolve.disable_cache](#disable_cache)  
+    :material-plus: [resolve.rewrite_ttl](#rewrite_ttl)  
+    :material-plus: [resolve.client_subnet](#client_subnet)
 
 
 ## Final actions
 ## Final actions
 
 
@@ -210,19 +213,44 @@ Timeout for sniffing.
 ```json
 ```json
 {
 {
   "action": "resolve",
   "action": "resolve",
+  "server": "",
   "strategy": "",
   "strategy": "",
-  "server": ""
+  "disable_cache": false,
+  "rewrite_ttl": null,
+  "client_subnet": null
 }
 }
 ```
 ```
 
 
 `resolve` resolve request destination from domain to IP addresses.
 `resolve` resolve request destination from domain to IP addresses.
 
 
+#### server
+
+Specifies DNS server tag to use instead of selecting through DNS routing.
+
 #### strategy
 #### strategy
 
 
 DNS resolution strategy, available values are: `prefer_ipv4`, `prefer_ipv6`, `ipv4_only`, `ipv6_only`.
 DNS resolution strategy, available values are: `prefer_ipv4`, `prefer_ipv6`, `ipv4_only`, `ipv6_only`.
 
 
 `dns.strategy` will be used by default.
 `dns.strategy` will be used by default.
 
 
-#### server
+#### disable_cache
 
 
-Specifies DNS server tag to use instead of selecting through DNS routing.
+!!! question "Since sing-box 1.12.0"
+
+Disable cache and save cache in this query.
+
+#### rewrite_ttl
+
+!!! question "Since sing-box 1.12.0"
+
+Rewrite TTL in DNS responses.
+
+#### client_subnet
+
+!!! question "Since sing-box 1.12.0"
+
+Append a `edns0-subnet` OPT extra record with the specified IP prefix to every query by default.
+
+If value is an IP address instead of prefix, `/32` or `/128` will be appended automatically.
+
+Will overrides `dns.client_subnet`.

+ 28 - 3
docs/configuration/route/rule_action.zh.md

@@ -206,19 +206,44 @@ UDP 连接超时时间。
 ```json
 ```json
 {
 {
   "action": "resolve",
   "action": "resolve",
+  "server": "",
   "strategy": "",
   "strategy": "",
-  "server": ""
+  "disable_cache": false,
+  "rewrite_ttl": null,
+  "client_subnet": null
 }
 }
 ```
 ```
 
 
 `resolve` 将请求的目标从域名解析为 IP 地址。
 `resolve` 将请求的目标从域名解析为 IP 地址。
 
 
+#### server
+
+指定要使用的 DNS 服务器的标签,而不是通过 DNS 路由进行选择。
+
 #### strategy
 #### strategy
 
 
 DNS 解析策略,可用值有:`prefer_ipv4`、`prefer_ipv6`、`ipv4_only`、`ipv6_only`。
 DNS 解析策略,可用值有:`prefer_ipv4`、`prefer_ipv6`、`ipv4_only`、`ipv6_only`。
 
 
 默认使用 `dns.strategy`。
 默认使用 `dns.strategy`。
 
 
-#### server
+#### disable_cache
 
 
-指定要使用的 DNS 服务器的标签,而不是通过 DNS 路由进行选择。
+!!! question "自 sing-box 1.12.0 起"
+
+在此查询中禁用缓存。
+
+#### rewrite_ttl
+
+!!! question "自 sing-box 1.12.0 起"
+
+重写 DNS 回应中的 TTL。
+
+#### client_subnet
+
+!!! question "自 sing-box 1.12.0 起"
+
+默认情况下,将带有指定 IP 前缀的 `edns0-subnet` OPT 附加记录附加到每个查询。
+
+如果值是 IP 地址而不是前缀,则会自动附加 `/32` 或 `/128`。
+
+将覆盖 `dns.client_subnet`.

+ 5 - 2
option/rule_action.go

@@ -288,6 +288,9 @@ type RouteActionSniff struct {
 }
 }
 
 
 type RouteActionResolve struct {
 type RouteActionResolve struct {
-	Strategy DomainStrategy `json:"strategy,omitempty"`
-	Server   string         `json:"server,omitempty"`
+	Server       string                `json:"server,omitempty"`
+	Strategy     DomainStrategy        `json:"strategy,omitempty"`
+	DisableCache bool                  `json:"disable_cache,omitempty"`
+	RewriteTTL   *uint32               `json:"rewrite_ttl,omitempty"`
+	ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
 }
 }

+ 5 - 2
route/route.go

@@ -662,8 +662,11 @@ func (r *Router) actionResolve(ctx context.Context, metadata *adapter.InboundCon
 			}
 			}
 		}
 		}
 		addresses, err := r.dns.Lookup(adapter.WithContext(ctx, metadata), metadata.Destination.Fqdn, adapter.DNSQueryOptions{
 		addresses, err := r.dns.Lookup(adapter.WithContext(ctx, metadata), metadata.Destination.Fqdn, adapter.DNSQueryOptions{
-			Transport: transport,
-			Strategy:  action.Strategy,
+			Transport:    transport,
+			Strategy:     action.Strategy,
+			DisableCache: action.DisableCache,
+			RewriteTTL:   action.RewriteTTL,
+			ClientSubnet: action.ClientSubnet,
 		})
 		})
 		if err != nil {
 		if err != nil {
 			return err
 			return err

+ 29 - 11
route/rule/rule_action.go

@@ -88,8 +88,11 @@ func NewRuleAction(ctx context.Context, logger logger.ContextLogger, action opti
 		return sniffAction, sniffAction.build()
 		return sniffAction, sniffAction.build()
 	case C.RuleActionTypeResolve:
 	case C.RuleActionTypeResolve:
 		return &RuleActionResolve{
 		return &RuleActionResolve{
-			Strategy: C.DomainStrategy(action.ResolveOptions.Strategy),
-			Server:   action.ResolveOptions.Server,
+			Server:       action.ResolveOptions.Server,
+			Strategy:     C.DomainStrategy(action.ResolveOptions.Strategy),
+			DisableCache: action.ResolveOptions.DisableCache,
+			RewriteTTL:   action.ResolveOptions.RewriteTTL,
+			ClientSubnet: action.ResolveOptions.ClientSubnet.Build(netip.Prefix{}),
 		}, nil
 		}, nil
 	default:
 	default:
 		panic(F.ToString("unknown rule action: ", action.Action))
 		panic(F.ToString("unknown rule action: ", action.Action))
@@ -376,8 +379,11 @@ func (r *RuleActionSniff) String() string {
 }
 }
 
 
 type RuleActionResolve struct {
 type RuleActionResolve struct {
-	Strategy C.DomainStrategy
-	Server   string
+	Server       string
+	Strategy     C.DomainStrategy
+	DisableCache bool
+	RewriteTTL   *uint32
+	ClientSubnet netip.Prefix
 }
 }
 
 
 func (r *RuleActionResolve) Type() string {
 func (r *RuleActionResolve) Type() string {
@@ -385,13 +391,25 @@ func (r *RuleActionResolve) Type() string {
 }
 }
 
 
 func (r *RuleActionResolve) String() string {
 func (r *RuleActionResolve) String() string {
-	if r.Strategy == C.DomainStrategyAsIS && r.Server == "" {
-		return F.ToString("resolve")
-	} else if r.Strategy != C.DomainStrategyAsIS && r.Server == "" {
-		return F.ToString("resolve(", option.DomainStrategy(r.Strategy).String(), ")")
-	} else if r.Strategy == C.DomainStrategyAsIS && r.Server != "" {
-		return F.ToString("resolve(", r.Server, ")")
+	var options []string
+	if r.Server != "" {
+		options = append(options, r.Server)
+	}
+	if r.Strategy != C.DomainStrategyAsIS {
+		options = append(options, F.ToString(option.DomainStrategy(r.Strategy)))
+	}
+	if r.DisableCache {
+		options = append(options, "disable_cache")
+	}
+	if r.RewriteTTL != nil {
+		options = append(options, F.ToString("rewrite_ttl=", *r.RewriteTTL))
+	}
+	if r.ClientSubnet.IsValid() {
+		options = append(options, F.ToString("client_subnet=", r.ClientSubnet))
+	}
+	if len(options) == 0 {
+		return "resolve"
 	} else {
 	} else {
-		return F.ToString("resolve(", option.DomainStrategy(r.Strategy).String(), ",", r.Server, ")")
+		return F.ToString("resolve(", strings.Join(options, ","), ")")
 	}
 	}
 }
 }