refactor: Outbound domain resolver

This commit is contained in:
世界 2025-01-12 12:45:27 +08:00
parent 0415782b2d
commit 88aa2e430e
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
33 changed files with 392 additions and 167 deletions

View file

@ -4,7 +4,6 @@ import (
"context"
"net/netip"
"net/url"
"os"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/experimental/deprecated"
@ -121,11 +120,6 @@ func (o *NewDNSServerOptions) Upgrade(ctx context.Context) error {
if o.Type != C.DNSTypeLegacy {
return nil
}
defer func() {
encoder := json.NewEncoder(os.Stderr)
encoder.SetIndent("", " ")
encoder.Encode(o)
}()
options := o.Options.(*LegacyDNSServerOptions)
serverURL, _ := url.Parse(options.Address)
var serverType string
@ -139,18 +133,34 @@ func (o *NewDNSServerOptions) Upgrade(ctx context.Context) error {
serverType = C.DNSTypeUDP
}
}
remoteOptions := RemoteDNSServerOptions{
LocalDNSServerOptions: LocalDNSServerOptions{
DialerOptions: DialerOptions{
Detour: options.Detour,
var remoteOptions RemoteDNSServerOptions
if options.Detour == "" {
remoteOptions = RemoteDNSServerOptions{
LocalDNSServerOptions: LocalDNSServerOptions{
LegacyStrategy: options.Strategy,
LegacyDefaultDialer: options.Detour == "",
LegacyClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
},
LegacyStrategy: options.Strategy,
LegacyDefaultDialer: options.Detour == "",
LegacyClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
},
AddressResolver: options.AddressResolver,
AddressStrategy: options.AddressStrategy,
AddressFallbackDelay: options.AddressFallbackDelay,
LegacyAddressResolver: options.AddressResolver,
LegacyAddressStrategy: options.AddressStrategy,
LegacyAddressFallbackDelay: options.AddressFallbackDelay,
}
} else {
remoteOptions = RemoteDNSServerOptions{
LocalDNSServerOptions: LocalDNSServerOptions{
DialerOptions: DialerOptions{
Detour: options.Detour,
DomainResolver: &DomainResolveOptions{
Server: options.AddressResolver,
Strategy: options.AddressStrategy,
},
FallbackDelay: options.AddressFallbackDelay,
},
LegacyStrategy: options.Strategy,
LegacyDefaultDialer: options.Detour == "",
LegacyClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
},
}
}
switch serverType {
case C.DNSTypeLocal:
@ -291,9 +301,9 @@ type LocalDNSServerOptions struct {
type RemoteDNSServerOptions struct {
LocalDNSServerOptions
ServerOptions
AddressResolver string `json:"address_resolver,omitempty"`
AddressStrategy DomainStrategy `json:"address_strategy,omitempty"`
AddressFallbackDelay badoption.Duration `json:"address_fallback_delay,omitempty"`
LegacyAddressResolver string `json:"-"`
LegacyAddressStrategy DomainStrategy `json:"-"`
LegacyAddressFallbackDelay badoption.Duration `json:"-"`
}
type RemoteTLSDNSServerOptions struct {

View file

@ -77,12 +77,46 @@ type DialerOptions struct {
TCPMultiPath bool `json:"tcp_multi_path,omitempty"`
UDPFragment *bool `json:"udp_fragment,omitempty"`
UDPFragmentDefault bool `json:"-"`
DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"`
DomainResolver *DomainResolveOptions `json:"domain_resolver,omitempty"`
NetworkStrategy *NetworkStrategy `json:"network_strategy,omitempty"`
NetworkType badoption.Listable[InterfaceType] `json:"network_type,omitempty"`
FallbackNetworkType badoption.Listable[InterfaceType] `json:"fallback_network_type,omitempty"`
FallbackDelay badoption.Duration `json:"fallback_delay,omitempty"`
IsWireGuardListener bool `json:"-"`
// Deprecated: migrated to domain resolver
DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"`
}
type _DomainResolveOptions struct {
Server string `json:"server"`
Strategy DomainStrategy `json:"strategy,omitempty"`
DisableCache bool `json:"disable_cache,omitempty"`
RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
}
type DomainResolveOptions _DomainResolveOptions
func (o DomainResolveOptions) MarshalJSON() ([]byte, error) {
if o.Strategy == DomainStrategy(C.DomainStrategyAsIS) &&
!o.DisableCache &&
o.RewriteTTL == nil &&
o.ClientSubnet == nil {
return json.Marshal(o.Server)
} else {
return json.Marshal((_DomainResolveOptions)(o))
}
}
func (o *DomainResolveOptions) UnmarshalJSON(bytes []byte) error {
var stringValue string
err := json.Unmarshal(bytes, &stringValue)
if err == nil {
o.Server = stringValue
return nil
}
return json.Unmarshal(bytes, (*_DomainResolveOptions)(o))
}
func (o *DialerOptions) TakeDialerOptions() DialerOptions {
@ -107,6 +141,10 @@ func (o ServerOptions) Build() M.Socksaddr {
return M.ParseSocksaddrHostPort(o.Server, o.ServerPort)
}
func (o ServerOptions) ServerIsDomain() bool {
return M.IsDomainName(o.Server)
}
func (o *ServerOptions) TakeServerOptions() ServerOptions {
return *o
}

View file

@ -13,6 +13,7 @@ type RouteOptions struct {
OverrideAndroidVPN bool `json:"override_android_vpn,omitempty"`
DefaultInterface string `json:"default_interface,omitempty"`
DefaultMark FwMark `json:"default_mark,omitempty"`
DefaultDomainResolver *DomainResolveOptions `json:"default_domain_resolver,omitempty"`
DefaultNetworkStrategy *NetworkStrategy `json:"default_network_strategy,omitempty"`
DefaultNetworkType badoption.Listable[InterfaceType] `json:"default_network_type,omitempty"`
DefaultFallbackNetworkType badoption.Listable[InterfaceType] `json:"default_fallback_network_type,omitempty"`