Add support for rule actions

This commit is contained in:
世界 2024-11-16 20:02:39 +08:00
parent d2f1118c2e
commit 1649ae16e4
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
15 changed files with 317 additions and 312 deletions

View File

@ -5,7 +5,7 @@ import (
"os"
"time"
box "github.com/sagernet/sing-box"
"github.com/sagernet/sing-box"
"github.com/sagernet/sing-box/include"
_ "github.com/sagernet/sing-box/include"
"github.com/sagernet/sing-box/log"

View File

@ -31,7 +31,7 @@ RuleSet generate configuration.
{
"type": "github",
"repository": "SagerNet/sing-geosite",
"path": "rule-set",
"path": "rule-set/geosite-",
"prefix": "geosite-",
"rule_set": [
"apple",
@ -47,7 +47,7 @@ RuleSet generate configuration.
{
"type": "github",
"repository": "MetaCubeX/meta-rules-dat",
"path": "sing/geo/geosite",
"path": "sing/geo/geosite/",
"prefix": "geosite-",
"rule_set": [
"apple",

View File

@ -11,7 +11,8 @@
"domain_strategy": "",
"domain_strategy_local": "",
"disable_traffic_bypass": false,
"disable_rule_set": false,
"disable_sniff": false,
"disable_rule_action": false,
"remote_resolve": false,
// DNS
@ -113,9 +114,13 @@ Local sing-box domain strategy.
`prefer_ipv4` is used by default.
#### disable_rule_set
#### disable_sniff
Use `geoip` and `geosite` for traffic bypassing instead of rule sets.
Don`t generate protocol sniffing options.
#### disable_rule_action
Don`t generate rule action options.
#### disable_traffic_bypass

22
go.mod
View File

@ -11,13 +11,13 @@ require (
github.com/go-chi/render v1.0.3
github.com/miekg/dns v1.1.62
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
github.com/sagernet/sing v0.5.1-0.20241107131656-6e1285b5d82f
github.com/sagernet/sing-box v1.10.2-0.20241107134520-fead0e42505f
github.com/sagernet/sing-dns v0.3.1-0.20241105104342-1914f319ddab
github.com/sagernet/sing v0.6.0-alpha.16
github.com/sagernet/sing-box v1.11.0-alpha.17
github.com/sagernet/sing-dns v0.4.0-alpha.2
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
golang.org/x/mod v0.21.0
golang.org/x/net v0.30.0
golang.org/x/net v0.31.0
)
require (
@ -68,12 +68,12 @@ require (
github.com/sagernet/nftables v0.3.0-beta.4 // indirect
github.com/sagernet/quic-go v0.48.1-beta.1 // indirect
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect
github.com/sagernet/sing-mux v0.2.1-0.20241020175909-fe6153f7a9ec // indirect
github.com/sagernet/sing-quic v0.3.0-rc.2 // indirect
github.com/sagernet/sing-mux v0.3.0-alpha.1 // indirect
github.com/sagernet/sing-quic v0.4.0-alpha.3 // indirect
github.com/sagernet/sing-shadowsocks v0.2.7 // indirect
github.com/sagernet/sing-shadowsocks2 v0.2.0 // indirect
github.com/sagernet/sing-shadowtls v0.1.4 // indirect
github.com/sagernet/sing-tun v0.4.0-rc.5.0.20241107062822-5a91eb99c90f // indirect
github.com/sagernet/sing-tun v0.6.0-alpha.8 // indirect
github.com/sagernet/sing-vmess v0.1.12 // indirect
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 // indirect
github.com/sagernet/utls v1.6.7 // indirect
@ -91,11 +91,11 @@ require (
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
golang.org/x/crypto v0.28.0 // indirect
golang.org/x/crypto v0.29.0 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/sync v0.9.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/text v0.20.0 // indirect
golang.org/x/time v0.7.0 // indirect
golang.org/x/tools v0.24.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect

48
go.sum
View File

@ -121,24 +121,24 @@ github.com/sagernet/quic-go v0.48.1-beta.1/go.mod h1:1WgdDIVD1Gybp40JTWketeSfKA/
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
github.com/sagernet/sing v0.5.1-0.20241107131656-6e1285b5d82f h1:A6+OeV5P1mok0eEEbLh4PidymZ6VZnTZ2uHwfapXgdU=
github.com/sagernet/sing v0.5.1-0.20241107131656-6e1285b5d82f/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/sagernet/sing-box v1.10.2-0.20241107134520-fead0e42505f h1:CkGSNvQvZlzm5VuKmc23DiY2WxxHbp1jYux0fh3xRW4=
github.com/sagernet/sing-box v1.10.2-0.20241107134520-fead0e42505f/go.mod h1:3Ujxk8+gNR1Kve68iZFjzxDHLGrFODdsvnth8oakrwk=
github.com/sagernet/sing-dns v0.3.1-0.20241105104342-1914f319ddab h1:djP4EY/KM5T62xscormLflVi7eDlHv6p7md1FHMSArE=
github.com/sagernet/sing-dns v0.3.1-0.20241105104342-1914f319ddab/go.mod h1:TqLIelI+FAbVEdiTRolhGLOwvhVjY7oT+wezlOJUQ7M=
github.com/sagernet/sing-mux v0.2.1-0.20241020175909-fe6153f7a9ec h1:6Fd/VsEsw9qIjaGi1IBTZSb4b4v5JYtNcoiBtGsQC48=
github.com/sagernet/sing-mux v0.2.1-0.20241020175909-fe6153f7a9ec/go.mod h1:RSwqqHwbtTOX3vs6ms8vMtBGH/0ZNyLm/uwt6TlmR84=
github.com/sagernet/sing-quic v0.3.0-rc.2 h1:7vcC4bdS1GBJzHZhfmJiH0CfzQ4mYLUW51Z2RNHcGwc=
github.com/sagernet/sing-quic v0.3.0-rc.2/go.mod h1:3UOq51WVqzra7eCgod7t4hqnTaOiZzFUci9avMrtOqs=
github.com/sagernet/sing v0.6.0-alpha.16 h1:Ml+nJa8J9d+Svqv2pBvJoet+8PF302Snb6wcMUXaoy4=
github.com/sagernet/sing v0.6.0-alpha.16/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/sagernet/sing-box v1.11.0-alpha.17 h1:j7+LwRgXvcs1qqmNcj0ckQTzBnEl9FO3eEc5AQOdj3g=
github.com/sagernet/sing-box v1.11.0-alpha.17/go.mod h1:5Gekm6mVOgaL+9JTmNu0vngMuSltxwjLUiHLCQ6gc6w=
github.com/sagernet/sing-dns v0.4.0-alpha.2 h1:0x5WjrO+Ifk9sqJlHRz/tKENHwoEinQ8HQCHAhpJHAQ=
github.com/sagernet/sing-dns v0.4.0-alpha.2/go.mod h1:ZiXcacKL54jSSYZMbYF3qKNFkkW674Jt+85YCmK64K8=
github.com/sagernet/sing-mux v0.3.0-alpha.1 h1:IgNX5bJBpL41gGbp05pdDOvh/b5eUQ6cv9240+Ngipg=
github.com/sagernet/sing-mux v0.3.0-alpha.1/go.mod h1:FTcImmdfW38Lz7b+HQ+mxxOth1lz4ao8uEnz+MwIJQE=
github.com/sagernet/sing-quic v0.4.0-alpha.3 h1:2svvOqgQCJg7FNrIrLTaRB6oDzXPiIyWIt9csjZxD6Q=
github.com/sagernet/sing-quic v0.4.0-alpha.3/go.mod h1:Fmnpy0XoyYdjJrxNqEyl3LC9uLibMNNbxG7dt6HATY4=
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wKFHi+8XwgADg=
github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
github.com/sagernet/sing-tun v0.4.0-rc.5.0.20241107062822-5a91eb99c90f h1:gQwTgN/E4oHe3VlseD3/RhPs866cWcTsPG4dP6a8f8o=
github.com/sagernet/sing-tun v0.4.0-rc.5.0.20241107062822-5a91eb99c90f/go.mod h1:Ehs5mZ3T8tTgV3H1Tx4Va5ixvyKjTAUPJ3G11dq7B/g=
github.com/sagernet/sing-tun v0.6.0-alpha.8 h1:HhXyUvXxtaXgT+IILZMq6kbrAyDbUwbN+Df/XxpL7Vo=
github.com/sagernet/sing-tun v0.6.0-alpha.8/go.mod h1:JkgiLLnQUXln1zLGVoJqUwAulJGT0xoiPU4/pYF1fhU=
github.com/sagernet/sing-vmess v0.1.12 h1:2gFD8JJb+eTFMoa8FIVMnknEi+vCSfaiTXTfEYAYAPg=
github.com/sagernet/sing-vmess v0.1.12/go.mod h1:luTSsfyBGAc9VhtCqwjR+dt1QgqBhuYBCONB/POhF8I=
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ=
@ -188,18 +188,18 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -210,15 +210,15 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View File

@ -36,10 +36,10 @@ func (o *Options) UnmarshalJSONContext(ctx context.Context, content []byte) erro
}
type User struct {
Name string `json:"name,omitempty"`
Password string `json:"password,omitempty"`
Profile option.Listable[string] `json:"profile,omitempty"`
DefaultProfile string `json:"default_profile,omitempty"`
Name string `json:"name,omitempty"`
Password string `json:"password,omitempty"`
Profile badoption.Listable[string] `json:"profile,omitempty"`
DefaultProfile string `json:"default_profile,omitempty"`
}
const (
@ -47,24 +47,24 @@ const (
)
type Subscription struct {
Name string `json:"name,omitempty"`
URL string `json:"url,omitempty"`
UserAgent string `json:"user_agent,omitempty"`
UpdateInterval option.Duration `json:"update_interval,omitempty"`
Process option.Listable[OutboundProcessOptions] `json:"process,omitempty"`
DeDuplication bool `json:"deduplication,omitempty"`
GenerateSelector bool `json:"generate_selector,omitempty"`
GenerateURLTest bool `json:"generate_urltest,omitempty"`
URLTestTagSuffix string `json:"urltest_suffix,omitempty"`
CustomSelector *option.SelectorOutboundOptions `json:"custom_selector,omitempty"`
CustomURLTest *option.URLTestOutboundOptions `json:"custom_urltest,omitempty"`
Name string `json:"name,omitempty"`
URL string `json:"url,omitempty"`
UserAgent string `json:"user_agent,omitempty"`
UpdateInterval badoption.Duration `json:"update_interval,omitempty"`
Process badoption.Listable[OutboundProcessOptions] `json:"process,omitempty"`
DeDuplication bool `json:"deduplication,omitempty"`
GenerateSelector bool `json:"generate_selector,omitempty"`
GenerateURLTest bool `json:"generate_urltest,omitempty"`
URLTestTagSuffix string `json:"urltest_suffix,omitempty"`
CustomSelector *option.SelectorOutboundOptions `json:"custom_selector,omitempty"`
CustomURLTest *option.URLTestOutboundOptions `json:"custom_urltest,omitempty"`
}
type OutboundProcessOptions struct {
Filter option.Listable[string] `json:"filter,omitempty"`
Exclude option.Listable[string] `json:"exclude,omitempty"`
FilterType option.Listable[string] `json:"filter_type,omitempty"`
ExcludeType option.Listable[string] `json:"exclude_type,omitempty"`
Filter badoption.Listable[string] `json:"filter,omitempty"`
Exclude badoption.Listable[string] `json:"exclude,omitempty"`
FilterType badoption.Listable[string] `json:"filter_type,omitempty"`
ExcludeType badoption.Listable[string] `json:"exclude_type,omitempty"`
Invert bool `json:"invert,omitempty"`
Remove bool `json:"remove,omitempty"`
Rename *badjson.TypedMap[string, string] `json:"rename,omitempty"`
@ -77,6 +77,6 @@ type Profile struct {
Template string `json:"template,omitempty"`
TemplateForPlatform *badjson.TypedMap[string, string] `json:"template_for_platform,omitempty"`
TemplateForUserAgent *badjson.TypedMap[string, string] `json:"template_for_user_agent,omitempty"`
Outbound option.Listable[string] `json:"outbound,omitempty"`
Subscription option.Listable[string] `json:"subscription,omitempty"`
Outbound badoption.Listable[string] `json:"outbound,omitempty"`
Subscription badoption.Listable[string] `json:"subscription,omitempty"`
}

View File

@ -9,6 +9,7 @@ import (
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/badoption"
)
type _Template struct {
@ -22,7 +23,8 @@ type _Template struct {
DomainStrategy option.DomainStrategy `json:"domain_strategy,omitempty"`
DomainStrategyLocal option.DomainStrategy `json:"domain_strategy_local,omitempty"`
DisableTrafficBypass bool `json:"disable_traffic_bypass,omitempty"`
DisableRuleSet bool `json:"disable_rule_set,omitempty"`
DisableSniff bool `json:"disable_sniff,omitempty"`
DisableRuleAction bool `json:"disable_rule_action,omitempty"`
RemoteResolve bool `json:"remote_resolve,omitempty"`
// DNS
@ -53,14 +55,12 @@ type _Template struct {
CustomURLTest *option.URLTestOutboundOptions `json:"custom_urltest,omitempty"`
// Route
DisableDefaultRules bool `json:"disable_default_rules,omitempty"`
PreRules []option.Rule `json:"pre_rules,omitempty"`
CustomRules []option.Rule `json:"custom_rules,omitempty"`
EnableJSDelivr bool `json:"enable_jsdelivr,omitempty"`
CustomGeoIP *option.GeoIPOptions `json:"custom_geoip,omitempty"`
CustomGeosite *option.GeositeOptions `json:"custom_geosite,omitempty"`
CustomRuleSet []RuleSet `json:"custom_rule_set,omitempty"`
PostRuleSet []RuleSet `json:"post_rule_set,omitempty"`
DisableDefaultRules bool `json:"disable_default_rules,omitempty"`
PreRules []option.Rule `json:"pre_rules,omitempty"`
CustomRules []option.Rule `json:"custom_rules,omitempty"`
EnableJSDelivr bool `json:"enable_jsdelivr,omitempty"`
CustomRuleSet []RuleSet `json:"custom_rule_set,omitempty"`
PostRuleSet []RuleSet `json:"post_rule_set,omitempty"`
// Experimental
DisableCacheFile bool `json:"disable_cache_file,omitempty"`
@ -122,10 +122,10 @@ func (r *RuleSet) UnmarshalJSON(content []byte) error {
}
type GitHubRuleSetOptions struct {
Repository string `json:"repository,omitempty"`
Path string `json:"path,omitempty"`
Prefix string `json:"prefix,omitempty"`
RuleSet option.Listable[string] `json:"rule_set,omitempty"`
Repository string `json:"repository,omitempty"`
Path string `json:"path,omitempty"`
Prefix string `json:"prefix,omitempty"`
RuleSet badoption.Listable[string] `json:"rule_set,omitempty"`
}
func (t Template) DisableIPv6() bool {
@ -137,8 +137,8 @@ type ExtraGroup struct {
Target ExtraGroupTarget `json:"target,omitempty"`
TagPerSubscription string `json:"tag_per_subscription,omitempty"`
Type string `json:"type,omitempty"`
Filter option.Listable[string] `json:"filter,omitempty"`
Exclude option.Listable[string] `json:"exclude,omitempty"`
Filter badoption.Listable[string] `json:"filter,omitempty"`
Exclude badoption.Listable[string] `json:"exclude,omitempty"`
CustomSelector *option.SelectorOutboundOptions `json:"custom_selector,omitempty"`
CustomURLTest *option.URLTestOutboundOptions `json:"custom_urltest,omitempty"`
}

View File

@ -138,9 +138,16 @@ func (p *Profile) Render(metadata metadata.Metadata) (*boxOption.Options, error)
outbounds := common.Filter(p.manager.outbounds, func(it []boxOption.Outbound) bool {
return common.Contains(p.Outbound, it[0].Tag)
})
subscriptions := common.Filter(p.manager.subscription.Subscriptions(), func(it *subscription.Subscription) bool {
return common.Contains(p.Subscription, it.Name)
})
var subscriptions []*subscription.Subscription
for _, subscriptionName := range p.Subscription {
subscription := common.Find(p.manager.subscription.Subscriptions(), func(it *subscription.Subscription) bool {
return it.Name == subscriptionName
})
if subscription == nil {
return nil, E.New("render profile[", p.Name, "]: subscription not found: ", subscriptionName)
}
subscriptions = append(subscriptions, subscription)
}
options, err := selectedTemplate.Render(p.manager.ctx, metadata, p.Name, outbounds, subscriptions)
if err != nil {
return nil, err

View File

@ -8,6 +8,7 @@ import (
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/json/badoption"
N "github.com/sagernet/sing/common/network"
"github.com/Dreamacro/clash/adapter"
@ -224,10 +225,10 @@ func clashPluginOptions(plugin string, opts map[string]any) string {
func clashTransport(network string, httpOpts clash_outbound.HTTPOptions, h2Opts clash_outbound.HTTP2Options, grpcOpts clash_outbound.GrpcOptions, wsOpts clash_outbound.WSOptions) *option.V2RayTransportOptions {
switch network {
case "http":
var headers map[string]option.Listable[string]
var headers map[string]badoption.Listable[string]
for key, values := range httpOpts.Headers {
if headers == nil {
headers = make(map[string]option.Listable[string])
headers = make(map[string]badoption.Listable[string])
}
headers[key] = values
}
@ -255,10 +256,10 @@ func clashTransport(network string, httpOpts clash_outbound.HTTPOptions, h2Opts
},
}
case "ws":
var headers map[string]option.Listable[string]
var headers map[string]badoption.Listable[string]
for key, value := range wsOpts.Headers {
if headers == nil {
headers = make(map[string]option.Listable[string])
headers = make(map[string]badoption.Listable[string])
}
headers[key] = []string{value}
}

View File

@ -19,8 +19,15 @@ func TestFilter1100(t *testing.T) {
{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultDNSRule{
RuleSet: []string{"test"},
Server: "test",
RawDefaultDNSRule: option.RawDefaultDNSRule{
RuleSet: []string{"test"},
},
DNSRuleAction: option.DNSRuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.DNSRouteActionOptions{
Server: "test",
},
},
},
},
},
@ -30,8 +37,15 @@ func TestFilter1100(t *testing.T) {
{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
RuleSet: []string{"test"},
Outbound: "test",
RawDefaultRule: option.RawDefaultRule{
Domain: []string{"example.com"},
},
RuleAction: option.RuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.RouteActionOptions{
Outbound: "test",
},
},
},
},
},
@ -61,8 +75,15 @@ func TestFilter1100(t *testing.T) {
{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultDNSRule{
Domain: []string{"example.com"},
Server: "test",
RawDefaultDNSRule: option.RawDefaultDNSRule{
Domain: []string{"example.com"},
},
DNSRuleAction: option.DNSRuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.DNSRouteActionOptions{
Server: "test",
},
},
},
},
},
@ -72,8 +93,15 @@ func TestFilter1100(t *testing.T) {
{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
Domain: []string{"example.com"},
Outbound: "test",
RawDefaultRule: option.RawDefaultRule{
Domain: []string{"example.com"},
},
RuleAction: option.RuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.RouteActionOptions{
Outbound: "test",
},
},
},
},
},

View File

@ -167,37 +167,21 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error
options.DNS.Rules = append(options.DNS.Rules, t.PreDNSRules...)
if len(t.CustomDNSRules) == 0 {
if !t.DisableTrafficBypass {
if t.DisableRuleSet || (metadata.Version != nil && metadata.Version.LessThan(semver.ParseVersion("1.8.0-alpha.10"))) {
options.DNS.Rules = append(options.DNS.Rules, option.DNSRule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultDNSRule{
RawDefaultDNSRule: option.RawDefaultDNSRule{
Geosite: []string{"geolocation-cn"},
},
DNSRuleAction: option.DNSRuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.DNSRouteActionOptions{
Server: DNSLocalTag,
},
options.DNS.Rules = append(options.DNS.Rules, option.DNSRule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultDNSRule{
RawDefaultDNSRule: option.RawDefaultDNSRule{
RuleSet: []string{"geosite-geolocation-cn"},
},
DNSRuleAction: option.DNSRuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.DNSRouteActionOptions{
Server: DNSLocalTag,
},
},
})
} else {
options.DNS.Rules = append(options.DNS.Rules, option.DNSRule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultDNSRule{
RawDefaultDNSRule: option.RawDefaultDNSRule{
RuleSet: []string{"geosite-geolocation-cn"},
},
DNSRuleAction: option.DNSRuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.DNSRouteActionOptions{
Server: DNSLocalTag,
},
},
},
})
}
},
})
if !t.DisableDNSLeak && (metadata.Version == nil || metadata.Version.GreaterThanOrEqual(semver.ParseVersion("1.9.0-alpha.1"))) {
options.DNS.Rules = append(options.DNS.Rules, option.DNSRule{
Type: C.RuleTypeDefault,
@ -224,12 +208,6 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error
RawDefaultDNSRule: option.RawDefaultDNSRule{
RuleSet: []string{"geosite-geolocation-!cn"},
},
DNSRuleAction: option.DNSRuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.DNSRouteActionOptions{
Server: DNSDefaultTag,
},
},
},
},
{
@ -238,12 +216,6 @@ func (t *Template) renderDNS(metadata M.Metadata, options *option.Options) error
RawDefaultDNSRule: option.RawDefaultDNSRule{
RuleSet: []string{"geoip-cn"},
},
DNSRuleAction: option.DNSRuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.DNSRouteActionOptions{
Server: DNSLocalTag,
},
},
},
},
},

View File

@ -2,7 +2,6 @@ package template
import (
M "github.com/sagernet/serenity/common/metadata"
"github.com/sagernet/serenity/common/semver"
"github.com/sagernet/serenity/constant"
"github.com/sagernet/serenity/option"
C "github.com/sagernet/sing-box/constant"
@ -10,87 +9,55 @@ import (
)
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 len(t.CustomRuleSet) == 0 {
var (
geoipDownloadURL string
geositeDownloadURL string
downloadDetour string
downloadURL string
downloadDetour string
branchSplit string
)
if t.EnableJSDelivr {
geoipDownloadURL = "https://testingcf.jsdelivr.net/gh/SagerNet/sing-geoip@release/geoip-cn.db"
geositeDownloadURL = "https://testingcf.jsdelivr.net/gh/SagerNet/sing-geosite@release/geosite-cn.db"
downloadURL = "https://testingcf.jsdelivr.net/gh/"
if t.DirectTag != "" {
downloadDetour = t.DirectTag
} else {
downloadDetour = DefaultDirectTag
}
branchSplit = "@"
} else {
geoipDownloadURL = "https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip-cn.db"
geositeDownloadURL = "https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite-cn.db"
downloadURL = "https://raw.githubusercontent.com/"
branchSplit = "/"
}
if t.CustomGeoIP == nil {
options.Route.GeoIP = &boxOption.GeoIPOptions{
DownloadURL: geoipDownloadURL,
DownloadDetour: downloadDetour,
}
}
if t.CustomGeosite == nil {
options.Route.Geosite = &boxOption.GeositeOptions{
DownloadURL: geositeDownloadURL,
DownloadDetour: downloadDetour,
}
}
} else {
if len(t.CustomRuleSet) == 0 {
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 = "/"
}
options.Route.RuleSet = []boxOption.RuleSet{
{
Type: C.RuleSetTypeRemote,
Tag: "geoip-cn",
Format: C.RuleSetFormatBinary,
RemoteOptions: boxOption.RemoteRuleSet{
URL: downloadURL + "SagerNet/sing-geoip" + branchSplit + "rule-set/geoip-cn.srs",
DownloadDetour: downloadDetour,
},
options.Route.RuleSet = []boxOption.RuleSet{
{
Type: C.RuleSetTypeRemote,
Tag: "geoip-cn",
Format: C.RuleSetFormatBinary,
RemoteOptions: boxOption.RemoteRuleSet{
URL: downloadURL + "SagerNet/sing-geoip" + branchSplit + "rule-set/geoip-cn.srs",
DownloadDetour: downloadDetour,
},
{
Type: C.RuleSetTypeRemote,
Tag: "geosite-geolocation-cn",
Format: C.RuleSetFormatBinary,
RemoteOptions: boxOption.RemoteRuleSet{
URL: downloadURL + "SagerNet/sing-geosite" + branchSplit + "rule-set/geosite-geolocation-cn.srs",
DownloadDetour: downloadDetour,
},
},
{
Type: C.RuleSetTypeRemote,
Tag: "geosite-geolocation-cn",
Format: C.RuleSetFormatBinary,
RemoteOptions: boxOption.RemoteRuleSet{
URL: downloadURL + "SagerNet/sing-geosite" + branchSplit + "rule-set/geosite-geolocation-cn.srs",
DownloadDetour: downloadDetour,
},
{
Type: C.RuleSetTypeRemote,
Tag: "geosite-geolocation-!cn",
Format: C.RuleSetFormatBinary,
RemoteOptions: boxOption.RemoteRuleSet{
URL: downloadURL + "SagerNet/sing-geosite" + branchSplit + "rule-set/geosite-geolocation-!cn.srs",
DownloadDetour: downloadDetour,
},
},
{
Type: C.RuleSetTypeRemote,
Tag: "geosite-geolocation-!cn",
Format: C.RuleSetFormatBinary,
RemoteOptions: boxOption.RemoteRuleSet{
URL: downloadURL + "SagerNet/sing-geosite" + branchSplit + "rule-set/geosite-geolocation-!cn.srs",
DownloadDetour: downloadDetour,
},
}
},
}
options.Route.RuleSet = append(options.Route.RuleSet, t.renderRuleSet(t.PostRuleSet)...)
}
options.Route.RuleSet = append(options.Route.RuleSet, t.renderRuleSet(t.PostRuleSet)...)
}
func (t *Template) renderRuleSet(ruleSets []option.RuleSet) []boxOption.RuleSet {

View File

@ -9,16 +9,14 @@ import (
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-dns"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/json/badjson"
"github.com/sagernet/sing/common/json/badoption"
)
func (t *Template) renderInbounds(metadata M.Metadata, options *option.Options) error {
options.Inbounds = t.Inbounds
var needSniff bool
if !t.DisableTrafficBypass {
needSniff = true
}
var domainStrategy option.DomainStrategy
if !t.RemoteResolve {
if t.DomainStrategy != option.DomainStrategy(dns.DomainStrategyAsIS) {
@ -27,6 +25,7 @@ func (t *Template) renderInbounds(metadata M.Metadata, options *option.Options)
domainStrategy = option.DomainStrategy(dns.DomainStrategyPreferIPv4)
}
}
disableRuleAction := t.DisableRuleAction || (metadata.Version != nil && metadata.Version.LessThan(semver.ParseVersion("1.11.0-alpha.7")))
autoRedirect := t.AutoRedirect &&
!metadata.Platform.IsApple() &&
(metadata.Version == nil || metadata.Version.GreaterThanOrEqual(semver.ParseVersion("1.10.0-alpha.2")))
@ -40,9 +39,6 @@ func (t *Template) renderInbounds(metadata M.Metadata, options *option.Options)
tunOptions := &option.TunInboundOptions{
AutoRoute: true,
Address: address,
InboundOptions: option.InboundOptions{
SniffEnabled: needSniff,
},
}
tunInbound := option.Inbound{
Type: C.TypeTun,
@ -54,12 +50,17 @@ func (t *Template) renderInbounds(metadata M.Metadata, options *option.Options)
tunOptions.RouteExcludeAddressSet = []string{"geoip-cn"}
}
}
if t.EnableFakeIP {
tunOptions.DomainStrategy = domainStrategy
}
if metadata.Platform == M.PlatformUnknown {
tunOptions.StrictRoute = true
}
if disableRuleAction {
tunOptions.InboundOptions = option.InboundOptions{
SniffEnabled: !t.DisableSniff,
}
if t.EnableFakeIP {
tunOptions.DomainStrategy = domainStrategy
}
}
if !t.DisableSystemProxy && metadata.Platform != M.PlatformUnknown {
var httpPort uint16
if t.CustomMixed != nil {
@ -90,15 +91,17 @@ func (t *Template) renderInbounds(metadata M.Metadata, options *option.Options)
if disableTun || !t.DisableSystemProxy {
mixedOptions := &option.HTTPMixedInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.AddrFrom4([4]byte{127, 0, 0, 1})),
Listen: common.Ptr(badoption.Addr(netip.AddrFrom4([4]byte{127, 0, 0, 1}))),
ListenPort: DefaultMixedPort,
InboundOptions: option.InboundOptions{
SniffEnabled: needSniff,
DomainStrategy: domainStrategy,
},
},
SetSystemProxy: metadata.Platform == M.PlatformUnknown && disableTun && !t.DisableSystemProxy,
}
if disableRuleAction {
mixedOptions.InboundOptions = option.InboundOptions{
SniffEnabled: !t.DisableSniff,
DomainStrategy: domainStrategy,
}
}
mixedInbound := option.Inbound{
Type: C.TypeMixed,
Options: mixedOptions,

View File

@ -6,6 +6,7 @@ import (
"text/template"
M "github.com/sagernet/serenity/common/metadata"
"github.com/sagernet/serenity/common/semver"
"github.com/sagernet/serenity/option"
"github.com/sagernet/serenity/subscription"
C "github.com/sagernet/sing-box/constant"
@ -16,6 +17,7 @@ import (
)
func (t *Template) renderOutbounds(metadata M.Metadata, options *boxOption.Options, outbounds [][]boxOption.Outbound, subscriptions []*subscription.Subscription) error {
disableRuleAction := t.DisableRuleAction || (metadata.Version != nil && metadata.Version.LessThan(semver.ParseVersion("1.11.0-alpha.7")))
defaultTag := t.DefaultTag
if defaultTag == "" {
defaultTag = DefaultDefaultTag
@ -35,22 +37,26 @@ func (t *Template) renderOutbounds(metadata M.Metadata, options *boxOption.Optio
Type: C.TypeDirect,
Options: common.Ptr(common.PtrValueOrDefault(t.CustomDirect)),
},
{
Tag: blockTag,
Type: C.TypeBlock,
Options: &boxOption.StubOptions{},
},
{
Tag: DNSTag,
Type: C.TypeDNS,
Options: &boxOption.StubOptions{},
},
{
Tag: defaultTag,
Type: C.TypeSelector,
Options: common.Ptr(common.PtrValueOrDefault(t.CustomSelector)),
},
}
if disableRuleAction {
options.Outbounds = append(options.Outbounds,
boxOption.Outbound{
Tag: blockTag,
Type: C.TypeBlock,
Options: &boxOption.StubOptions{},
},
boxOption.Outbound{
Tag: DNSTag,
Type: C.TypeDNS,
Options: &boxOption.StubOptions{},
},
)
}
urlTestTag := t.URLTestTag
if urlTestTag == "" {
urlTestTag = DefaultURLTestTag

View File

@ -11,49 +11,90 @@ import (
func (t *Template) renderRoute(metadata M.Metadata, options *option.Options) error {
if options.Route == nil {
options.Route = &option.RouteOptions{
GeoIP: t.CustomGeoIP,
Geosite: t.CustomGeosite,
RuleSet: t.renderRuleSet(t.CustomRuleSet),
}
}
if !t.DisableTrafficBypass {
t.renderGeoResources(metadata, options)
}
disable18Features := metadata.Version != nil && metadata.Version.LessThan(semver.ParseVersion("1.8.0-alpha.10"))
options.Route.Rules = []option.Rule{
{
Type: C.RuleTypeLogical,
LogicalOptions: option.LogicalRule{
RawLogicalRule: option.RawLogicalRule{
Mode: C.LogicalTypeOr,
Rules: []option.Rule{
{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
RawDefaultRule: option.RawDefaultRule{
Network: []string{N.NetworkUDP},
Port: []uint16{53},
disableRuleAction := t.DisableRuleAction || (metadata.Version != nil && metadata.Version.LessThan(semver.ParseVersion("1.11.0-alpha.7")))
if disableRuleAction {
options.Route.Rules = []option.Rule{
{
Type: C.RuleTypeLogical,
LogicalOptions: option.LogicalRule{
RawLogicalRule: option.RawLogicalRule{
Mode: C.LogicalTypeOr,
Rules: []option.Rule{
{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
RawDefaultRule: option.RawDefaultRule{
Network: []string{N.NetworkUDP},
Port: []uint16{53},
},
},
},
},
{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
RawDefaultRule: option.RawDefaultRule{
Protocol: []string{C.ProtocolDNS},
{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
RawDefaultRule: option.RawDefaultRule{
Protocol: []string{C.ProtocolDNS},
},
},
},
},
},
},
RuleAction: option.RuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.RouteActionOptions{
Outbound: DNSTag,
RuleAction: option.RuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.RouteActionOptions{
Outbound: DNSTag,
},
},
},
},
},
}
} else {
options.Route.Rules = []option.Rule{
{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
RuleAction: option.RuleAction{
Action: C.RuleActionTypeSniff,
},
},
},
{
Type: C.RuleTypeLogical,
LogicalOptions: option.LogicalRule{
RawLogicalRule: option.RawLogicalRule{
Mode: C.LogicalTypeOr,
Rules: []option.Rule{
{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
RawDefaultRule: option.RawDefaultRule{
Network: []string{N.NetworkUDP},
Port: []uint16{53},
},
},
},
{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
RawDefaultRule: option.RawDefaultRule{
Protocol: []string{C.ProtocolDNS},
},
},
},
},
},
RuleAction: option.RuleAction{
Action: C.RuleActionTypeHijackDNS,
},
},
},
}
}
directTag := t.DirectTag
defaultTag := t.DefaultTag
@ -63,37 +104,20 @@ func (t *Template) renderRoute(metadata M.Metadata, options *option.Options) err
if defaultTag == "" {
defaultTag = DefaultDefaultTag
}
if disable18Features {
options.Route.Rules = append(options.Route.Rules, option.Rule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
RawDefaultRule: option.RawDefaultRule{
GeoIP: []string{"private"},
},
RuleAction: option.RuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.RouteActionOptions{
Outbound: directTag,
},
options.Route.Rules = append(options.Route.Rules, option.Rule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
RawDefaultRule: option.RawDefaultRule{
IPIsPrivate: true,
},
RuleAction: option.RuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.RouteActionOptions{
Outbound: directTag,
},
},
})
} else {
options.Route.Rules = append(options.Route.Rules, option.Rule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
RawDefaultRule: option.RawDefaultRule{
IPIsPrivate: true,
},
RuleAction: option.RuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.RouteActionOptions{
Outbound: directTag,
},
},
},
})
}
},
})
if !t.DisableClashMode {
modeGlobal := t.ClashModeGlobal
modeDirect := t.ClashModeDirect
@ -131,41 +155,33 @@ func (t *Template) renderRoute(metadata M.Metadata, options *option.Options) err
},
})
}
if disableRuleAction {
options.Route.Rules = append(options.Route.Rules, option.Rule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
RuleAction: option.RuleAction{
Action: C.RuleActionTypeResolve,
},
},
})
}
options.Route.Rules = append(options.Route.Rules, t.PreRules...)
if len(t.CustomRules) == 0 {
if !t.DisableTrafficBypass {
if t.DisableRuleSet || disable18Features {
options.Route.Rules = append(options.Route.Rules, option.Rule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
RawDefaultRule: option.RawDefaultRule{
GeoIP: []string{"cn"},
Geosite: []string{"geolocation-cn"},
},
RuleAction: option.RuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.RouteActionOptions{
Outbound: directTag,
},
options.Route.Rules = append(options.Route.Rules, option.Rule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
RawDefaultRule: option.RawDefaultRule{
RuleSet: []string{"geoip-cn", "geosite-geolocation-cn"},
},
RuleAction: option.RuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.RouteActionOptions{
Outbound: directTag,
},
},
})
} else {
options.Route.Rules = append(options.Route.Rules, option.Rule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
RawDefaultRule: option.RawDefaultRule{
RuleSet: []string{"geoip-cn", "geosite-geolocation-cn"},
},
RuleAction: option.RuleAction{
Action: C.RuleActionTypeRoute,
RouteOptions: option.RouteActionOptions{
Outbound: directTag,
},
},
},
})
}
},
})
}
} else {
options.Route.Rules = append(options.Route.Rules, t.CustomRules...)