Fix override logic
This commit is contained in:
@@ -37,8 +37,15 @@ func create(configPath *C.char) *C.char {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return C.CString(err.Error())
|
return C.CString(err.Error())
|
||||||
}
|
}
|
||||||
overrides := shared.ConfigOverrides{ExcludeTunInbound: true, IncludeMixedInbound: true, IncludeLogOutput: true, LogLevel: "info", IncludeLogTimestamp: false, ClashApiPort: 9090}
|
overrides := shared.ConfigOverrides{
|
||||||
options = shared.ApplyOverrides(options, overrides)
|
LogOutput: shared.StringAddr("box.log"),
|
||||||
|
EnableTun: shared.BoolAddr(false),
|
||||||
|
SetSystemProxy: shared.BoolAddr(true),
|
||||||
|
}
|
||||||
|
template := shared.DefaultTemplate(overrides)
|
||||||
|
options = shared.ApplyOverrides(template, options, overrides)
|
||||||
|
|
||||||
|
shared.SaveCurrentConfig(sWorkingPath, options)
|
||||||
|
|
||||||
instance, err := NewService(options)
|
instance, err := NewService(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -6,6 +6,7 @@ require (
|
|||||||
github.com/sagernet/gomobile v0.0.0-20230728014906-3de089147f59
|
github.com/sagernet/gomobile v0.0.0-20230728014906-3de089147f59
|
||||||
github.com/sagernet/sing v0.2.10-0.20230807080248-4db0062caa0a
|
github.com/sagernet/sing v0.2.10-0.20230807080248-4db0062caa0a
|
||||||
github.com/sagernet/sing-box v1.3.6
|
github.com/sagernet/sing-box v1.3.6
|
||||||
|
github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659
|
||||||
github.com/xmdhs/clash2singbox v0.0.0-20230810082059-5054938e1bfd
|
github.com/xmdhs/clash2singbox v0.0.0-20230810082059-5054938e1bfd
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
@@ -54,7 +55,6 @@ require (
|
|||||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
|
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
|
||||||
github.com/sagernet/quic-go v0.0.0-20230731012313-1327e4015111 // indirect
|
github.com/sagernet/quic-go v0.0.0-20230731012313-1327e4015111 // indirect
|
||||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect
|
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect
|
||||||
github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659 // indirect
|
|
||||||
github.com/sagernet/sing-mux v0.1.3-0.20230803070305-ea4a972acd21 // indirect
|
github.com/sagernet/sing-mux v0.1.3-0.20230803070305-ea4a972acd21 // indirect
|
||||||
github.com/sagernet/sing-shadowsocks v0.2.4 // indirect
|
github.com/sagernet/sing-shadowsocks v0.2.4 // indirect
|
||||||
github.com/sagernet/sing-shadowsocks2 v0.1.3 // indirect
|
github.com/sagernet/sing-shadowsocks2 v0.1.3 // indirect
|
||||||
|
|||||||
@@ -1,3 +1,34 @@
|
|||||||
|
// package mobile
|
||||||
|
|
||||||
|
// import (
|
||||||
|
// "encoding/json"
|
||||||
|
// "os"
|
||||||
|
|
||||||
|
// "github.com/hiddify/libcore/shared"
|
||||||
|
// _ "github.com/sagernet/gomobile/event/key"
|
||||||
|
// "github.com/sagernet/sing-box/option"
|
||||||
|
// )
|
||||||
|
|
||||||
|
// func Parse(path string) error {
|
||||||
|
// return shared.ParseConfig(path)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func ApplyOverrides(path string) (string, error) {
|
||||||
|
// fileContent, err := os.ReadFile(path)
|
||||||
|
// if err != nil {
|
||||||
|
// return "", err
|
||||||
|
// }
|
||||||
|
// var options option.Options
|
||||||
|
// err = options.UnmarshalJSON(fileContent)
|
||||||
|
// if err != nil {
|
||||||
|
// return "", err
|
||||||
|
// }
|
||||||
|
// overrides := shared.ConfigOverrides{ExcludeTunInbound: false, IncludeMixedInbound: false, IncludeLogOutput: false, LogLevel: "", IncludeLogTimestamp: false, ClashApiPort: 9090}
|
||||||
|
// options = shared.ApplyOverrides(options, overrides)
|
||||||
|
// config, err := json.Marshal(options)
|
||||||
|
// return string(config), err
|
||||||
|
// }
|
||||||
|
|
||||||
package mobile
|
package mobile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -23,8 +54,13 @@ func ApplyOverrides(path string) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
overrides := shared.ConfigOverrides{ExcludeTunInbound: false, IncludeMixedInbound: false, IncludeLogOutput: false, LogLevel: "", IncludeLogTimestamp: false, ClashApiPort: 9090}
|
overrides := shared.ConfigOverrides{
|
||||||
options = shared.ApplyOverrides(options, overrides)
|
EnableTun: shared.BoolAddr(true),
|
||||||
|
SetSystemProxy: shared.BoolAddr(false),
|
||||||
|
LogOutput: shared.StringAddr(""),
|
||||||
|
}
|
||||||
|
template := shared.DefaultTemplate(overrides)
|
||||||
|
options = shared.ApplyOverrides(template, options, overrides)
|
||||||
config, err := json.Marshal(options)
|
config, err := json.Marshal(options)
|
||||||
return string(config), err
|
return string(config), err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,127 +1,8 @@
|
|||||||
{
|
{
|
||||||
"log": {},
|
"log": {},
|
||||||
"dns": {
|
"dns": {},
|
||||||
"servers": [
|
"inbounds": [],
|
||||||
{
|
"outbounds": [],
|
||||||
"tag": "remote",
|
"route": {},
|
||||||
"address_resolver": "local",
|
"experimental": {}
|
||||||
"address": "tcp://1.1.1.1",
|
|
||||||
"strategy": "prefer_ipv4",
|
|
||||||
"detour": "select"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tag": "local",
|
|
||||||
"address": "local",
|
|
||||||
"detour": "direct"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"rules": [
|
|
||||||
{
|
|
||||||
"clash_mode": "global",
|
|
||||||
"server": "remote"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"clash_mode": "direct",
|
|
||||||
"server": "local"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"outbound": [
|
|
||||||
"any"
|
|
||||||
],
|
|
||||||
"server": "local"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"geosite": "ir",
|
|
||||||
"server": "local"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"strategy": "ipv4_only"
|
|
||||||
},
|
|
||||||
"inbounds": [
|
|
||||||
{
|
|
||||||
"type": "tun",
|
|
||||||
"inet4_address": "172.19.0.1/30",
|
|
||||||
"sniff": true,
|
|
||||||
"sniff_override_destination": true,
|
|
||||||
"domain_strategy": "ipv4_only",
|
|
||||||
"strict_route": true,
|
|
||||||
"mtu": 9000,
|
|
||||||
"endpoint_independent_nat": true,
|
|
||||||
"auto_route": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "socks",
|
|
||||||
"tag": "socks-in",
|
|
||||||
"listen": "127.0.0.1",
|
|
||||||
"sniff": true,
|
|
||||||
"sniff_override_destination": true,
|
|
||||||
"domain_strategy": "ipv4_only",
|
|
||||||
"listen_port": 2333,
|
|
||||||
"users": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "mixed",
|
|
||||||
"tag": "mixed-in",
|
|
||||||
"sniff": true,
|
|
||||||
"sniff_override_destination": true,
|
|
||||||
"domain_strategy": "ipv4_only",
|
|
||||||
"listen": "127.0.0.1",
|
|
||||||
"listen_port": 2334,
|
|
||||||
"set_system_proxy": true,
|
|
||||||
"users": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"outbounds": [
|
|
||||||
{
|
|
||||||
"type": "direct",
|
|
||||||
"tag": "direct"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "block",
|
|
||||||
"tag": "block"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "dns",
|
|
||||||
"tag": "dns-out"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"route": {
|
|
||||||
"rules": [
|
|
||||||
{
|
|
||||||
"geosite": "category-ads-all",
|
|
||||||
"outbound": "block"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"protocol": "dns",
|
|
||||||
"outbound": "dns-out"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"clash_mode": "direct",
|
|
||||||
"outbound": "direct"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"clash_mode": "global",
|
|
||||||
"outbound": "select"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"geoip": [
|
|
||||||
"ir",
|
|
||||||
"private"
|
|
||||||
],
|
|
||||||
"outbound": "direct"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"geosite": "ir",
|
|
||||||
"outbound": "direct"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"auto_detect_interface": true
|
|
||||||
},
|
|
||||||
"experimental": {
|
|
||||||
"clash_api": {
|
|
||||||
"external_controller": "127.0.0.1:9090",
|
|
||||||
"store_selected": true,
|
|
||||||
"secret": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
22
shared/debug.go
Normal file
22
shared/debug.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package shared
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing-box/option"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SaveCurrentConfig(path string, options option.Options) error {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
json.NewEncoder(&buffer)
|
||||||
|
encoder := json.NewEncoder(&buffer)
|
||||||
|
encoder.SetIndent("", " ")
|
||||||
|
err := encoder.Encode(options)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return os.WriteFile(filepath.Join(path, "current-config.json"), buffer.Bytes(), 0777)
|
||||||
|
}
|
||||||
@@ -8,91 +8,95 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ConfigOverrides struct {
|
type ConfigOverrides struct {
|
||||||
ExcludeTunInbound bool
|
ClashApiPort *int `json:"clash-api-port"`
|
||||||
IncludeMixedInbound bool
|
EnableTun *bool `json:"enable-tun"`
|
||||||
IncludeLogOutput bool
|
SetSystemProxy *bool `json:"set-system-proxy"`
|
||||||
IncludeLogTimestamp bool
|
LogLevel *string `json:"log-level"`
|
||||||
LogLevel string
|
LogOutput *string `json:"log-output"`
|
||||||
ClashApiPort int
|
DNSRemote *string `json:"dns-remote"`
|
||||||
|
MixedPort *int `json:"mixed-port"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func ApplyOverrides(options option.Options, overrides ConfigOverrides) option.Options {
|
func ApplyOverrides(base option.Options, options option.Options, overrides ConfigOverrides) option.Options {
|
||||||
options.Log = &option.LogOptions{
|
clashApiPort := pointerOrDefaultInt(overrides.ClashApiPort, 9090)
|
||||||
Disabled: false,
|
base.Experimental = &option.ExperimentalOptions{
|
||||||
Timestamp: overrides.IncludeLogTimestamp,
|
ClashAPI: &option.ClashAPIOptions{
|
||||||
DisableColor: true,
|
ExternalController: fmt.Sprintf("%s:%d", "127.0.0.1", clashApiPort),
|
||||||
}
|
StoreSelected: true,
|
||||||
if overrides.LogLevel != "" {
|
},
|
||||||
options.Log.Level = overrides.LogLevel
|
|
||||||
}
|
|
||||||
if overrides.IncludeLogOutput {
|
|
||||||
options.Log.Output = "box.log"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
options.Experimental.ClashAPI = &option.ClashAPIOptions{
|
base.Log = &option.LogOptions{
|
||||||
ExternalController: fmt.Sprintf("%s:%d", "127.0.0.1", overrides.ClashApiPort),
|
Level: pointerOrDefaultString(overrides.LogLevel, "info"),
|
||||||
StoreSelected: true,
|
Output: pointerOrDefaultString(overrides.LogOutput, ""),
|
||||||
Secret: "",
|
Disabled: false,
|
||||||
|
Timestamp: false,
|
||||||
|
DisableColor: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
var inbounds []option.Inbound
|
var inbounds []option.Inbound
|
||||||
for _, inb := range options.Inbounds {
|
for _, inb := range base.Inbounds {
|
||||||
if overrides.ExcludeTunInbound && inb.Type == C.TypeTun {
|
switch inb.Type {
|
||||||
continue
|
case C.TypeTun:
|
||||||
}
|
if pointerOrDefaultBool(overrides.EnableTun, true) {
|
||||||
if overrides.IncludeMixedInbound && inb.Type == C.TypeMixed {
|
inbounds = append(inbounds, inb)
|
||||||
inb.MixedOptions.SetSystemProxy = true
|
}
|
||||||
|
default:
|
||||||
inbounds = append(inbounds, inb)
|
inbounds = append(inbounds, inb)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
inbounds = append(inbounds, inb)
|
|
||||||
}
|
}
|
||||||
options.Inbounds = inbounds
|
base.Inbounds = inbounds
|
||||||
|
|
||||||
hasSelector := false
|
var outbounds []option.Outbound
|
||||||
hasUrlTest := false
|
var tags []string
|
||||||
var selectable []option.Outbound
|
|
||||||
var urlTests []option.Outbound
|
|
||||||
for _, out := range options.Outbounds {
|
for _, out := range options.Outbounds {
|
||||||
if out.Type == C.TypeSelector {
|
|
||||||
hasSelector = true
|
|
||||||
} else if out.Type == C.TypeURLTest {
|
|
||||||
hasUrlTest = true
|
|
||||||
urlTests = append(urlTests, out)
|
|
||||||
}
|
|
||||||
switch out.Type {
|
switch out.Type {
|
||||||
case C.TypeDirect, C.TypeBlock, C.TypeDNS:
|
case C.TypeDirect, C.TypeBlock, C.TypeDNS:
|
||||||
continue
|
continue
|
||||||
|
case C.TypeSelector, C.TypeURLTest:
|
||||||
|
continue
|
||||||
|
default:
|
||||||
|
tags = append(tags, out.Tag)
|
||||||
}
|
}
|
||||||
selectable = append(selectable, out)
|
outbounds = append(outbounds, out)
|
||||||
}
|
|
||||||
var generatedUrlTest *option.Outbound
|
|
||||||
if !hasUrlTest {
|
|
||||||
var urlSelectOuts []string
|
|
||||||
for _, out := range selectable {
|
|
||||||
urlSelectOuts = append(urlSelectOuts, out.Tag)
|
|
||||||
}
|
|
||||||
generatedUrlTest = &option.Outbound{Type: C.TypeURLTest, Tag: "urltest", URLTestOptions: option.URLTestOutboundOptions{Outbounds: urlSelectOuts}}
|
|
||||||
urlTests = append(urlTests, *generatedUrlTest)
|
|
||||||
}
|
|
||||||
if !hasSelector {
|
|
||||||
var selectorOuts []string
|
|
||||||
for _, out := range selectable {
|
|
||||||
selectorOuts = append(selectorOuts, out.Tag)
|
|
||||||
}
|
|
||||||
for _, out := range urlTests {
|
|
||||||
selectorOuts = append(selectorOuts, out.Tag)
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultSelector := option.Outbound{Type: C.TypeSelector, Tag: "select", SelectorOptions: option.SelectorOutboundOptions{Outbounds: selectorOuts}}
|
|
||||||
if generatedUrlTest != nil {
|
|
||||||
defaultSelector.SelectorOptions.Default = generatedUrlTest.Tag
|
|
||||||
}
|
|
||||||
options.Outbounds = append([]option.Outbound{defaultSelector}, options.Outbounds...)
|
|
||||||
}
|
|
||||||
if generatedUrlTest != nil {
|
|
||||||
options.Outbounds = append(options.Outbounds, *generatedUrlTest)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return options
|
urlTest := option.Outbound{
|
||||||
|
Type: C.TypeURLTest,
|
||||||
|
Tag: "auto",
|
||||||
|
URLTestOptions: option.URLTestOutboundOptions{
|
||||||
|
Outbounds: tags,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
selector := option.Outbound{
|
||||||
|
Type: C.TypeSelector,
|
||||||
|
Tag: "select",
|
||||||
|
SelectorOptions: option.SelectorOutboundOptions{
|
||||||
|
Outbounds: append([]string{urlTest.Tag}, tags...),
|
||||||
|
Default: urlTest.Tag,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
outbounds = append([]option.Outbound{selector, urlTest}, outbounds...)
|
||||||
|
|
||||||
|
base.Outbounds = append(
|
||||||
|
outbounds,
|
||||||
|
[]option.Outbound{
|
||||||
|
{
|
||||||
|
Tag: "direct",
|
||||||
|
Type: C.TypeDirect,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Tag: "block",
|
||||||
|
Type: C.TypeBlock,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Tag: "dns-out",
|
||||||
|
Type: C.TypeDNS,
|
||||||
|
},
|
||||||
|
}...,
|
||||||
|
)
|
||||||
|
|
||||||
|
return base
|
||||||
}
|
}
|
||||||
|
|||||||
168
shared/template.go
Normal file
168
shared/template.go
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
package shared
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
|
C "github.com/sagernet/sing-box/constant"
|
||||||
|
"github.com/sagernet/sing-box/option"
|
||||||
|
dns "github.com/sagernet/sing-dns"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DefaultTemplate(overrides ConfigOverrides) option.Options {
|
||||||
|
var options option.Options
|
||||||
|
|
||||||
|
options.Experimental = &option.ExperimentalOptions{
|
||||||
|
ClashAPI: &option.ClashAPIOptions{
|
||||||
|
ExternalController: "127.0.0.1:9090",
|
||||||
|
StoreSelected: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
options.Log = &option.LogOptions{
|
||||||
|
Level: "warn",
|
||||||
|
Disabled: false,
|
||||||
|
Timestamp: false,
|
||||||
|
DisableColor: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
options.DNS = &option.DNSOptions{
|
||||||
|
DNSClientOptions: option.DNSClientOptions{
|
||||||
|
Strategy: option.DomainStrategy(dns.DomainStrategyPreferIPv4),
|
||||||
|
IndependentCache: true,
|
||||||
|
},
|
||||||
|
Servers: []option.DNSServerOptions{
|
||||||
|
{
|
||||||
|
Tag: "local",
|
||||||
|
Address: "local",
|
||||||
|
Detour: "direct",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Tag: "dns-remote",
|
||||||
|
Address: pointerOrDefaultString(overrides.DNSRemote, "tcp://1.1.1.1"),
|
||||||
|
AddressResolver: "local",
|
||||||
|
Strategy: option.DomainStrategy(dns.DomainStrategyPreferIPv4),
|
||||||
|
Detour: "select",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Rules: []option.DNSRule{
|
||||||
|
{
|
||||||
|
Type: C.RuleTypeDefault,
|
||||||
|
DefaultOptions: option.DefaultDNSRule{
|
||||||
|
ClashMode: "direct",
|
||||||
|
Server: "local",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: C.RuleTypeDefault,
|
||||||
|
DefaultOptions: option.DefaultDNSRule{
|
||||||
|
ClashMode: "global",
|
||||||
|
Server: "dns-remote",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: C.RuleTypeDefault,
|
||||||
|
DefaultOptions: option.DefaultDNSRule{
|
||||||
|
DomainSuffix: []string{"ir"},
|
||||||
|
Server: "local",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: C.RuleTypeDefault,
|
||||||
|
DefaultOptions: option.DefaultDNSRule{
|
||||||
|
Outbound: []string{"any"},
|
||||||
|
Server: "local",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ReverseMapping: true,
|
||||||
|
Final: "dns-remote",
|
||||||
|
}
|
||||||
|
|
||||||
|
if pointerOrDefaultBool(overrides.EnableTun, true) {
|
||||||
|
options.Inbounds = append(
|
||||||
|
options.Inbounds,
|
||||||
|
option.Inbound{
|
||||||
|
Type: C.TypeTun,
|
||||||
|
Tag: "tun-in",
|
||||||
|
TunOptions: option.TunInboundOptions{
|
||||||
|
Inet4Address: []option.ListenPrefix{
|
||||||
|
option.ListenPrefix(netip.MustParsePrefix("172.19.0.1/30")),
|
||||||
|
},
|
||||||
|
MTU: 9000,
|
||||||
|
AutoRoute: true,
|
||||||
|
StrictRoute: true,
|
||||||
|
EndpointIndependentNat: true,
|
||||||
|
InboundOptions: option.InboundOptions{
|
||||||
|
SniffEnabled: true,
|
||||||
|
SniffOverrideDestination: true,
|
||||||
|
DomainStrategy: option.DomainStrategy(dns.DomainStrategyUseIPv4),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
options.Inbounds = append(
|
||||||
|
options.Inbounds,
|
||||||
|
option.Inbound{
|
||||||
|
Type: C.TypeMixed,
|
||||||
|
Tag: "mixed-in",
|
||||||
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
|
ListenOptions: option.ListenOptions{
|
||||||
|
Listen: option.NewListenAddress(netip.MustParseAddr("127.0.0.1")),
|
||||||
|
ListenPort: uint16(pointerOrDefaultInt(overrides.MixedPort, 2334)),
|
||||||
|
InboundOptions: option.InboundOptions{
|
||||||
|
SniffEnabled: true,
|
||||||
|
SniffOverrideDestination: true,
|
||||||
|
DomainStrategy: option.DomainStrategy(dns.DomainStrategyUseIPv4),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SetSystemProxy: pointerOrDefaultBool(overrides.SetSystemProxy, true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
options.Route = &option.RouteOptions{
|
||||||
|
Rules: []option.Rule{
|
||||||
|
{
|
||||||
|
Type: C.RuleTypeDefault,
|
||||||
|
DefaultOptions: option.DefaultRule{
|
||||||
|
Geosite: []string{"category-ads-all"},
|
||||||
|
Outbound: "block",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: C.RuleTypeDefault,
|
||||||
|
DefaultOptions: option.DefaultRule{
|
||||||
|
Protocol: []string{"dns"},
|
||||||
|
Outbound: "dns-out",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: C.RuleTypeDefault,
|
||||||
|
DefaultOptions: option.DefaultRule{
|
||||||
|
ClashMode: "direct",
|
||||||
|
Outbound: "direct",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: C.RuleTypeDefault,
|
||||||
|
DefaultOptions: option.DefaultRule{
|
||||||
|
ClashMode: "global",
|
||||||
|
Outbound: "select",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: C.RuleTypeDefault,
|
||||||
|
DefaultOptions: option.DefaultRule{
|
||||||
|
GeoIP: []string{"ir", "private"},
|
||||||
|
DomainSuffix: []string{"ir"},
|
||||||
|
Outbound: "direct",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AutoDetectInterface: true,
|
||||||
|
OverrideAndroidVPN: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
return options
|
||||||
|
}
|
||||||
35
shared/utils.go
Normal file
35
shared/utils.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package shared
|
||||||
|
|
||||||
|
func StringAddr(b string) *string {
|
||||||
|
stringVar := b
|
||||||
|
return &stringVar
|
||||||
|
}
|
||||||
|
|
||||||
|
func BoolAddr(b bool) *bool {
|
||||||
|
boolVar := b
|
||||||
|
return &boolVar
|
||||||
|
}
|
||||||
|
|
||||||
|
func pointerOrDefaultString(p *string, def string) string {
|
||||||
|
if p != nil {
|
||||||
|
return *p
|
||||||
|
}
|
||||||
|
|
||||||
|
return def
|
||||||
|
}
|
||||||
|
|
||||||
|
func pointerOrDefaultInt(p *int, def int) int {
|
||||||
|
if p != nil {
|
||||||
|
return *p
|
||||||
|
}
|
||||||
|
|
||||||
|
return def
|
||||||
|
}
|
||||||
|
|
||||||
|
func pointerOrDefaultBool(p *bool, def bool) bool {
|
||||||
|
if p != nil {
|
||||||
|
return *p
|
||||||
|
}
|
||||||
|
|
||||||
|
return def
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user