Let more dns flags editable

This commit is contained in:
Puqns67 2024-11-23 19:26:23 +08:00
parent 7be25fb1c0
commit f7224b3d60
Signed by: Puqns67
GPG Key ID: 9669DF042554F536
3 changed files with 100 additions and 96 deletions

View File

@ -5,7 +5,7 @@ import (
C "github.com/sagernet/serenity/constant" C "github.com/sagernet/serenity/constant"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-dns" dns "github.com/sagernet/sing-dns"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/json" "github.com/sagernet/sing/common/json"
"github.com/sagernet/sing/common/json/badjson" "github.com/sagernet/sing/common/json/badjson"
@ -28,14 +28,18 @@ type _Template struct {
RemoteResolve bool `json:"remote_resolve,omitempty"` RemoteResolve bool `json:"remote_resolve,omitempty"`
// DNS // DNS
Servers []option.DNSServerOptions `json:"servers,omitempty"` CustomDNSServers []option.DNSServerOptions `json:"custom_dns_servers,omitempty"`
DNS string `json:"dns,omitempty"` DNS string `json:"dns,omitempty"`
DNSLocal string `json:"dns_local,omitempty"` DNSLocal string `json:"dns_local,omitempty"`
EnableFakeIP bool `json:"enable_fakeip,omitempty"` EnableFakeIP bool `json:"enable_fakeip,omitempty"`
DisableDNSLeak bool `json:"disable_dns_leak,omitempty"` DisableDNSLeak bool `json:"disable_dns_leak,omitempty"`
PreDNSRules []option.DNSRule `json:"pre_dns_rules,omitempty"` PreDNSRules []option.DNSRule `json:"pre_dns_rules,omitempty"`
CustomDNSRules []option.DNSRule `json:"custom_dns_rules,omitempty"` CustomDNSRules []option.DNSRule `json:"custom_dns_rules,omitempty"`
CustomFakeIP *option.DNSFakeIPOptions `json:"custom_fakeip,omitempty"` CustomFakeIP *option.DNSFakeIPOptions `json:"custom_fakeip,omitempty"`
CustomDNSTag string `json:"custom_dns_tag,omitempty"`
CustomDNSLocalTag string `json:"custom_dns_local_tag,omitempty"`
CustomDNSLocalSetupTag string `json:"custom_dns_local_setup_tag,omitempty"`
CustomDNSFakeIPTag string `json:"custom_dns_fakeip_tag,omitempty"`
// Inbound // Inbound
Inbounds []option.Inbound `json:"inbounds,omitempty"` Inbounds []option.Inbound `json:"inbounds,omitempty"`
@ -95,16 +99,16 @@ func (t *Template) UnmarshalJSONContext(ctx context.Context, content []byte) err
} }
type _RuleSet struct { type _RuleSet struct {
Type string `json:"type,omitempty"` Type string `json:"type,omitempty"`
DefaultOptions option.RuleSet `json:"-"` DefaultOptions option.RuleSet `json:"-"`
GitHubOptions GitHubRuleSetOptions `json:"-"` URLOptions URLRuleSetOptions `json:"-"`
} }
type RuleSet _RuleSet type RuleSet _RuleSet
func (r *RuleSet) MarshalJSON() ([]byte, error) { func (r *RuleSet) MarshalJSON() ([]byte, error) {
if r.Type == C.RuleSetTypeGitHub { if r.Type == C.RuleSetTypeURL {
return badjson.MarshallObjects((*_RuleSet)(r), r.GitHubOptions) return badjson.MarshallObjects((*_RuleSet)(r), r.URLOptions)
} else { } else {
return json.Marshal(r.DefaultOptions) return json.Marshal(r.DefaultOptions)
} }
@ -115,18 +119,17 @@ func (r *RuleSet) UnmarshalJSON(content []byte) error {
if err != nil { if err != nil {
return err return err
} }
if r.Type == C.RuleSetTypeGitHub { if r.Type == C.RuleSetTypeURL {
return badjson.UnmarshallExcluded(content, (*_RuleSet)(r), &r.GitHubOptions) return badjson.UnmarshallExcluded(content, (*_RuleSet)(r), &r.URLOptions)
} else { } else {
return badjson.UnmarshallExcluded(content, (*_RuleSet)(r), &r.DefaultOptions) return badjson.UnmarshallExcluded(content, (*_RuleSet)(r), &r.DefaultOptions)
} }
} }
type GitHubRuleSetOptions struct { type URLRuleSetOptions struct {
Repository string `json:"repository,omitempty"` Base string `json:"base,omitempty"`
Path string `json:"path,omitempty"` Prefix string `json:"prefix,omitempty"`
Prefix string `json:"prefix,omitempty"` RuleSet map[string]string `json:"rule_set,omitempty"`
RuleSet badoption.Listable[string] `json:"rule_set,omitempty"`
} }
func (t Template) DisableIPv6() bool { func (t Template) DisableIPv6() bool {

View File

@ -8,13 +8,20 @@ import (
"github.com/sagernet/serenity/common/semver" "github.com/sagernet/serenity/common/semver"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-dns" dns "github.com/sagernet/sing-dns"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
BM "github.com/sagernet/sing/common/metadata" BM "github.com/sagernet/sing/common/metadata"
mDNS "github.com/miekg/dns" mDNS "github.com/miekg/dns"
) )
func getOrDefault(v string, d string) string {
if v != "" {
return v
}
return d
}
func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error { func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error {
var ( var (
domainStrategy option.DomainStrategy domainStrategy option.DomainStrategy
@ -35,64 +42,60 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error
if domainStrategyLocal == domainStrategy { if domainStrategyLocal == domainStrategy {
domainStrategyLocal = 0 domainStrategyLocal = 0
} }
dnsTag := getOrDefault(t.CustomDNSTag, DefaultDNSTag)
dnsLocalTag := getOrDefault(t.CustomDNSLocalTag, DefaultDNSLocalTag)
dnsLocalSetupTag := getOrDefault(t.CustomDNSLocalSetupTag, DefaultDNSLocalSetupTag)
dnsFakeIPTag := getOrDefault(t.CustomDNSFakeIPTag, DefaultDNSFakeIPTag)
dns := getOrDefault(t.DNS, DefaultDNS)
dnsLocal := getOrDefault(t.DNSLocal, DefaultDNSLocal)
directTag := getOrDefault(t.DirectTag, DefaultDirectTag)
options.DNS = &option.DNSOptions{ options.DNS = &option.DNSOptions{
Servers: t.Servers, Servers: []option.DNSServerOptions{},
ReverseMapping: !t.DisableTrafficBypass && metadata.Platform != M.PlatformUnknown && !metadata.Platform.IsApple(), ReverseMapping: !t.DisableTrafficBypass && metadata.Platform != M.PlatformUnknown && !metadata.Platform.IsApple(),
DNSClientOptions: option.DNSClientOptions{ DNSClientOptions: option.DNSClientOptions{
Strategy: domainStrategy, Strategy: domainStrategy,
IndependentCache: t.EnableFakeIP, IndependentCache: t.EnableFakeIP,
}, },
} }
dnsDefault := t.DNS
if dnsDefault == "" {
dnsDefault = DefaultDNS
}
dnsLocal := t.DNSLocal
if dnsLocal == "" {
dnsLocal = DefaultDNSLocal
}
directTag := t.DirectTag
if directTag == "" {
directTag = DefaultDirectTag
}
defaultDNSOptions := option.DNSServerOptions{ defaultDNSOptions := option.DNSServerOptions{
Tag: DNSDefaultTag, Tag: dnsTag,
Address: dnsDefault, Address: dns,
} }
if dnsDefaultUrl, err := url.Parse(dnsDefault); err == nil && BM.IsDomainName(dnsDefaultUrl.Hostname()) { if dnsDefaultUrl, err := url.Parse(dns); err == nil && BM.IsDomainName(dnsDefaultUrl.Hostname()) {
defaultDNSOptions.AddressResolver = DNSLocalTag defaultDNSOptions.AddressResolver = dnsLocalTag
}
if t.RemoteResolve {
defaultDNSOptions.Detour = getOrDefault(t.DefaultTag, DefaultDefaultTag)
} }
options.DNS.Servers = append(options.DNS.Servers, defaultDNSOptions) options.DNS.Servers = append(options.DNS.Servers, defaultDNSOptions)
var (
localDNSOptions option.DNSServerOptions
localDNSIsDomain bool
)
if t.DisableTrafficBypass { if t.DisableTrafficBypass {
localDNSOptions = option.DNSServerOptions{
Tag: DNSLocalTag,
Address: "local",
Strategy: domainStrategyLocal,
}
} else {
localDNSOptions = option.DNSServerOptions{
Tag: DNSLocalTag,
Address: dnsLocal,
Detour: directTag,
Strategy: domainStrategyLocal,
}
if dnsLocalUrl, err := url.Parse(dnsLocal); err == nil && BM.IsDomainName(dnsLocalUrl.Hostname()) {
localDNSOptions.AddressResolver = DNSLocalSetupTag
localDNSIsDomain = true
}
}
options.DNS.Servers = append(options.DNS.Servers, localDNSOptions)
if localDNSIsDomain {
options.DNS.Servers = append(options.DNS.Servers, option.DNSServerOptions{ options.DNS.Servers = append(options.DNS.Servers, option.DNSServerOptions{
Tag: DNSLocalSetupTag, Tag: dnsLocalTag,
Address: "local", Address: "local",
Strategy: domainStrategyLocal, Strategy: domainStrategyLocal,
}) })
} else {
localDNSOptions := []option.DNSServerOptions{{
Tag: dnsLocalTag,
Address: dnsLocal,
Detour: directTag,
Strategy: domainStrategyLocal,
}}
if dnsLocalUrl, err := url.Parse(dnsLocal); err == nil && BM.IsDomainName(dnsLocalUrl.Hostname()) {
localDNSOptions[0].AddressResolver = dnsLocalSetupTag
localDNSOptions = append(localDNSOptions, option.DNSServerOptions{
Tag: dnsLocalSetupTag,
Address: "local",
Strategy: domainStrategyLocal,
})
}
options.DNS.Servers = append(options.DNS.Servers, localDNSOptions...)
} }
if t.EnableFakeIP { if t.EnableFakeIP {
options.DNS.FakeIP = t.CustomFakeIP options.DNS.FakeIP = t.CustomFakeIP
if options.DNS.FakeIP == nil { if options.DNS.FakeIP == nil {
@ -106,10 +109,15 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error
options.DNS.FakeIP.Inet6Range = common.Ptr(netip.MustParsePrefix("fc00::/18")) options.DNS.FakeIP.Inet6Range = common.Ptr(netip.MustParsePrefix("fc00::/18"))
} }
options.DNS.Servers = append(options.DNS.Servers, option.DNSServerOptions{ options.DNS.Servers = append(options.DNS.Servers, option.DNSServerOptions{
Tag: DNSFakeIPTag, Tag: dnsFakeIPTag,
Address: "fakeip", Address: "fakeip",
}) })
} }
if len(t.CustomDNSServers) > 0 {
options.DNS.Servers = append(options.DNS.Servers, t.CustomDNSServers...)
}
options.DNS.Rules = []option.DNSRule{ options.DNS.Rules = []option.DNSRule{
{ {
Type: C.RuleTypeDefault, Type: C.RuleTypeDefault,
@ -120,24 +128,16 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error
DNSRuleAction: option.DNSRuleAction{ DNSRuleAction: option.DNSRuleAction{
Action: C.RuleActionTypeRoute, Action: C.RuleActionTypeRoute,
RouteOptions: option.DNSRouteActionOptions{ RouteOptions: option.DNSRouteActionOptions{
Server: DNSLocalTag, Server: dnsLocalTag,
}, },
}, },
}, },
}, },
} }
clashModeRule := t.ClashModeRule
if clashModeRule == "" { clashModeRule := getOrDefault(t.ClashModeRule, "Rule")
clashModeRule = "Rule" clashModeGlobal := getOrDefault(t.ClashModeGlobal, "Global")
} clashModeDirect := getOrDefault(t.ClashModeDirect, "Direct")
clashModeGlobal := t.ClashModeGlobal
if clashModeGlobal == "" {
clashModeGlobal = "Global"
}
clashModeDirect := t.ClashModeDirect
if clashModeDirect == "" {
clashModeDirect = "Direct"
}
if !t.DisableClashMode { if !t.DisableClashMode {
options.DNS.Rules = append(options.DNS.Rules, option.DNSRule{ options.DNS.Rules = append(options.DNS.Rules, option.DNSRule{
@ -149,7 +149,7 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error
DNSRuleAction: option.DNSRuleAction{ DNSRuleAction: option.DNSRuleAction{
Action: C.RuleActionTypeRoute, Action: C.RuleActionTypeRoute,
RouteOptions: option.DNSRouteActionOptions{ RouteOptions: option.DNSRouteActionOptions{
Server: DNSDefaultTag, Server: dnsTag,
}, },
}, },
}, },
@ -162,16 +162,16 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error
DNSRuleAction: option.DNSRuleAction{ DNSRuleAction: option.DNSRuleAction{
Action: C.RuleActionTypeRoute, Action: C.RuleActionTypeRoute,
RouteOptions: option.DNSRouteActionOptions{ RouteOptions: option.DNSRouteActionOptions{
Server: DNSLocalTag, Server: dnsLocalTag,
}, },
}, },
}, },
}) })
} }
options.DNS.Rules = append(options.DNS.Rules, t.PreDNSRules...) options.DNS.Rules = append(options.DNS.Rules, t.PreDNSRules...)
if len(t.CustomDNSRules) == 0 { if len(t.CustomDNSRules) == 0 {
if !t.DisableTrafficBypass { if !t.DisableTrafficBypass {
options.DNS.Rules = append(options.DNS.Rules, option.DNSRule{ options.DNS.Rules = append(options.DNS.Rules, option.DNSRule{
Type: C.RuleTypeDefault, Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultDNSRule{ DefaultOptions: option.DefaultDNSRule{
@ -181,7 +181,7 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error
DNSRuleAction: option.DNSRuleAction{ DNSRuleAction: option.DNSRuleAction{
Action: C.RuleActionTypeRoute, Action: C.RuleActionTypeRoute,
RouteOptions: option.DNSRouteActionOptions{ RouteOptions: option.DNSRouteActionOptions{
Server: DNSLocalTag, Server: dnsLocalTag,
}, },
}, },
}, },
@ -196,7 +196,7 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error
DNSRuleAction: option.DNSRuleAction{ DNSRuleAction: option.DNSRuleAction{
Action: C.RuleActionTypeRoute, Action: C.RuleActionTypeRoute,
RouteOptions: option.DNSRouteActionOptions{ RouteOptions: option.DNSRouteActionOptions{
Server: DNSDefaultTag, Server: dnsTag,
}, },
}, },
}, },
@ -227,7 +227,7 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error
DNSRuleAction: option.DNSRuleAction{ DNSRuleAction: option.DNSRuleAction{
Action: C.RuleActionTypeRoute, Action: C.RuleActionTypeRoute,
RouteOptions: option.DNSRouteActionOptions{ RouteOptions: option.DNSRouteActionOptions{
Server: DNSLocalTag, Server: dnsLocalTag,
}, },
}, },
}, },
@ -237,6 +237,7 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error
} else { } else {
options.DNS.Rules = append(options.DNS.Rules, t.CustomDNSRules...) options.DNS.Rules = append(options.DNS.Rules, t.CustomDNSRules...)
} }
if t.EnableFakeIP { if t.EnableFakeIP {
options.DNS.Rules = append(options.DNS.Rules, option.DNSRule{ options.DNS.Rules = append(options.DNS.Rules, option.DNSRule{
Type: C.RuleTypeDefault, Type: C.RuleTypeDefault,
@ -250,7 +251,7 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error
DNSRuleAction: option.DNSRuleAction{ DNSRuleAction: option.DNSRuleAction{
Action: C.RuleActionTypeRoute, Action: C.RuleActionTypeRoute,
RouteOptions: option.DNSRouteActionOptions{ RouteOptions: option.DNSRouteActionOptions{
Server: DNSFakeIPTag, Server: dnsFakeIPTag,
}, },
}, },
}, },

View File

@ -13,18 +13,18 @@ import (
) )
const ( const (
DefaultMixedPort = 8080 DefaultMixedPort = 8080
DNSDefaultTag = "default" DefaultDNSTag = "default"
DNSLocalTag = "local" DefaultDNSLocalTag = "local"
DNSLocalSetupTag = "local_setup" DefaultDNSLocalSetupTag = "local_setup"
DNSFakeIPTag = "remote" DefaultDNSFakeIPTag = "remote"
DefaultDNS = "tls://8.8.8.8" DefaultDNS = "tls://8.8.8.8"
DefaultDNSLocal = "https://223.5.5.5/dns-query" DefaultDNSLocal = "https://223.5.5.5/dns-query"
DefaultDefaultTag = "default" DefaultDefaultTag = "default"
DefaultDirectTag = "direct" DefaultDirectTag = "direct"
DefaultBlockTag = "block" DefaultBlockTag = "block"
DNSTag = "dns" DNSTag = "dns"
DefaultURLTestTag = "URLTest" DefaultURLTestTag = "URLTest"
) )
var Default = new(Template) var Default = new(Template)