simple refactor config.go

This commit is contained in:
Hiddify
2024-08-05 18:41:14 +02:00
parent da5e90e289
commit be126caf72

View File

@@ -59,7 +59,7 @@ func BuildConfigJson(configOpt ConfigOptions, input option.Options) (string, err
// TODO include selectors // TODO include selectors
func BuildConfig(opt ConfigOptions, input option.Options) (*option.Options, error) { func BuildConfig(opt ConfigOptions, input option.Options) (*option.Options, error) {
fmt.Printf("config options: %+v\n", opt) fmt.Printf("config options: %++v\n", opt)
var options option.Options var options option.Options
if opt.EnableFullConfig { if opt.EnableFullConfig {
@@ -67,176 +67,67 @@ func BuildConfig(opt ConfigOptions, input option.Options) (*option.Options, erro
options.DNS = input.DNS options.DNS = input.DNS
options.Route = input.Route options.Route = input.Route
} }
directDNSDomains := make(map[string]bool)
var bind string setClashAPI(&options, &opt)
if opt.AllowConnectionFromLAN { setLog(&options, &opt)
bind = "0.0.0.0" setInbound(&options, &opt)
} else { setDns(&options, &opt)
bind = "127.0.0.1" setRoutingOptions(&options, &opt)
setFakeDns(&options, &opt)
err := setOutbounds(&options, &input, &opt)
if err != nil {
return nil, err
} }
if opt.EnableClashApi { return &options, nil
if opt.ClashApiSecret == "" { }
opt.ClashApiSecret = generateRandomString(16) func addForceDirect(options *option.Options, opt *ConfigOptions, directDNSDomains map[string]bool) {
}
options.Experimental = &option.ExperimentalOptions{
ClashAPI: &option.ClashAPIOptions{
ExternalController: fmt.Sprintf("%s:%d", "127.0.0.1", opt.ClashApiPort),
Secret: opt.ClashApiSecret,
},
CacheFile: &option.CacheFileOptions{
Enabled: true,
Path: "clash.db",
},
}
}
options.Log = &option.LogOptions{
Level: opt.LogLevel,
Output: "box.log",
Disabled: false,
Timestamp: true,
DisableColor: true,
}
options.DNS = &option.DNSOptions{
StaticIPs: map[string][]string{},
DNSClientOptions: option.DNSClientOptions{
IndependentCache: opt.IndependentDNSCache,
},
Final: DNSRemoteTag,
Servers: []option.DNSServerOptions{
{
Tag: DNSRemoteTag,
Address: opt.RemoteDnsAddress,
AddressResolver: DNSDirectTag,
Strategy: opt.RemoteDnsDomainStrategy,
},
{
Tag: DNSTricksDirectTag,
Address: "https://sky.rethinkdns.com/",
// AddressResolver: "dns-local",
Strategy: opt.DirectDnsDomainStrategy,
Detour: OutboundDirectFragmentTag,
},
{
Tag: DNSDirectTag,
Address: opt.DirectDnsAddress,
AddressResolver: DNSLocalTag,
Strategy: opt.DirectDnsDomainStrategy,
Detour: OutboundDirectTag,
},
{
Tag: DNSLocalTag,
Address: "local",
Detour: OutboundDirectTag,
},
{
Tag: DNSBlockTag,
Address: "rcode://success",
},
},
}
sky_rethinkdns := getIPs([]string{"www.speedtest.net", "sky.rethinkdns.com"})
if len(sky_rethinkdns) > 0 {
options.DNS.StaticIPs["sky.rethinkdns.com"] = sky_rethinkdns
}
var inboundDomainStrategy option.DomainStrategy
if !opt.ResolveDestination {
inboundDomainStrategy = option.DomainStrategy(dns.DomainStrategyAsIS)
} else {
inboundDomainStrategy = opt.IPv6Mode
}
if opt.EnableTunService {
ActivateTunnelService(opt)
} else if opt.EnableTun {
tunInbound := option.Inbound{
Type: C.TypeTun,
Tag: InboundTUNTag,
TunOptions: option.TunInboundOptions{
Stack: opt.TUNStack,
MTU: opt.MTU,
AutoRoute: true,
StrictRoute: opt.StrictRoute,
EndpointIndependentNat: true,
// GSO: runtime.GOOS != "windows",
InboundOptions: option.InboundOptions{
SniffEnabled: true,
SniffOverrideDestination: true,
DomainStrategy: inboundDomainStrategy,
},
},
}
switch opt.IPv6Mode {
case option.DomainStrategy(dns.DomainStrategyUseIPv4):
tunInbound.TunOptions.Inet4Address = []netip.Prefix{
netip.MustParsePrefix("172.19.0.1/28"),
}
case option.DomainStrategy(dns.DomainStrategyUseIPv6):
tunInbound.TunOptions.Inet6Address = []netip.Prefix{
netip.MustParsePrefix("fdfe:dcba:9876::1/126"),
}
default:
tunInbound.TunOptions.Inet4Address = []netip.Prefix{
netip.MustParsePrefix("172.19.0.1/28"),
}
tunInbound.TunOptions.Inet6Address = []netip.Prefix{
netip.MustParsePrefix("fdfe:dcba:9876::1/126"),
}
}
options.Inbounds = append(options.Inbounds, tunInbound)
}
options.Inbounds = append(
options.Inbounds,
option.Inbound{
Type: C.TypeMixed,
Tag: InboundMixedTag,
MixedOptions: option.HTTPMixedInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.MustParseAddr(bind)),
ListenPort: opt.MixedPort,
InboundOptions: option.InboundOptions{
SniffEnabled: true,
SniffOverrideDestination: true,
DomainStrategy: inboundDomainStrategy,
},
},
SetSystemProxy: opt.SetSystemProxy,
},
},
)
options.Inbounds = append(
options.Inbounds,
option.Inbound{
Type: C.TypeDirect,
Tag: InboundDNSTag,
DirectOptions: option.DirectInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.MustParseAddr(bind)),
ListenPort: opt.LocalDnsPort,
},
// OverrideAddress: "1.1.1.1",
// OverridePort: 53,
},
},
)
remoteDNSAddress := opt.RemoteDnsAddress remoteDNSAddress := opt.RemoteDnsAddress
if strings.Contains(remoteDNSAddress, "://") { if strings.Contains(remoteDNSAddress, "://") {
remoteDNSAddress = strings.SplitAfter(remoteDNSAddress, "://")[1] remoteDNSAddress = strings.SplitAfter(remoteDNSAddress, "://")[1]
} }
parsedUrl, err := url.Parse(fmt.Sprintf("https://%s", remoteDNSAddress)) parsedUrl, err := url.Parse(fmt.Sprintf("https://%s", remoteDNSAddress))
if err == nil && net.ParseIP(parsedUrl.Host) == nil { if err == nil && net.ParseIP(parsedUrl.Host) == nil {
directDNSDomains["full:"+parsedUrl.Host] = true directDNSDomains[parsedUrl.Host] = true
//TODO: IS it really needed
} }
setRoutingOptions(&options, &opt) if len(directDNSDomains) > 0 {
setFakeDns(&options, &opt) // trickDnsDomains := []string{}
// directDNSDomains = removeDuplicateStr(directDNSDomains)
// b, _ := batch.New(context.Background(), batch.WithConcurrencyNum[bool](10))
// for _, d := range directDNSDomains {
// b.Go(d, func() (bool, error) {
// return isBlockedDomain(d), nil
// })
// }
// b.Wait()
// for domain, isBlock := range b.Result() {
// if isBlock.Value {
// trickDnsDomains = append(trickDnsDomains, domain)
// }
// }
// trickDomains := strings.Join(trickDnsDomains, ",")
// trickRule := Rule{Domains: trickDomains, Outbound: OutboundBypassTag}
// trickDnsRule := trickRule.MakeDNSRule()
// trickDnsRule.Server = DNSTricksDirectTag
// options.DNS.Rules = append([]option.DNSRule{{Type: C.RuleTypeDefault, DefaultOptions: trickDnsRule}}, options.DNS.Rules...)
directDNSDomainskeys := make([]string, 0, len(directDNSDomains))
for key := range directDNSDomains {
directDNSDomainskeys = append(directDNSDomainskeys, key)
}
domains := strings.Join(directDNSDomainskeys, ",")
directRule := Rule{Domains: domains, Outbound: OutboundBypassTag}
dnsRule := directRule.MakeDNSRule()
dnsRule.Server = DNSDirectTag
options.DNS.Rules = append([]option.DNSRule{{Type: C.RuleTypeDefault, DefaultOptions: dnsRule}}, options.DNS.Rules...)
}
}
func setOutbounds(options *option.Options, input *option.Options, opt *ConfigOptions) error {
directDNSDomains := make(map[string]bool)
var outbounds []option.Outbound var outbounds []option.Outbound
var tags []string var tags []string
OutboundMainProxyTag = OutboundSelectTag OutboundMainProxyTag = OutboundSelectTag
@@ -262,7 +153,7 @@ func BuildConfig(opt ConfigOptions, input option.Options) (*option.Options, erro
if opt.Warp.EnableWarp && (opt.Warp.Mode == "warp_over_proxy" || opt.Warp.Mode == "proxy_over_warp") { if opt.Warp.EnableWarp && (opt.Warp.Mode == "warp_over_proxy" || opt.Warp.Mode == "proxy_over_warp") {
out, err := GenerateWarpSingbox(opt.Warp.WireguardConfig, opt.Warp.CleanIP, opt.Warp.CleanPort, opt.Warp.FakePackets, opt.Warp.FakePacketSize, opt.Warp.FakePacketDelay, opt.Warp.FakePacketMode) out, err := GenerateWarpSingbox(opt.Warp.WireguardConfig, opt.Warp.CleanIP, opt.Warp.CleanPort, opt.Warp.FakePackets, opt.Warp.FakePacketSize, opt.Warp.FakePacketDelay, opt.Warp.FakePacketMode)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to generate warp config: %v", err) return fmt.Errorf("failed to generate warp config: %v", err)
} }
out.Tag = "Hiddify Warp ✅" out.Tag = "Hiddify Warp ✅"
if opt.Warp.Mode == "warp_over_proxy" { if opt.Warp.Mode == "warp_over_proxy" {
@@ -271,14 +162,14 @@ func BuildConfig(opt ConfigOptions, input option.Options) (*option.Options, erro
} else { } else {
out.WireGuardOptions.Detour = OutboundDirectTag out.WireGuardOptions.Detour = OutboundDirectTag
} }
patchWarp(out, &opt, true, nil) patchWarp(out, opt, true, nil)
outbounds = append(outbounds, *out) outbounds = append(outbounds, *out)
// tags = append(tags, out.Tag) // tags = append(tags, out.Tag)
} }
for _, out := range input.Outbounds { for _, out := range input.Outbounds {
outbound, serverDomain, err := patchOutbound(out, opt, options.DNS.StaticIPs) outbound, serverDomain, err := patchOutbound(out, *opt, options.DNS.StaticIPs)
if err != nil { if err != nil {
return nil, err return err
} }
if serverDomain != "" { if serverDomain != "" {
@@ -297,7 +188,7 @@ func BuildConfig(opt ConfigOptions, input option.Options) (*option.Options, erro
if !strings.Contains(out.Tag, "§hide§") { if !strings.Contains(out.Tag, "§hide§") {
tags = append(tags, out.Tag) tags = append(tags, out.Tag)
} }
out = patchHiddifyWarpFromConfig(out, opt) out = patchHiddifyWarpFromConfig(out, *opt)
outbounds = append(outbounds, out) outbounds = append(outbounds, out)
} }
} }
@@ -367,41 +258,177 @@ func BuildConfig(opt ConfigOptions, input option.Options) (*option.Options, erro
}, },
}..., }...,
) )
if len(directDNSDomains) > 0 {
// trickDnsDomains := []string{}
// directDNSDomains = removeDuplicateStr(directDNSDomains)
// b, _ := batch.New(context.Background(), batch.WithConcurrencyNum[bool](10))
// for _, d := range directDNSDomains {
// b.Go(d, func() (bool, error) {
// return isBlockedDomain(d), nil
// })
// }
// b.Wait()
// for domain, isBlock := range b.Result() {
// if isBlock.Value {
// trickDnsDomains = append(trickDnsDomains, domain)
// }
// }
// trickDomains := strings.Join(trickDnsDomains, ",") addForceDirect(options, opt, directDNSDomains)
// trickRule := Rule{Domains: trickDomains, Outbound: OutboundBypassTag} return nil
// trickDnsRule := trickRule.MakeDNSRule() }
// trickDnsRule.Server = DNSTricksDirectTag
// options.DNS.Rules = append([]option.DNSRule{{Type: C.RuleTypeDefault, DefaultOptions: trickDnsRule}}, options.DNS.Rules...)
directDNSDomainskeys := make([]string, 0, len(directDNSDomains)) func setClashAPI(options *option.Options, opt *ConfigOptions) {
for key := range directDNSDomains { if opt.EnableClashApi {
directDNSDomainskeys = append(directDNSDomainskeys, key) if opt.ClashApiSecret == "" {
opt.ClashApiSecret = generateRandomString(16)
} }
options.Experimental = &option.ExperimentalOptions{
ClashAPI: &option.ClashAPIOptions{
ExternalController: fmt.Sprintf("%s:%d", "127.0.0.1", opt.ClashApiPort),
Secret: opt.ClashApiSecret,
},
domains := strings.Join(directDNSDomainskeys, ",") CacheFile: &option.CacheFileOptions{
directRule := Rule{Domains: domains, Outbound: OutboundBypassTag} Enabled: true,
dnsRule := directRule.MakeDNSRule() Path: "clash.db",
dnsRule.Server = DNSDirectTag },
options.DNS.Rules = append([]option.DNSRule{{Type: C.RuleTypeDefault, DefaultOptions: dnsRule}}, options.DNS.Rules...) }
}
}
func setLog(options *option.Options, opt *ConfigOptions) {
options.Log = &option.LogOptions{
Level: opt.LogLevel,
Output: "box.log",
Disabled: false,
Timestamp: true,
DisableColor: true,
}
}
func setInbound(options *option.Options, opt *ConfigOptions) {
var inboundDomainStrategy option.DomainStrategy
if !opt.ResolveDestination {
inboundDomainStrategy = option.DomainStrategy(dns.DomainStrategyAsIS)
} else {
inboundDomainStrategy = opt.IPv6Mode
}
if opt.EnableTunService {
ActivateTunnelService(*opt)
} else if opt.EnableTun {
tunInbound := option.Inbound{
Type: C.TypeTun,
Tag: InboundTUNTag,
TunOptions: option.TunInboundOptions{
Stack: opt.TUNStack,
MTU: opt.MTU,
AutoRoute: true,
StrictRoute: opt.StrictRoute,
EndpointIndependentNat: true,
// GSO: runtime.GOOS != "windows",
InboundOptions: option.InboundOptions{
SniffEnabled: true,
SniffOverrideDestination: true,
DomainStrategy: inboundDomainStrategy,
},
},
}
switch opt.IPv6Mode {
case option.DomainStrategy(dns.DomainStrategyUseIPv4):
tunInbound.TunOptions.Inet4Address = []netip.Prefix{
netip.MustParsePrefix("172.19.0.1/28"),
}
case option.DomainStrategy(dns.DomainStrategyUseIPv6):
tunInbound.TunOptions.Inet6Address = []netip.Prefix{
netip.MustParsePrefix("fdfe:dcba:9876::1/126"),
}
default:
tunInbound.TunOptions.Inet4Address = []netip.Prefix{
netip.MustParsePrefix("172.19.0.1/28"),
}
tunInbound.TunOptions.Inet6Address = []netip.Prefix{
netip.MustParsePrefix("fdfe:dcba:9876::1/126"),
}
}
options.Inbounds = append(options.Inbounds, tunInbound)
}
var bind string
if opt.AllowConnectionFromLAN {
bind = "0.0.0.0"
} else {
bind = "127.0.0.1"
}
options.Inbounds = append(
options.Inbounds,
option.Inbound{
Type: C.TypeMixed,
Tag: InboundMixedTag,
MixedOptions: option.HTTPMixedInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.MustParseAddr(bind)),
ListenPort: opt.MixedPort,
InboundOptions: option.InboundOptions{
SniffEnabled: true,
SniffOverrideDestination: true,
DomainStrategy: inboundDomainStrategy,
},
},
SetSystemProxy: opt.SetSystemProxy,
},
},
)
options.Inbounds = append(
options.Inbounds,
option.Inbound{
Type: C.TypeDirect,
Tag: InboundDNSTag,
DirectOptions: option.DirectInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.MustParseAddr(bind)),
ListenPort: opt.LocalDnsPort,
},
// OverrideAddress: "1.1.1.1",
// OverridePort: 53,
},
},
)
}
func setDns(options *option.Options, opt *ConfigOptions) {
options.DNS = &option.DNSOptions{
StaticIPs: map[string][]string{},
DNSClientOptions: option.DNSClientOptions{
IndependentCache: opt.IndependentDNSCache,
},
Final: DNSRemoteTag,
Servers: []option.DNSServerOptions{
{
Tag: DNSRemoteTag,
Address: opt.RemoteDnsAddress,
AddressResolver: DNSDirectTag,
Strategy: opt.RemoteDnsDomainStrategy,
},
{
Tag: DNSTricksDirectTag,
Address: "https://sky.rethinkdns.com/",
// AddressResolver: "dns-local",
Strategy: opt.DirectDnsDomainStrategy,
Detour: OutboundDirectFragmentTag,
},
{
Tag: DNSDirectTag,
Address: opt.DirectDnsAddress,
AddressResolver: DNSLocalTag,
Strategy: opt.DirectDnsDomainStrategy,
Detour: OutboundDirectTag,
},
{
Tag: DNSLocalTag,
Address: "local",
Detour: OutboundDirectTag,
},
{
Tag: DNSBlockTag,
Address: "rcode://success",
},
},
}
sky_rethinkdns := getIPs([]string{"www.speedtest.net", "sky.rethinkdns.com"})
if len(sky_rethinkdns) > 0 {
options.DNS.StaticIPs["sky.rethinkdns.com"] = sky_rethinkdns
} }
options.Route.Final = OutboundMainProxyTag
return &options, nil
} }
func setFakeDns(options *option.Options, opt *ConfigOptions) { func setFakeDns(options *option.Options, opt *ConfigOptions) {
@@ -456,7 +483,7 @@ func setRoutingOptions(options *option.Options, opt *ConfigOptions) {
Outbound: OutboundDNSTag, Outbound: OutboundDNSTag,
}, },
}) })
if opt.EnableTun && false { if opt.EnableTun {
routeRules = append( routeRules = append(
routeRules, routeRules,
option.Rule{ option.Rule{
@@ -537,9 +564,9 @@ func setRoutingOptions(options *option.Options, opt *ConfigOptions) {
dnsRules = append(dnsRules, dnsRule) dnsRules = append(dnsRules, dnsRule)
} }
var dnsCPttl uint32 = 3000
parsedURL, err := url.Parse(opt.ConnectionTestUrl) parsedURL, err := url.Parse(opt.ConnectionTestUrl)
if err == nil { if err == nil {
var dnsCPttl uint32 = 3000
dnsRules = append(dnsRules, option.DefaultDNSRule{ dnsRules = append(dnsRules, option.DefaultDNSRule{
Domain: []string{parsedURL.Host}, Domain: []string{parsedURL.Host},
Server: DNSRemoteTag, Server: DNSRemoteTag,
@@ -621,6 +648,17 @@ func setRoutingOptions(options *option.Options, opt *ConfigOptions) {
} }
if opt.Region != "other" { if opt.Region != "other" {
dnsRules = append(dnsRules, option.DefaultDNSRule{
DomainSuffix: []string{"." + opt.Region},
Server: DNSDirectTag,
})
routeRules = append(routeRules, option.Rule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
DomainSuffix: []string{"." + opt.Region},
Outbound: OutboundDirectTag,
},
})
dnsRules = append(dnsRules, option.DefaultDNSRule{ dnsRules = append(dnsRules, option.DefaultDNSRule{
RuleSet: []string{ RuleSet: []string{
"geoip-" + opt.Region, "geoip-" + opt.Region,
@@ -628,10 +666,7 @@ func setRoutingOptions(options *option.Options, opt *ConfigOptions) {
}, },
Server: DNSDirectTag, Server: DNSDirectTag,
}) })
dnsRules = append(dnsRules, option.DefaultDNSRule{
DomainSuffix: []string{"." + opt.Region},
Server: DNSDirectTag,
})
rulesets = append(rulesets, option.RuleSet{ rulesets = append(rulesets, option.RuleSet{
Type: C.RuleSetTypeRemote, Type: C.RuleSetTypeRemote,
Tag: "geoip-" + opt.Region, Tag: "geoip-" + opt.Region,
@@ -662,14 +697,6 @@ func setRoutingOptions(options *option.Options, opt *ConfigOptions) {
}, },
}) })
routeRules = append(routeRules, option.Rule{
Type: C.RuleTypeDefault,
DefaultOptions: option.DefaultRule{
DomainSuffix: []string{"." + opt.Region},
Outbound: OutboundDirectTag,
},
})
} }
options.Route = &option.RouteOptions{ options.Route = &option.RouteOptions{
Rules: routeRules, Rules: routeRules,