forked from mirror/serenity
Add tempalte.extended
, template.<rule_set>.<type=github/owner/repo/branch/rule_set>
, template.block_tag
This commit is contained in:
parent
404de85ab1
commit
9ae4f644f1
6
constant/rule_set.go
Normal file
6
constant/rule_set.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package constant
|
||||||
|
|
||||||
|
const (
|
||||||
|
RuleSetTypeDefault = "default"
|
||||||
|
RuleSetTypeGitHub = "github"
|
||||||
|
)
|
@ -57,7 +57,7 @@
|
|||||||
"custom_geoip": {},
|
"custom_geoip": {},
|
||||||
"custom_geosite": {},
|
"custom_geosite": {},
|
||||||
"custom_rule_set": [],
|
"custom_rule_set": [],
|
||||||
"post_custom_rule_set": [],
|
"post_rule_set": [],
|
||||||
|
|
||||||
// Experimental
|
// Experimental
|
||||||
|
|
||||||
@ -253,7 +253,7 @@ List of [RuleSet](https://sing-box.sagernet.org/configuration/rule-set/).
|
|||||||
|
|
||||||
Default rule sets will not be generated if not empty.
|
Default rule sets will not be generated if not empty.
|
||||||
|
|
||||||
#### post_custom_rule_set
|
#### post_rule_set
|
||||||
|
|
||||||
List of [RuleSet](https://sing-box.sagernet.org/configuration/rule-set/).
|
List of [RuleSet](https://sing-box.sagernet.org/configuration/rule-set/).
|
||||||
|
|
||||||
|
@ -2,13 +2,17 @@ package option
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/sagernet/serenity/common/semver"
|
"github.com/sagernet/serenity/common/semver"
|
||||||
|
C "github.com/sagernet/serenity/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing-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"
|
"github.com/sagernet/sing/common/json/badjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Template struct {
|
type Template struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
|
Extend string `json:"extend,omitempty"`
|
||||||
|
|
||||||
// Global
|
// Global
|
||||||
|
|
||||||
@ -37,6 +41,7 @@ type Template struct {
|
|||||||
ExtraGroups []ExtraGroup `json:"extra_groups,omitempty"`
|
ExtraGroups []ExtraGroup `json:"extra_groups,omitempty"`
|
||||||
GenerateGlobalURLTest bool `json:"generate_global_urltest,omitempty"`
|
GenerateGlobalURLTest bool `json:"generate_global_urltest,omitempty"`
|
||||||
DirectTag string `json:"direct_tag,omitempty"`
|
DirectTag string `json:"direct_tag,omitempty"`
|
||||||
|
BlockTag string `json:"block_tag,omitempty"`
|
||||||
DefaultTag string `json:"default_tag,omitempty"`
|
DefaultTag string `json:"default_tag,omitempty"`
|
||||||
URLTestTag string `json:"urltest_tag,omitempty"`
|
URLTestTag string `json:"urltest_tag,omitempty"`
|
||||||
CustomDirect *option.DirectOutboundOptions `json:"custom_direct,omitempty"`
|
CustomDirect *option.DirectOutboundOptions `json:"custom_direct,omitempty"`
|
||||||
@ -51,8 +56,8 @@ type Template struct {
|
|||||||
EnableJSDelivr bool `json:"enable_jsdelivr,omitempty"`
|
EnableJSDelivr bool `json:"enable_jsdelivr,omitempty"`
|
||||||
CustomGeoIP *option.GeoIPOptions `json:"custom_geoip,omitempty"`
|
CustomGeoIP *option.GeoIPOptions `json:"custom_geoip,omitempty"`
|
||||||
CustomGeosite *option.GeositeOptions `json:"custom_geosite,omitempty"`
|
CustomGeosite *option.GeositeOptions `json:"custom_geosite,omitempty"`
|
||||||
CustomRuleSet []option.RuleSet `json:"custom_rule_set,omitempty"`
|
CustomRuleSet []RuleSet `json:"custom_rule_set,omitempty"`
|
||||||
PostCustomRuleSet []option.RuleSet `json:"post_custom_rule_set,omitempty"`
|
PostRuleSet []RuleSet `json:"post_rule_set,omitempty"`
|
||||||
|
|
||||||
// Experimental
|
// Experimental
|
||||||
DisableCacheFile bool `json:"disable_cache_file,omitempty"`
|
DisableCacheFile bool `json:"disable_cache_file,omitempty"`
|
||||||
@ -70,6 +75,53 @@ type Template struct {
|
|||||||
MemoryLimit option.MemoryBytes `json:"memory_limit,omitempty"`
|
MemoryLimit option.MemoryBytes `json:"memory_limit,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type _RuleSet struct {
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
DefaultOptions option.RuleSet `json:"-"`
|
||||||
|
GitHubOptions GitHubRuleSetOptions `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RuleSet _RuleSet
|
||||||
|
|
||||||
|
func (r *RuleSet) RawOptions() (any, error) {
|
||||||
|
switch r.Type {
|
||||||
|
case C.RuleSetTypeDefault, "":
|
||||||
|
r.Type = ""
|
||||||
|
return &r.DefaultOptions, nil
|
||||||
|
case C.RuleSetTypeGitHub:
|
||||||
|
return &r.GitHubOptions, nil
|
||||||
|
default:
|
||||||
|
return nil, E.New("unknown rule set type", r.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RuleSet) MarshalJSON() ([]byte, error) {
|
||||||
|
rawOptions, err := r.RawOptions()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return option.MarshallObjects((*_RuleSet)(r), rawOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RuleSet) UnmarshalJSON(bytes []byte) error {
|
||||||
|
err := json.Unmarshal(bytes, (*_RuleSet)(r))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rawOptions, err := r.RawOptions()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return option.UnmarshallExcluded(bytes, (*_RuleSet)(r), rawOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
type GitHubRuleSetOptions struct {
|
||||||
|
Owner string `json:"owner,omitempty"`
|
||||||
|
Repo string `json:"repo,omitempty"`
|
||||||
|
Branch string `json:"branch,omitempty"`
|
||||||
|
RuleSet option.Listable[string] `json:"rule_set,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
func (t Template) DisableIPv6() bool {
|
func (t Template) DisableIPv6() bool {
|
||||||
return t.DomainStrategy == option.DomainStrategy(dns.DomainStrategyUseIPv4)
|
return t.DomainStrategy == option.DomainStrategy(dns.DomainStrategyUseIPv4)
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/sagernet/serenity/option"
|
"github.com/sagernet/serenity/option"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
"github.com/sagernet/sing/common/json/badjson"
|
||||||
"github.com/sagernet/sing/common/logger"
|
"github.com/sagernet/sing/common/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,12 +17,49 @@ type Manager struct {
|
|||||||
templates []*Template
|
templates []*Template
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extendTemplate(rawTemplates []option.Template, root, current option.Template) (option.Template, error) {
|
||||||
|
if current.Extend == "" {
|
||||||
|
return current, nil
|
||||||
|
} else if root.Name == current.Extend {
|
||||||
|
return option.Template{}, E.New("initialize template[", current.Name, "]: circular extend detected: ", current.Extend)
|
||||||
|
}
|
||||||
|
var next option.Template
|
||||||
|
for _, it := range rawTemplates {
|
||||||
|
if it.Name == current.Extend {
|
||||||
|
next = it
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if next.Name == "" {
|
||||||
|
return option.Template{}, E.New("initialize template[", current.Name, "]: extended template not found: ", current.Extend)
|
||||||
|
}
|
||||||
|
if next.Extend != "" {
|
||||||
|
newNext, err := extendTemplate(rawTemplates, root, next)
|
||||||
|
if err != nil {
|
||||||
|
return option.Template{}, E.Cause(err, next.Extend)
|
||||||
|
}
|
||||||
|
next = newNext
|
||||||
|
}
|
||||||
|
newTemplate, err := badjson.Merge(current, next)
|
||||||
|
if err != nil {
|
||||||
|
return option.Template{}, E.Cause(err, "initialize template[", current.Name, "]: merge extended template: ", current.Extend)
|
||||||
|
}
|
||||||
|
return newTemplate, nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewManager(ctx context.Context, logger logger.Logger, rawTemplates []option.Template) (*Manager, error) {
|
func NewManager(ctx context.Context, logger logger.Logger, rawTemplates []option.Template) (*Manager, error) {
|
||||||
var templates []*Template
|
var templates []*Template
|
||||||
for templateIndex, template := range rawTemplates {
|
for templateIndex, template := range rawTemplates {
|
||||||
if template.Name == "" {
|
if template.Name == "" {
|
||||||
return nil, E.New("initialize template[", templateIndex, "]: missing name")
|
return nil, E.New("initialize template[", templateIndex, "]: missing name")
|
||||||
}
|
}
|
||||||
|
if template.Extend != "" {
|
||||||
|
newTemplate, err := extendTemplate(rawTemplates, template, template)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
template = newTemplate
|
||||||
|
}
|
||||||
var groups []*ExtraGroup
|
var groups []*ExtraGroup
|
||||||
for groupIndex, group := range template.ExtraGroups {
|
for groupIndex, group := range template.ExtraGroups {
|
||||||
if group.Tag == "" {
|
if group.Tag == "" {
|
||||||
|
@ -37,6 +37,10 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error
|
|||||||
if dnsLocal == "" {
|
if dnsLocal == "" {
|
||||||
dnsLocal = DefaultDNSLocal
|
dnsLocal = DefaultDNSLocal
|
||||||
}
|
}
|
||||||
|
directTag := t.DirectTag
|
||||||
|
if directTag == "" {
|
||||||
|
directTag = DefaultDirectTag
|
||||||
|
}
|
||||||
defaultDNSOptions := option.DNSServerOptions{
|
defaultDNSOptions := option.DNSServerOptions{
|
||||||
Tag: DNSDefaultTag,
|
Tag: DNSDefaultTag,
|
||||||
Address: dnsDefault,
|
Address: dnsDefault,
|
||||||
@ -58,7 +62,7 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error
|
|||||||
localDNSOptions = option.DNSServerOptions{
|
localDNSOptions = option.DNSServerOptions{
|
||||||
Tag: DNSLocalTag,
|
Tag: DNSLocalTag,
|
||||||
Address: dnsLocal,
|
Address: dnsLocal,
|
||||||
Detour: DefaultDirectTag,
|
Detour: directTag,
|
||||||
}
|
}
|
||||||
if dnsLocalUrl, err := url.Parse(dnsLocal); err == nil && BM.IsDomainName(dnsLocalUrl.Hostname()) {
|
if dnsLocalUrl, err := url.Parse(dnsLocal); err == nil && BM.IsDomainName(dnsLocalUrl.Hostname()) {
|
||||||
localDNSOptions.AddressResolver = DNSLocalSetupTag
|
localDNSOptions.AddressResolver = DNSLocalSetupTag
|
||||||
|
@ -3,11 +3,13 @@ package template
|
|||||||
import (
|
import (
|
||||||
M "github.com/sagernet/serenity/common/metadata"
|
M "github.com/sagernet/serenity/common/metadata"
|
||||||
"github.com/sagernet/serenity/common/semver"
|
"github.com/sagernet/serenity/common/semver"
|
||||||
|
"github.com/sagernet/serenity/constant"
|
||||||
|
"github.com/sagernet/serenity/option"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
boxOption "github.com/sagernet/sing-box/option"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *Template) renderGeoResources(metadata M.Metadata, options *option.Options) {
|
func (t *Template) renderGeoResources(metadata M.Metadata, options *boxOption.Options) {
|
||||||
if t.DisableRuleSet || (metadata.Version != nil && metadata.Version.LessThan(semver.ParseVersion("1.8.0-alpha.10"))) {
|
if t.DisableRuleSet || (metadata.Version != nil && metadata.Version.LessThan(semver.ParseVersion("1.8.0-alpha.10"))) {
|
||||||
var (
|
var (
|
||||||
geoipDownloadURL string
|
geoipDownloadURL string
|
||||||
@ -27,13 +29,13 @@ func (t *Template) renderGeoResources(metadata M.Metadata, options *option.Optio
|
|||||||
geositeDownloadURL = "https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite-cn.db"
|
geositeDownloadURL = "https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite-cn.db"
|
||||||
}
|
}
|
||||||
if t.CustomGeoIP == nil {
|
if t.CustomGeoIP == nil {
|
||||||
options.Route.GeoIP = &option.GeoIPOptions{
|
options.Route.GeoIP = &boxOption.GeoIPOptions{
|
||||||
DownloadURL: geoipDownloadURL,
|
DownloadURL: geoipDownloadURL,
|
||||||
DownloadDetour: downloadDetour,
|
DownloadDetour: downloadDetour,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if t.CustomGeosite == nil {
|
if t.CustomGeosite == nil {
|
||||||
options.Route.Geosite = &option.GeositeOptions{
|
options.Route.Geosite = &boxOption.GeositeOptions{
|
||||||
DownloadURL: geositeDownloadURL,
|
DownloadURL: geositeDownloadURL,
|
||||||
DownloadDetour: downloadDetour,
|
DownloadDetour: downloadDetour,
|
||||||
}
|
}
|
||||||
@ -57,12 +59,12 @@ func (t *Template) renderGeoResources(metadata M.Metadata, options *option.Optio
|
|||||||
downloadURL = "https://raw.githubusercontent.com/"
|
downloadURL = "https://raw.githubusercontent.com/"
|
||||||
branchSplit = "/"
|
branchSplit = "/"
|
||||||
}
|
}
|
||||||
options.Route.RuleSet = []option.RuleSet{
|
options.Route.RuleSet = []boxOption.RuleSet{
|
||||||
{
|
{
|
||||||
Type: C.RuleSetTypeRemote,
|
Type: C.RuleSetTypeRemote,
|
||||||
Tag: "geoip-cn",
|
Tag: "geoip-cn",
|
||||||
Format: C.RuleSetFormatBinary,
|
Format: C.RuleSetFormatBinary,
|
||||||
RemoteOptions: option.RemoteRuleSet{
|
RemoteOptions: boxOption.RemoteRuleSet{
|
||||||
URL: downloadURL + "SagerNet/sing-geoip" + branchSplit + "rule-set/geoip-cn.srs",
|
URL: downloadURL + "SagerNet/sing-geoip" + branchSplit + "rule-set/geoip-cn.srs",
|
||||||
DownloadDetour: downloadDetour,
|
DownloadDetour: downloadDetour,
|
||||||
},
|
},
|
||||||
@ -71,7 +73,7 @@ func (t *Template) renderGeoResources(metadata M.Metadata, options *option.Optio
|
|||||||
Type: C.RuleSetTypeRemote,
|
Type: C.RuleSetTypeRemote,
|
||||||
Tag: "geosite-geolocation-cn",
|
Tag: "geosite-geolocation-cn",
|
||||||
Format: C.RuleSetFormatBinary,
|
Format: C.RuleSetFormatBinary,
|
||||||
RemoteOptions: option.RemoteRuleSet{
|
RemoteOptions: boxOption.RemoteRuleSet{
|
||||||
URL: downloadURL + "SagerNet/sing-geosite" + branchSplit + "rule-set/geosite-geolocation-cn.srs",
|
URL: downloadURL + "SagerNet/sing-geosite" + branchSplit + "rule-set/geosite-geolocation-cn.srs",
|
||||||
DownloadDetour: downloadDetour,
|
DownloadDetour: downloadDetour,
|
||||||
},
|
},
|
||||||
@ -80,13 +82,58 @@ func (t *Template) renderGeoResources(metadata M.Metadata, options *option.Optio
|
|||||||
Type: C.RuleSetTypeRemote,
|
Type: C.RuleSetTypeRemote,
|
||||||
Tag: "geosite-geolocation-!cn",
|
Tag: "geosite-geolocation-!cn",
|
||||||
Format: C.RuleSetFormatBinary,
|
Format: C.RuleSetFormatBinary,
|
||||||
RemoteOptions: option.RemoteRuleSet{
|
RemoteOptions: boxOption.RemoteRuleSet{
|
||||||
URL: downloadURL + "SagerNet/sing-geosite" + branchSplit + "rule-set/geosite-geolocation-!cn.srs",
|
URL: downloadURL + "SagerNet/sing-geosite" + branchSplit + "rule-set/geosite-geolocation-!cn.srs",
|
||||||
DownloadDetour: downloadDetour,
|
DownloadDetour: downloadDetour,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
options.Route.RuleSet = append(options.Route.RuleSet, t.PostCustomRuleSet...)
|
options.Route.RuleSet = append(options.Route.RuleSet, t.renderRuleSet(t.PostRuleSet)...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Template) renderRuleSet(ruleSets []option.RuleSet) []boxOption.RuleSet {
|
||||||
|
var result []boxOption.RuleSet
|
||||||
|
for _, ruleSet := range ruleSets {
|
||||||
|
switch ruleSet.Type {
|
||||||
|
case constant.RuleSetTypeDefault, "":
|
||||||
|
result = append(result, ruleSet.DefaultOptions)
|
||||||
|
case constant.RuleSetTypeGitHub:
|
||||||
|
var (
|
||||||
|
downloadURL string
|
||||||
|
downloadDetour string
|
||||||
|
branchSplit string
|
||||||
|
)
|
||||||
|
if t.EnableJSDelivr {
|
||||||
|
downloadURL = "https://testingcf.jsdelivr.net/gh/"
|
||||||
|
if t.DirectTag != "" {
|
||||||
|
downloadDetour = t.DirectTag
|
||||||
|
} else {
|
||||||
|
downloadDetour = DefaultDirectTag
|
||||||
|
}
|
||||||
|
branchSplit = "@"
|
||||||
|
} else {
|
||||||
|
downloadURL = "https://raw.githubusercontent.com/"
|
||||||
|
branchSplit = "/"
|
||||||
|
}
|
||||||
|
for _, code := range ruleSet.GitHubOptions.RuleSet {
|
||||||
|
result = append(result, boxOption.RuleSet{
|
||||||
|
Type: C.RuleSetTypeRemote,
|
||||||
|
Tag: code,
|
||||||
|
Format: C.RuleSetFormatBinary,
|
||||||
|
RemoteOptions: boxOption.RemoteRuleSet{
|
||||||
|
URL: downloadURL +
|
||||||
|
ruleSet.GitHubOptions.Owner + "/" +
|
||||||
|
ruleSet.GitHubOptions.Repo + "/" +
|
||||||
|
branchSplit +
|
||||||
|
ruleSet.GitHubOptions.Branch + "/" +
|
||||||
|
code + ".srs",
|
||||||
|
DownloadDetour: downloadDetour,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
@ -20,6 +20,10 @@ func (t *Template) renderOutbounds(metadata M.Metadata, options *option.Options,
|
|||||||
if directTag == "" {
|
if directTag == "" {
|
||||||
directTag = DefaultDirectTag
|
directTag = DefaultDirectTag
|
||||||
}
|
}
|
||||||
|
blockTag := t.BlockTag
|
||||||
|
if blockTag == "" {
|
||||||
|
blockTag = DefaultBlockTag
|
||||||
|
}
|
||||||
options.Outbounds = []option.Outbound{
|
options.Outbounds = []option.Outbound{
|
||||||
{
|
{
|
||||||
Tag: directTag,
|
Tag: directTag,
|
||||||
@ -27,7 +31,7 @@ func (t *Template) renderOutbounds(metadata M.Metadata, options *option.Options,
|
|||||||
DirectOptions: common.PtrValueOrDefault(t.CustomDirect),
|
DirectOptions: common.PtrValueOrDefault(t.CustomDirect),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Tag: BlockTag,
|
Tag: blockTag,
|
||||||
Type: C.TypeBlock,
|
Type: C.TypeBlock,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -85,7 +89,7 @@ func (t *Template) renderOutbounds(metadata M.Metadata, options *option.Options,
|
|||||||
selectorOutbound := option.Outbound{
|
selectorOutbound := option.Outbound{
|
||||||
Type: C.TypeSelector,
|
Type: C.TypeSelector,
|
||||||
Tag: it.Name,
|
Tag: it.Name,
|
||||||
SelectorOptions: common.PtrValueOrDefault(t.CustomSelector),
|
SelectorOptions: common.PtrValueOrDefault(it.CustomSelector),
|
||||||
}
|
}
|
||||||
selectorOutbound.SelectorOptions.Outbounds = append(selectorOutbound.SelectorOptions.Outbounds, joinOutbounds...)
|
selectorOutbound.SelectorOptions.Outbounds = append(selectorOutbound.SelectorOptions.Outbounds, joinOutbounds...)
|
||||||
allGroups = append(allGroups, selectorOutbound)
|
allGroups = append(allGroups, selectorOutbound)
|
||||||
@ -171,9 +175,9 @@ func groupJoin(outbounds []option.Outbound, groupTag string, groupOutbounds ...s
|
|||||||
groupOutbound := outbounds[groupIndex]
|
groupOutbound := outbounds[groupIndex]
|
||||||
switch groupOutbound.Type {
|
switch groupOutbound.Type {
|
||||||
case C.TypeSelector:
|
case C.TypeSelector:
|
||||||
groupOutbound.SelectorOptions.Outbounds = append(groupOutbound.SelectorOptions.Outbounds, groupOutbounds...)
|
groupOutbound.SelectorOptions.Outbounds = common.Dup(append(groupOutbound.SelectorOptions.Outbounds, groupOutbounds...))
|
||||||
case C.TypeURLTest:
|
case C.TypeURLTest:
|
||||||
groupOutbound.URLTestOptions.Outbounds = append(groupOutbound.URLTestOptions.Outbounds, groupOutbounds...)
|
groupOutbound.URLTestOptions.Outbounds = common.Dup(append(groupOutbound.URLTestOptions.Outbounds, groupOutbounds...))
|
||||||
}
|
}
|
||||||
outbounds[groupIndex] = groupOutbound
|
outbounds[groupIndex] = groupOutbound
|
||||||
return outbounds
|
return outbounds
|
||||||
|
@ -13,7 +13,7 @@ func (t *Template) renderRoute(metadata M.Metadata, options *option.Options) err
|
|||||||
options.Route = &option.RouteOptions{
|
options.Route = &option.RouteOptions{
|
||||||
GeoIP: t.CustomGeoIP,
|
GeoIP: t.CustomGeoIP,
|
||||||
Geosite: t.CustomGeosite,
|
Geosite: t.CustomGeosite,
|
||||||
RuleSet: t.CustomRuleSet,
|
RuleSet: t.renderRuleSet(t.CustomRuleSet),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !t.DisableTrafficBypass {
|
if !t.DisableTrafficBypass {
|
||||||
@ -45,6 +45,10 @@ func (t *Template) renderRoute(metadata M.Metadata, options *option.Options) err
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
if !t.DisableTrafficBypass && !t.DisableDefaultRules {
|
if !t.DisableTrafficBypass && !t.DisableDefaultRules {
|
||||||
|
blockTag := t.BlockTag
|
||||||
|
if blockTag == "" {
|
||||||
|
blockTag = DefaultBlockTag
|
||||||
|
}
|
||||||
options.Route.Rules = append(options.Route.Rules, option.Rule{
|
options.Route.Rules = append(options.Route.Rules, option.Rule{
|
||||||
Type: C.RuleTypeLogical,
|
Type: C.RuleTypeLogical,
|
||||||
LogicalOptions: option.LogicalRule{
|
LogicalOptions: option.LogicalRule{
|
||||||
@ -64,7 +68,7 @@ func (t *Template) renderRoute(metadata M.Metadata, options *option.Options) err
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Outbound: BlockTag,
|
Outbound: blockTag,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,9 @@ const (
|
|||||||
DNSFakeIPTag = "remote"
|
DNSFakeIPTag = "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"
|
||||||
BlockTag = "block"
|
DefaultBlockTag = "block"
|
||||||
DNSTag = "dns"
|
DNSTag = "dns"
|
||||||
DefaultURLTestTag = "URLTest"
|
DefaultURLTestTag = "URLTest"
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user