From f7224b3d6045bb2df2e526287f7c64b938f95e6c Mon Sep 17 00:00:00 2001 From: Puqns67 Date: Sat, 23 Nov 2024 19:26:23 +0800 Subject: [PATCH] Let more dns flags editable --- option/template.go | 45 ++++++++------- template/render_dns.go | 127 +++++++++++++++++++++-------------------- template/template.go | 24 ++++---- 3 files changed, 100 insertions(+), 96 deletions(-) diff --git a/option/template.go b/option/template.go index 59201cc..b35ef13 100644 --- a/option/template.go +++ b/option/template.go @@ -5,7 +5,7 @@ import ( C "github.com/sagernet/serenity/constant" "github.com/sagernet/sing-box/option" - "github.com/sagernet/sing-dns" + dns "github.com/sagernet/sing-dns" E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/json" "github.com/sagernet/sing/common/json/badjson" @@ -28,14 +28,18 @@ type _Template struct { RemoteResolve bool `json:"remote_resolve,omitempty"` // DNS - Servers []option.DNSServerOptions `json:"servers,omitempty"` - DNS string `json:"dns,omitempty"` - DNSLocal string `json:"dns_local,omitempty"` - EnableFakeIP bool `json:"enable_fakeip,omitempty"` - DisableDNSLeak bool `json:"disable_dns_leak,omitempty"` - PreDNSRules []option.DNSRule `json:"pre_dns_rules,omitempty"` - CustomDNSRules []option.DNSRule `json:"custom_dns_rules,omitempty"` - CustomFakeIP *option.DNSFakeIPOptions `json:"custom_fakeip,omitempty"` + CustomDNSServers []option.DNSServerOptions `json:"custom_dns_servers,omitempty"` + DNS string `json:"dns,omitempty"` + DNSLocal string `json:"dns_local,omitempty"` + EnableFakeIP bool `json:"enable_fakeip,omitempty"` + DisableDNSLeak bool `json:"disable_dns_leak,omitempty"` + PreDNSRules []option.DNSRule `json:"pre_dns_rules,omitempty"` + CustomDNSRules []option.DNSRule `json:"custom_dns_rules,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 Inbounds []option.Inbound `json:"inbounds,omitempty"` @@ -95,16 +99,16 @@ func (t *Template) UnmarshalJSONContext(ctx context.Context, content []byte) err } type _RuleSet struct { - Type string `json:"type,omitempty"` - DefaultOptions option.RuleSet `json:"-"` - GitHubOptions GitHubRuleSetOptions `json:"-"` + Type string `json:"type,omitempty"` + DefaultOptions option.RuleSet `json:"-"` + URLOptions URLRuleSetOptions `json:"-"` } type RuleSet _RuleSet func (r *RuleSet) MarshalJSON() ([]byte, error) { - if r.Type == C.RuleSetTypeGitHub { - return badjson.MarshallObjects((*_RuleSet)(r), r.GitHubOptions) + if r.Type == C.RuleSetTypeURL { + return badjson.MarshallObjects((*_RuleSet)(r), r.URLOptions) } else { return json.Marshal(r.DefaultOptions) } @@ -115,18 +119,17 @@ func (r *RuleSet) UnmarshalJSON(content []byte) error { if err != nil { return err } - if r.Type == C.RuleSetTypeGitHub { - return badjson.UnmarshallExcluded(content, (*_RuleSet)(r), &r.GitHubOptions) + if r.Type == C.RuleSetTypeURL { + return badjson.UnmarshallExcluded(content, (*_RuleSet)(r), &r.URLOptions) } else { return badjson.UnmarshallExcluded(content, (*_RuleSet)(r), &r.DefaultOptions) } } -type GitHubRuleSetOptions struct { - Repository string `json:"repository,omitempty"` - Path string `json:"path,omitempty"` - Prefix string `json:"prefix,omitempty"` - RuleSet badoption.Listable[string] `json:"rule_set,omitempty"` +type URLRuleSetOptions struct { + Base string `json:"base,omitempty"` + Prefix string `json:"prefix,omitempty"` + RuleSet map[string]string `json:"rule_set,omitempty"` } func (t Template) DisableIPv6() bool { diff --git a/template/render_dns.go b/template/render_dns.go index 555c277..8564d2d 100644 --- a/template/render_dns.go +++ b/template/render_dns.go @@ -8,13 +8,20 @@ import ( "github.com/sagernet/serenity/common/semver" C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" - "github.com/sagernet/sing-dns" + dns "github.com/sagernet/sing-dns" "github.com/sagernet/sing/common" BM "github.com/sagernet/sing/common/metadata" 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 { var ( domainStrategy option.DomainStrategy @@ -35,64 +42,60 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error if domainStrategyLocal == domainStrategy { 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{ - Servers: t.Servers, + Servers: []option.DNSServerOptions{}, ReverseMapping: !t.DisableTrafficBypass && metadata.Platform != M.PlatformUnknown && !metadata.Platform.IsApple(), DNSClientOptions: option.DNSClientOptions{ Strategy: domainStrategy, 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{ - Tag: DNSDefaultTag, - Address: dnsDefault, + Tag: dnsTag, + Address: dns, } - if dnsDefaultUrl, err := url.Parse(dnsDefault); err == nil && BM.IsDomainName(dnsDefaultUrl.Hostname()) { - defaultDNSOptions.AddressResolver = DNSLocalTag + if dnsDefaultUrl, err := url.Parse(dns); err == nil && BM.IsDomainName(dnsDefaultUrl.Hostname()) { + defaultDNSOptions.AddressResolver = dnsLocalTag + } + if t.RemoteResolve { + defaultDNSOptions.Detour = getOrDefault(t.DefaultTag, DefaultDefaultTag) } options.DNS.Servers = append(options.DNS.Servers, defaultDNSOptions) - var ( - localDNSOptions option.DNSServerOptions - localDNSIsDomain bool - ) + 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{ - Tag: DNSLocalSetupTag, + 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[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 { options.DNS.FakeIP = t.CustomFakeIP 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.Servers = append(options.DNS.Servers, option.DNSServerOptions{ - Tag: DNSFakeIPTag, + Tag: dnsFakeIPTag, Address: "fakeip", }) } + + if len(t.CustomDNSServers) > 0 { + options.DNS.Servers = append(options.DNS.Servers, t.CustomDNSServers...) + } + options.DNS.Rules = []option.DNSRule{ { Type: C.RuleTypeDefault, @@ -120,24 +128,16 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error DNSRuleAction: option.DNSRuleAction{ Action: C.RuleActionTypeRoute, RouteOptions: option.DNSRouteActionOptions{ - Server: DNSLocalTag, + Server: dnsLocalTag, }, }, }, }, } - clashModeRule := t.ClashModeRule - if clashModeRule == "" { - clashModeRule = "Rule" - } - clashModeGlobal := t.ClashModeGlobal - if clashModeGlobal == "" { - clashModeGlobal = "Global" - } - clashModeDirect := t.ClashModeDirect - if clashModeDirect == "" { - clashModeDirect = "Direct" - } + + clashModeRule := getOrDefault(t.ClashModeRule, "Rule") + clashModeGlobal := getOrDefault(t.ClashModeGlobal, "Global") + clashModeDirect := getOrDefault(t.ClashModeDirect, "Direct") if !t.DisableClashMode { 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{ Action: C.RuleActionTypeRoute, 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{ Action: C.RuleActionTypeRoute, RouteOptions: option.DNSRouteActionOptions{ - Server: DNSLocalTag, + Server: dnsLocalTag, }, }, }, }) } options.DNS.Rules = append(options.DNS.Rules, t.PreDNSRules...) + if len(t.CustomDNSRules) == 0 { if !t.DisableTrafficBypass { - options.DNS.Rules = append(options.DNS.Rules, option.DNSRule{ Type: C.RuleTypeDefault, DefaultOptions: option.DefaultDNSRule{ @@ -181,7 +181,7 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error DNSRuleAction: option.DNSRuleAction{ Action: C.RuleActionTypeRoute, 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{ Action: C.RuleActionTypeRoute, 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{ Action: C.RuleActionTypeRoute, RouteOptions: option.DNSRouteActionOptions{ - Server: DNSLocalTag, + Server: dnsLocalTag, }, }, }, @@ -237,6 +237,7 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error } else { options.DNS.Rules = append(options.DNS.Rules, t.CustomDNSRules...) } + if t.EnableFakeIP { options.DNS.Rules = append(options.DNS.Rules, option.DNSRule{ Type: C.RuleTypeDefault, @@ -250,7 +251,7 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error DNSRuleAction: option.DNSRuleAction{ Action: C.RuleActionTypeRoute, RouteOptions: option.DNSRouteActionOptions{ - Server: DNSFakeIPTag, + Server: dnsFakeIPTag, }, }, }, diff --git a/template/template.go b/template/template.go index da04c96..82891ef 100644 --- a/template/template.go +++ b/template/template.go @@ -13,18 +13,18 @@ import ( ) const ( - DefaultMixedPort = 8080 - DNSDefaultTag = "default" - DNSLocalTag = "local" - DNSLocalSetupTag = "local_setup" - DNSFakeIPTag = "remote" - DefaultDNS = "tls://8.8.8.8" - DefaultDNSLocal = "https://223.5.5.5/dns-query" - DefaultDefaultTag = "default" - DefaultDirectTag = "direct" - DefaultBlockTag = "block" - DNSTag = "dns" - DefaultURLTestTag = "URLTest" + DefaultMixedPort = 8080 + DefaultDNSTag = "default" + DefaultDNSLocalTag = "local" + DefaultDNSLocalSetupTag = "local_setup" + DefaultDNSFakeIPTag = "remote" + DefaultDNS = "tls://8.8.8.8" + DefaultDNSLocal = "https://223.5.5.5/dns-query" + DefaultDefaultTag = "default" + DefaultDirectTag = "direct" + DefaultBlockTag = "block" + DNSTag = "dns" + DefaultURLTestTag = "URLTest" ) var Default = new(Template)