diff --git a/component/updater/update_ui.go b/component/updater/update_ui.go index 48d6536c..bd2a5881 100644 --- a/component/updater/update_ui.go +++ b/component/updater/update_ui.go @@ -58,7 +58,7 @@ func (u *UIUpdater) AutoDownloadUI() { log.Infoln("External UI downloading ...") err := u.downloadUI() if err != nil { - log.Errorln("Error downloading UI:", err) + log.Errorln("Error downloading UI: %s", err) } } } diff --git a/config/config.go b/config/config.go index 69957cee..ba6097bc 100644 --- a/config/config.go +++ b/config/config.go @@ -9,6 +9,7 @@ import ( "net/url" "strings" "time" + _ "unsafe" "github.com/metacubex/mihomo/adapter" "github.com/metacubex/mihomo/adapter/outbound" @@ -19,12 +20,9 @@ import ( "github.com/metacubex/mihomo/component/cidr" "github.com/metacubex/mihomo/component/fakeip" "github.com/metacubex/mihomo/component/geodata" - mihomoHttp "github.com/metacubex/mihomo/component/http" P "github.com/metacubex/mihomo/component/process" "github.com/metacubex/mihomo/component/resolver" - "github.com/metacubex/mihomo/component/resource" "github.com/metacubex/mihomo/component/sniffer" - tlsC "github.com/metacubex/mihomo/component/tls" "github.com/metacubex/mihomo/component/trie" C "github.com/metacubex/mihomo/constant" providerTypes "github.com/metacubex/mihomo/constant/provider" @@ -588,10 +586,11 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) { } config.General = general - if len(config.General.GlobalClientFingerprint) != 0 { - log.Debugln("GlobalClientFingerprint: %s", config.General.GlobalClientFingerprint) - tlsC.SetGlobalUtlsClient(config.General.GlobalClientFingerprint) - } + // We need to temporarily apply some configuration in general and roll back after parsing the complete configuration. + // The loading and downloading of geodata in the parseRules and parseRuleProviders rely on these. + // This implementation is very disgusting, but there is currently no better solution + rollback := temporaryUpdateGeneral(config.General) + defer rollback() controller, err := parseController(rawCfg) if err != nil { @@ -707,17 +706,10 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) { return config, nil } -func parseGeneral(cfg *RawConfig) (*General, error) { - geodata.SetGeodataMode(cfg.GeodataMode) - geodata.SetLoader(cfg.GeodataLoader) - geodata.SetSiteMatcher(cfg.GeositeMatcher) - geodata.SetGeoIpUrl(cfg.GeoXUrl.GeoIp) - geodata.SetGeoSiteUrl(cfg.GeoXUrl.GeoSite) - geodata.SetMmdbUrl(cfg.GeoXUrl.Mmdb) - geodata.SetASNUrl(cfg.GeoXUrl.ASN) - mihomoHttp.SetUA(cfg.GlobalUA) - resource.SetETag(cfg.ETagSupport) +//go:linkname temporaryUpdateGeneral +func temporaryUpdateGeneral(general *General) func() +func parseGeneral(cfg *RawConfig) (*General, error) { return &General{ Inbound: Inbound{ Port: cfg.Port, @@ -751,6 +743,7 @@ func parseGeneral(cfg *RawConfig) (*General, error) { GeoUpdateInterval: cfg.GeoUpdateInterval, GeodataMode: cfg.GeodataMode, GeodataLoader: cfg.GeodataLoader, + GeositeMatcher: cfg.GeositeMatcher, TCPConcurrent: cfg.TCPConcurrent, FindProcessMode: cfg.FindProcessMode, GlobalClientFingerprint: cfg.GlobalClientFingerprint, diff --git a/hub/executor/executor.go b/hub/executor/executor.go index 19979063..3fed360c 100644 --- a/hub/executor/executor.go +++ b/hub/executor/executor.go @@ -9,6 +9,7 @@ import ( "strconv" "sync" "time" + _ "unsafe" "github.com/metacubex/mihomo/adapter" "github.com/metacubex/mihomo/adapter/inbound" @@ -16,7 +17,7 @@ import ( "github.com/metacubex/mihomo/component/auth" "github.com/metacubex/mihomo/component/ca" "github.com/metacubex/mihomo/component/dialer" - G "github.com/metacubex/mihomo/component/geodata" + "github.com/metacubex/mihomo/component/geodata" mihomoHttp "github.com/metacubex/mihomo/component/http" "github.com/metacubex/mihomo/component/iface" "github.com/metacubex/mihomo/component/keepalive" @@ -101,7 +102,7 @@ func ApplyConfig(cfg *config.Config, force bool) { updateRules(cfg.Rules, cfg.SubRules, cfg.RuleProviders) updateSniffer(cfg.Sniffer) updateHosts(cfg.Hosts) - updateGeneral(cfg.General) + updateGeneral(cfg.General, true) updateNTP(cfg.NTP) updateDNS(cfg.DNS, cfg.General.IPv6) updateListeners(cfg.General, cfg.Listeners, force) @@ -161,16 +162,16 @@ func GetGeneral() *config.General { Interface: dialer.DefaultInterface.Load(), RoutingMark: int(dialer.DefaultRoutingMark.Load()), GeoXUrl: config.GeoXUrl{ - GeoIp: G.GeoIpUrl(), - Mmdb: G.MmdbUrl(), - ASN: G.ASNUrl(), - GeoSite: G.GeoSiteUrl(), + GeoIp: geodata.GeoIpUrl(), + Mmdb: geodata.MmdbUrl(), + ASN: geodata.ASNUrl(), + GeoSite: geodata.GeoSiteUrl(), }, GeoAutoUpdate: updater.GeoAutoUpdate(), GeoUpdateInterval: updater.GeoUpdateInterval(), - GeodataMode: G.GeodataMode(), - GeodataLoader: G.LoaderName(), - GeositeMatcher: G.SiteMatcherName(), + GeodataMode: geodata.GeodataMode(), + GeodataLoader: geodata.LoaderName(), + GeositeMatcher: geodata.SiteMatcherName(), TCPConcurrent: dialer.GetTcpConcurrent(), FindProcessMode: tunnel.FindProcessMode(), Sniffing: tunnel.IsSniffing(), @@ -408,13 +409,22 @@ func updateUpdater(cfg *config.Config) { updater.DefaultUiUpdater.AutoDownloadUI() } -func updateGeneral(general *config.General) { +//go:linkname temporaryUpdateGeneral github.com/metacubex/mihomo/config.temporaryUpdateGeneral +func temporaryUpdateGeneral(general *config.General) func() { + oldGeneral := GetGeneral() + updateGeneral(general, false) + return func() { + updateGeneral(oldGeneral, false) + } +} + +func updateGeneral(general *config.General, logging bool) { tunnel.SetMode(general.Mode) tunnel.SetFindProcessMode(general.FindProcessMode) resolver.DisableIPv6 = !general.IPv6 - if general.TCPConcurrent { - dialer.SetTcpConcurrent(general.TCPConcurrent) + dialer.SetTcpConcurrent(general.TCPConcurrent) + if logging && general.TCPConcurrent { log.Infoln("Use tcp concurrent") } @@ -429,13 +439,23 @@ func updateGeneral(general *config.General) { dialer.DefaultInterface.Store(general.Interface) dialer.DefaultRoutingMark.Store(int32(general.RoutingMark)) - if general.RoutingMark > 0 { + if logging && general.RoutingMark > 0 { log.Infoln("Use routing mark: %#x", general.RoutingMark) } iface.FlushCache() - G.SetLoader(general.GeodataLoader) - G.SetSiteMatcher(general.GeositeMatcher) + + geodata.SetGeodataMode(general.GeodataMode) + geodata.SetLoader(general.GeodataLoader) + geodata.SetSiteMatcher(general.GeositeMatcher) + geodata.SetGeoIpUrl(general.GeoXUrl.GeoIp) + geodata.SetGeoSiteUrl(general.GeoXUrl.GeoSite) + geodata.SetMmdbUrl(general.GeoXUrl.Mmdb) + geodata.SetASNUrl(general.GeoXUrl.ASN) + mihomoHttp.SetUA(general.GlobalUA) + resource.SetETag(general.ETagSupport) + + tlsC.SetGlobalUtlsClient(general.GlobalClientFingerprint) } func updateUsers(users []auth.AuthUser) {