mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-07-23 14:34:08 +08:00
Add options to custom DNS query timeout
This commit is contained in:
parent
70371c3cbe
commit
0d8c15932f
@ -3,6 +3,7 @@ package adapter
|
||||
import (
|
||||
"context"
|
||||
"net/netip"
|
||||
"time"
|
||||
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
@ -36,6 +37,7 @@ type DNSQueryOptions struct {
|
||||
Transport DNSTransport
|
||||
Strategy C.DomainStrategy
|
||||
LookupStrategy C.DomainStrategy
|
||||
Timeout time.Duration
|
||||
DisableCache bool
|
||||
RewriteTTL *uint32
|
||||
ClientSubnet netip.Prefix
|
||||
@ -53,6 +55,7 @@ func DNSQueryOptionsFrom(ctx context.Context, options *option.DomainResolveOptio
|
||||
return &DNSQueryOptions{
|
||||
Transport: transport,
|
||||
Strategy: C.DomainStrategy(options.Strategy),
|
||||
Timeout: time.Duration(options.Timeout),
|
||||
DisableCache: options.DisableCache,
|
||||
RewriteTTL: options.RewriteTTL,
|
||||
ClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
|
||||
@ -70,6 +73,7 @@ type DNSTransport interface {
|
||||
Type() string
|
||||
Tag() string
|
||||
Dependencies() []string
|
||||
HasDetour() bool
|
||||
Exchange(ctx context.Context, message *dns.Msg) (*dns.Msg, error)
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,7 @@ func NewWithOptions(options Options) (N.Dialer, error) {
|
||||
dnsQueryOptions = adapter.DNSQueryOptions{
|
||||
Transport: transport,
|
||||
Strategy: strategy,
|
||||
Timeout: time.Duration(dialOptions.DomainResolver.Timeout),
|
||||
DisableCache: dialOptions.DomainResolver.DisableCache,
|
||||
RewriteTTL: dialOptions.DomainResolver.RewriteTTL,
|
||||
ClientSubnet: dialOptions.DomainResolver.ClientSubnet.Build(netip.Prefix{}),
|
||||
|
@ -9,6 +9,7 @@ const (
|
||||
TCPTimeout = 15 * time.Second
|
||||
ReadPayloadTimeout = 300 * time.Millisecond
|
||||
DNSTimeout = 10 * time.Second
|
||||
DirectDNSTimeout = 5 * time.Second
|
||||
UDPTimeout = 5 * time.Minute
|
||||
DefaultURLTestInterval = 3 * time.Minute
|
||||
DefaultURLTestIdleTimeout = 30 * time.Minute
|
||||
|
@ -30,7 +30,6 @@ var (
|
||||
var _ adapter.DNSClient = (*Client)(nil)
|
||||
|
||||
type Client struct {
|
||||
timeout time.Duration
|
||||
disableCache bool
|
||||
disableExpire bool
|
||||
independentCache bool
|
||||
@ -43,7 +42,6 @@ type Client struct {
|
||||
}
|
||||
|
||||
type ClientOptions struct {
|
||||
Timeout time.Duration
|
||||
DisableCache bool
|
||||
DisableExpire bool
|
||||
IndependentCache bool
|
||||
@ -55,7 +53,6 @@ type ClientOptions struct {
|
||||
|
||||
func NewClient(options ClientOptions) *Client {
|
||||
client := &Client{
|
||||
timeout: options.Timeout,
|
||||
disableCache: options.DisableCache,
|
||||
disableExpire: options.DisableExpire,
|
||||
independentCache: options.IndependentCache,
|
||||
@ -63,9 +60,6 @@ func NewClient(options ClientOptions) *Client {
|
||||
initRDRCFunc: options.RDRC,
|
||||
logger: options.Logger,
|
||||
}
|
||||
if client.timeout == 0 {
|
||||
client.timeout = C.DNSTimeout
|
||||
}
|
||||
cacheCapacity := options.CacheCapacity
|
||||
if cacheCapacity < 1024 {
|
||||
cacheCapacity = 1024
|
||||
@ -153,7 +147,15 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m
|
||||
return nil, ErrResponseRejectedCached
|
||||
}
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(ctx, c.timeout)
|
||||
timeout := options.Timeout
|
||||
if timeout == 0 {
|
||||
if transport.HasDetour() {
|
||||
timeout = C.DNSTimeout
|
||||
} else {
|
||||
timeout = C.DirectDNSTimeout
|
||||
}
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(ctx, timeout)
|
||||
response, err := transport.Exchange(ctx, message)
|
||||
cancel()
|
||||
if err != nil {
|
||||
|
@ -158,6 +158,9 @@ func (r *Router) matchDNS(ctx context.Context, allowFakeIP bool, ruleIndex int,
|
||||
if action.Strategy != C.DomainStrategyAsIS {
|
||||
options.Strategy = action.Strategy
|
||||
}
|
||||
if action.Timeout > 0 {
|
||||
options.Timeout = action.Timeout
|
||||
}
|
||||
if isFakeIP || action.DisableCache {
|
||||
options.DisableCache = true
|
||||
}
|
||||
@ -180,6 +183,9 @@ func (r *Router) matchDNS(ctx context.Context, allowFakeIP bool, ruleIndex int,
|
||||
if action.Strategy != C.DomainStrategyAsIS {
|
||||
options.Strategy = action.Strategy
|
||||
}
|
||||
if action.Timeout > 0 {
|
||||
options.Timeout = action.Timeout
|
||||
}
|
||||
if action.DisableCache {
|
||||
options.DisableCache = true
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ type Transport struct {
|
||||
dns.TransportAdapter
|
||||
ctx context.Context
|
||||
dialer N.Dialer
|
||||
hasDetour bool
|
||||
logger logger.ContextLogger
|
||||
networkManager adapter.NetworkManager
|
||||
interfaceName string
|
||||
@ -59,6 +60,7 @@ func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, opt
|
||||
TransportAdapter: dns.NewTransportAdapterWithLocalOptions(C.DNSTypeDHCP, tag, options.LocalDNSServerOptions),
|
||||
ctx: ctx,
|
||||
dialer: transportDialer,
|
||||
hasDetour: options.Detour != "",
|
||||
logger: logger,
|
||||
networkManager: service.FromContext[adapter.NetworkManager](ctx),
|
||||
interfaceName: options.Interface,
|
||||
@ -89,6 +91,10 @@ func (t *Transport) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Transport) HasDetour() bool {
|
||||
return t.hasDetour
|
||||
}
|
||||
|
||||
func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
||||
err := t.fetchServers()
|
||||
if err != nil {
|
||||
|
@ -14,6 +14,7 @@ type TransportAdapter struct {
|
||||
transportType string
|
||||
transportTag string
|
||||
dependencies []string
|
||||
hasDetour bool
|
||||
strategy C.DomainStrategy
|
||||
clientSubnet netip.Prefix
|
||||
}
|
||||
@ -35,6 +36,7 @@ func NewTransportAdapterWithLocalOptions(transportType string, transportTag stri
|
||||
transportType: transportType,
|
||||
transportTag: transportTag,
|
||||
dependencies: dependencies,
|
||||
hasDetour: localOptions.Detour != "",
|
||||
strategy: C.DomainStrategy(localOptions.LegacyStrategy),
|
||||
clientSubnet: localOptions.LegacyClientSubnet,
|
||||
}
|
||||
@ -69,6 +71,10 @@ func (a *TransportAdapter) Dependencies() []string {
|
||||
return a.dependencies
|
||||
}
|
||||
|
||||
func (a *TransportAdapter) HasDetour() bool {
|
||||
return a.hasDetour
|
||||
}
|
||||
|
||||
func (a *TransportAdapter) LegacyStrategy() C.DomainStrategy {
|
||||
return a.strategy
|
||||
}
|
||||
|
@ -91,6 +91,7 @@ type DialerOptions struct {
|
||||
type _DomainResolveOptions struct {
|
||||
Server string `json:"server"`
|
||||
Strategy DomainStrategy `json:"strategy,omitempty"`
|
||||
Timeout badoption.Duration `json:"timeout,omitempty"`
|
||||
DisableCache bool `json:"disable_cache,omitempty"`
|
||||
RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
|
||||
ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
|
||||
@ -102,6 +103,7 @@ func (o DomainResolveOptions) MarshalJSON() ([]byte, error) {
|
||||
if o.Server == "" {
|
||||
return []byte("{}"), nil
|
||||
} else if o.Strategy == DomainStrategy(C.DomainStrategyAsIS) &&
|
||||
o.Timeout == 0 &&
|
||||
!o.DisableCache &&
|
||||
o.RewriteTTL == nil &&
|
||||
o.ClientSubnet == nil {
|
||||
|
@ -180,6 +180,7 @@ func (r *RouteOptionsActionOptions) UnmarshalJSON(data []byte) error {
|
||||
type DNSRouteActionOptions struct {
|
||||
Server string `json:"server,omitempty"`
|
||||
Strategy DomainStrategy `json:"strategy,omitempty"`
|
||||
Timeout badoption.Duration `json:"timeout,omitempty"`
|
||||
DisableCache bool `json:"disable_cache,omitempty"`
|
||||
RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
|
||||
ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
|
||||
@ -187,6 +188,7 @@ type DNSRouteActionOptions struct {
|
||||
|
||||
type _DNSRouteOptionsActionOptions struct {
|
||||
Strategy DomainStrategy `json:"strategy,omitempty"`
|
||||
Timeout badoption.Duration `json:"timeout,omitempty"`
|
||||
DisableCache bool `json:"disable_cache,omitempty"`
|
||||
RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
|
||||
ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
|
||||
|
@ -76,6 +76,7 @@ func NewNetworkManager(ctx context.Context, logger logger.ContextLogger, routeOp
|
||||
DomainResolver: defaultDomainResolver.Server,
|
||||
DomainResolveOptions: adapter.DNSQueryOptions{
|
||||
Strategy: C.DomainStrategy(defaultDomainResolver.Strategy),
|
||||
Timeout: time.Duration(defaultDomainResolver.Timeout),
|
||||
DisableCache: defaultDomainResolver.DisableCache,
|
||||
RewriteTTL: defaultDomainResolver.RewriteTTL,
|
||||
ClientSubnet: defaultDomainResolver.ClientSubnet.Build(netip.Prefix{}),
|
||||
|
@ -666,6 +666,7 @@ func (r *Router) actionResolve(ctx context.Context, metadata *adapter.InboundCon
|
||||
addresses, err := r.dns.Lookup(adapter.WithContext(ctx, metadata), metadata.Destination.Fqdn, adapter.DNSQueryOptions{
|
||||
Transport: transport,
|
||||
Strategy: action.Strategy,
|
||||
Timeout: action.Timeout,
|
||||
DisableCache: action.DisableCache,
|
||||
RewriteTTL: action.RewriteTTL,
|
||||
ClientSubnet: action.ClientSubnet,
|
||||
|
@ -113,6 +113,7 @@ func NewDNSRuleAction(logger logger.ContextLogger, action option.DNSRuleAction)
|
||||
Server: action.RouteOptions.Server,
|
||||
RuleActionDNSRouteOptions: RuleActionDNSRouteOptions{
|
||||
Strategy: C.DomainStrategy(action.RouteOptions.Strategy),
|
||||
Timeout: time.Duration(action.RouteOptions.Timeout),
|
||||
DisableCache: action.RouteOptions.DisableCache,
|
||||
RewriteTTL: action.RouteOptions.RewriteTTL,
|
||||
ClientSubnet: netip.Prefix(common.PtrValueOrDefault(action.RouteOptions.ClientSubnet)),
|
||||
@ -121,6 +122,7 @@ func NewDNSRuleAction(logger logger.ContextLogger, action option.DNSRuleAction)
|
||||
case C.RuleActionTypeRouteOptions:
|
||||
return &RuleActionDNSRouteOptions{
|
||||
Strategy: C.DomainStrategy(action.RouteOptionsOptions.Strategy),
|
||||
Timeout: time.Duration(action.RouteOptionsOptions.Timeout),
|
||||
DisableCache: action.RouteOptionsOptions.DisableCache,
|
||||
RewriteTTL: action.RouteOptionsOptions.RewriteTTL,
|
||||
ClientSubnet: netip.Prefix(common.PtrValueOrDefault(action.RouteOptionsOptions.ClientSubnet)),
|
||||
@ -235,20 +237,13 @@ func (r *RuleActionDNSRoute) Type() string {
|
||||
func (r *RuleActionDNSRoute) String() string {
|
||||
var descriptions []string
|
||||
descriptions = append(descriptions, r.Server)
|
||||
if r.DisableCache {
|
||||
descriptions = append(descriptions, "disable-cache")
|
||||
}
|
||||
if r.RewriteTTL != nil {
|
||||
descriptions = append(descriptions, F.ToString("rewrite-ttl=", *r.RewriteTTL))
|
||||
}
|
||||
if r.ClientSubnet.IsValid() {
|
||||
descriptions = append(descriptions, F.ToString("client-subnet=", r.ClientSubnet))
|
||||
}
|
||||
descriptions = append(descriptions, r.Descriptions()...)
|
||||
return F.ToString("route(", strings.Join(descriptions, ","), ")")
|
||||
}
|
||||
|
||||
type RuleActionDNSRouteOptions struct {
|
||||
Strategy C.DomainStrategy
|
||||
Timeout time.Duration
|
||||
DisableCache bool
|
||||
RewriteTTL *uint32
|
||||
ClientSubnet netip.Prefix
|
||||
@ -259,7 +254,17 @@ func (r *RuleActionDNSRouteOptions) Type() string {
|
||||
}
|
||||
|
||||
func (r *RuleActionDNSRouteOptions) String() string {
|
||||
return F.ToString("route-options(", strings.Join(r.Descriptions(), ","), ")")
|
||||
}
|
||||
|
||||
func (r *RuleActionDNSRouteOptions) Descriptions() []string {
|
||||
var descriptions []string
|
||||
if r.Strategy != C.DomainStrategyAsIS {
|
||||
descriptions = append(descriptions, F.ToString("strategy=", option.DomainStrategy(r.Strategy)))
|
||||
}
|
||||
if r.Timeout > 0 {
|
||||
descriptions = append(descriptions, F.ToString("timeout=", r.Timeout.String()))
|
||||
}
|
||||
if r.DisableCache {
|
||||
descriptions = append(descriptions, "disable-cache")
|
||||
}
|
||||
@ -269,7 +274,7 @@ func (r *RuleActionDNSRouteOptions) String() string {
|
||||
if r.ClientSubnet.IsValid() {
|
||||
descriptions = append(descriptions, F.ToString("client-subnet=", r.ClientSubnet))
|
||||
}
|
||||
return F.ToString("route-options(", strings.Join(descriptions, ","), ")")
|
||||
return descriptions
|
||||
}
|
||||
|
||||
type RuleActionDirect struct {
|
||||
@ -421,6 +426,7 @@ func (r *RuleActionSniff) String() string {
|
||||
type RuleActionResolve struct {
|
||||
Server string
|
||||
Strategy C.DomainStrategy
|
||||
Timeout time.Duration
|
||||
DisableCache bool
|
||||
RewriteTTL *uint32
|
||||
ClientSubnet netip.Prefix
|
||||
@ -438,6 +444,9 @@ func (r *RuleActionResolve) String() string {
|
||||
if r.Strategy != C.DomainStrategyAsIS {
|
||||
options = append(options, F.ToString(option.DomainStrategy(r.Strategy)))
|
||||
}
|
||||
if r.Timeout > 0 {
|
||||
options = append(options, F.ToString("timeout=", r.Timeout.String()))
|
||||
}
|
||||
if r.DisableCache {
|
||||
options = append(options, "disable_cache")
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user