chore: cleanup geo internal code

This commit is contained in:
wwqgtxx 2024-09-09 16:08:48 +08:00
parent ef244b896a
commit 7c8f451892
16 changed files with 219 additions and 214 deletions

View File

@ -130,7 +130,7 @@ func (pp *proxySetProvider) getSubscriptionInfo() {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*90) ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
defer cancel() defer cancel()
resp, err := mihomoHttp.HttpRequestWithProxy(ctx, pp.Vehicle().(*resource.HTTPVehicle).Url(), resp, err := mihomoHttp.HttpRequestWithProxy(ctx, pp.Vehicle().(*resource.HTTPVehicle).Url(),
http.MethodGet, http.Header{"User-Agent": {C.UA}}, nil, pp.Vehicle().Proxy()) http.MethodGet, nil, nil, pp.Vehicle().Proxy())
if err != nil { if err != nil {
return return
} }

View File

@ -6,8 +6,10 @@ import (
"io" "io"
"net/http" "net/http"
"os" "os"
"sync"
"time" "time"
"github.com/metacubex/mihomo/common/atomic"
mihomoHttp "github.com/metacubex/mihomo/component/http" mihomoHttp "github.com/metacubex/mihomo/component/http"
"github.com/metacubex/mihomo/component/mmdb" "github.com/metacubex/mihomo/component/mmdb"
C "github.com/metacubex/mihomo/constant" C "github.com/metacubex/mihomo/constant"
@ -18,12 +20,79 @@ var (
initGeoSite bool initGeoSite bool
initGeoIP int initGeoIP int
initASN bool initASN bool
initGeoSiteMutex sync.Mutex
initGeoIPMutex sync.Mutex
initASNMutex sync.Mutex
geoIpEnable atomic.Bool
geoSiteEnable atomic.Bool
asnEnable atomic.Bool
geoIpUrl string
mmdbUrl string
geoSiteUrl string
asnUrl string
) )
func GeoIpUrl() string {
return geoIpUrl
}
func SetGeoIpUrl(url string) {
geoIpUrl = url
}
func MmdbUrl() string {
return mmdbUrl
}
func SetMmdbUrl(url string) {
mmdbUrl = url
}
func GeoSiteUrl() string {
return geoSiteUrl
}
func SetGeoSiteUrl(url string) {
geoSiteUrl = url
}
func ASNUrl() string {
return asnUrl
}
func SetASNUrl(url string) {
asnUrl = url
}
func downloadToPath(url string, path string) (err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
defer cancel()
resp, err := mihomoHttp.HttpRequest(ctx, url, http.MethodGet, nil, nil)
if err != nil {
return
}
defer resp.Body.Close()
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0o644)
if err != nil {
return err
}
defer f.Close()
_, err = io.Copy(f, resp.Body)
return err
}
func InitGeoSite() error { func InitGeoSite() error {
geoSiteEnable.Store(true)
initGeoSiteMutex.Lock()
defer initGeoSiteMutex.Unlock()
if _, err := os.Stat(C.Path.GeoSite()); os.IsNotExist(err) { if _, err := os.Stat(C.Path.GeoSite()); os.IsNotExist(err) {
log.Infoln("Can't find GeoSite.dat, start download") log.Infoln("Can't find GeoSite.dat, start download")
if err := downloadGeoSite(C.Path.GeoSite()); err != nil { if err := downloadToPath(GeoSiteUrl(), C.Path.GeoSite()); err != nil {
return fmt.Errorf("can't download GeoSite.dat: %s", err.Error()) return fmt.Errorf("can't download GeoSite.dat: %s", err.Error())
} }
log.Infoln("Download GeoSite.dat finish") log.Infoln("Download GeoSite.dat finish")
@ -35,7 +104,7 @@ func InitGeoSite() error {
if err := os.Remove(C.Path.GeoSite()); err != nil { if err := os.Remove(C.Path.GeoSite()); err != nil {
return fmt.Errorf("can't remove invalid GeoSite.dat: %s", err.Error()) return fmt.Errorf("can't remove invalid GeoSite.dat: %s", err.Error())
} }
if err := downloadGeoSite(C.Path.GeoSite()); err != nil { if err := downloadToPath(GeoSiteUrl(), C.Path.GeoSite()); err != nil {
return fmt.Errorf("can't download GeoSite.dat: %s", err.Error()) return fmt.Errorf("can't download GeoSite.dat: %s", err.Error())
} }
} }
@ -44,49 +113,14 @@ func InitGeoSite() error {
return nil return nil
} }
func downloadGeoSite(path string) (err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
defer cancel()
resp, err := mihomoHttp.HttpRequest(ctx, C.GeoSiteUrl, http.MethodGet, http.Header{"User-Agent": {C.UA}}, nil)
if err != nil {
return
}
defer resp.Body.Close()
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0o644)
if err != nil {
return err
}
defer f.Close()
_, err = io.Copy(f, resp.Body)
return err
}
func downloadGeoIP(path string) (err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
defer cancel()
resp, err := mihomoHttp.HttpRequest(ctx, C.GeoIpUrl, http.MethodGet, http.Header{"User-Agent": {C.UA}}, nil)
if err != nil {
return
}
defer resp.Body.Close()
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0o644)
if err != nil {
return err
}
defer f.Close()
_, err = io.Copy(f, resp.Body)
return err
}
func InitGeoIP() error { func InitGeoIP() error {
if C.GeodataMode { geoIpEnable.Store(true)
initGeoIPMutex.Lock()
defer initGeoIPMutex.Unlock()
if GeodataMode() {
if _, err := os.Stat(C.Path.GeoIP()); os.IsNotExist(err) { if _, err := os.Stat(C.Path.GeoIP()); os.IsNotExist(err) {
log.Infoln("Can't find GeoIP.dat, start download") log.Infoln("Can't find GeoIP.dat, start download")
if err := downloadGeoIP(C.Path.GeoIP()); err != nil { if err := downloadToPath(GeoIpUrl(), C.Path.GeoIP()); err != nil {
return fmt.Errorf("can't download GeoIP.dat: %s", err.Error()) return fmt.Errorf("can't download GeoIP.dat: %s", err.Error())
} }
log.Infoln("Download GeoIP.dat finish") log.Infoln("Download GeoIP.dat finish")
@ -99,7 +133,7 @@ func InitGeoIP() error {
if err := os.Remove(C.Path.GeoIP()); err != nil { if err := os.Remove(C.Path.GeoIP()); err != nil {
return fmt.Errorf("can't remove invalid GeoIP.dat: %s", err.Error()) return fmt.Errorf("can't remove invalid GeoIP.dat: %s", err.Error())
} }
if err := downloadGeoIP(C.Path.GeoIP()); err != nil { if err := downloadToPath(GeoIpUrl(), C.Path.GeoIP()); err != nil {
return fmt.Errorf("can't download GeoIP.dat: %s", err.Error()) return fmt.Errorf("can't download GeoIP.dat: %s", err.Error())
} }
} }
@ -110,7 +144,7 @@ func InitGeoIP() error {
if _, err := os.Stat(C.Path.MMDB()); os.IsNotExist(err) { if _, err := os.Stat(C.Path.MMDB()); os.IsNotExist(err) {
log.Infoln("Can't find MMDB, start download") log.Infoln("Can't find MMDB, start download")
if err := mmdb.DownloadMMDB(C.Path.MMDB()); err != nil { if err := downloadToPath(MmdbUrl(), C.Path.MMDB()); err != nil {
return fmt.Errorf("can't download MMDB: %s", err.Error()) return fmt.Errorf("can't download MMDB: %s", err.Error())
} }
} }
@ -121,7 +155,7 @@ func InitGeoIP() error {
if err := os.Remove(C.Path.MMDB()); err != nil { if err := os.Remove(C.Path.MMDB()); err != nil {
return fmt.Errorf("can't remove invalid MMDB: %s", err.Error()) return fmt.Errorf("can't remove invalid MMDB: %s", err.Error())
} }
if err := mmdb.DownloadMMDB(C.Path.MMDB()); err != nil { if err := downloadToPath(MmdbUrl(), C.Path.MMDB()); err != nil {
return fmt.Errorf("can't download MMDB: %s", err.Error()) return fmt.Errorf("can't download MMDB: %s", err.Error())
} }
} }
@ -131,9 +165,12 @@ func InitGeoIP() error {
} }
func InitASN() error { func InitASN() error {
asnEnable.Store(true)
initASNMutex.Lock()
defer initASNMutex.Unlock()
if _, err := os.Stat(C.Path.ASN()); os.IsNotExist(err) { if _, err := os.Stat(C.Path.ASN()); os.IsNotExist(err) {
log.Infoln("Can't find ASN.mmdb, start download") log.Infoln("Can't find ASN.mmdb, start download")
if err := mmdb.DownloadASN(C.Path.ASN()); err != nil { if err := downloadToPath(ASNUrl(), C.Path.ASN()); err != nil {
return fmt.Errorf("can't download ASN.mmdb: %s", err.Error()) return fmt.Errorf("can't download ASN.mmdb: %s", err.Error())
} }
log.Infoln("Download ASN.mmdb finish") log.Infoln("Download ASN.mmdb finish")
@ -145,7 +182,7 @@ func InitASN() error {
if err := os.Remove(C.Path.ASN()); err != nil { if err := os.Remove(C.Path.ASN()); err != nil {
return fmt.Errorf("can't remove invalid ASN: %s", err.Error()) return fmt.Errorf("can't remove invalid ASN: %s", err.Error())
} }
if err := mmdb.DownloadASN(C.Path.ASN()); err != nil { if err := downloadToPath(ASNUrl(), C.Path.ASN()); err != nil {
return fmt.Errorf("can't download ASN: %s", err.Error()) return fmt.Errorf("can't download ASN: %s", err.Error())
} }
} }
@ -153,3 +190,15 @@ func InitASN() error {
} }
return nil return nil
} }
func GeoIpEnable() bool {
return geoIpEnable.Load()
}
func GeoSiteEnable() bool {
return geoSiteEnable.Load()
}
func ASNEnable() bool {
return asnEnable.Load()
}

View File

@ -13,8 +13,6 @@ import (
var ( var (
geoMode bool geoMode bool
AutoUpdate bool
UpdateInterval int
geoLoaderName = "memconservative" geoLoaderName = "memconservative"
geoSiteMatcher = "succinct" geoSiteMatcher = "succinct"
) )
@ -25,14 +23,6 @@ func GeodataMode() bool {
return geoMode return geoMode
} }
func GeoAutoUpdate() bool {
return AutoUpdate
}
func GeoUpdateInterval() int {
return UpdateInterval
}
func LoaderName() string { func LoaderName() string {
return geoLoaderName return geoLoaderName
} }
@ -44,12 +34,6 @@ func SiteMatcherName() string {
func SetGeodataMode(newGeodataMode bool) { func SetGeodataMode(newGeodataMode bool) {
geoMode = newGeodataMode geoMode = newGeodataMode
} }
func SetGeoAutoUpdate(newAutoUpdate bool) {
AutoUpdate = newAutoUpdate
}
func SetGeoUpdateInterval(newGeoUpdateInterval int) {
UpdateInterval = newGeoUpdateInterval
}
func SetLoader(newLoader string) { func SetLoader(newLoader string) {
if newLoader == "memc" { if newLoader == "memc" {

View File

@ -12,10 +12,21 @@ import (
"time" "time"
"github.com/metacubex/mihomo/component/ca" "github.com/metacubex/mihomo/component/ca"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/listener/inner" "github.com/metacubex/mihomo/listener/inner"
) )
var (
ua string
)
func UA() string {
return ua
}
func SetUA(UA string) {
ua = UA
}
func HttpRequest(ctx context.Context, url, method string, header map[string][]string, body io.Reader) (*http.Response, error) { func HttpRequest(ctx context.Context, url, method string, header map[string][]string, body io.Reader) (*http.Response, error) {
return HttpRequestWithProxy(ctx, url, method, header, body, "") return HttpRequestWithProxy(ctx, url, method, header, body, "")
} }
@ -35,7 +46,7 @@ func HttpRequestWithProxy(ctx context.Context, url, method string, header map[st
} }
if _, ok := header["User-Agent"]; !ok { if _, ok := header["User-Agent"]; !ok {
req.Header.Set("User-Agent", C.UA) req.Header.Set("User-Agent", UA())
} }
if err != nil { if err != nil {

View File

@ -1,15 +1,9 @@
package mmdb package mmdb
import ( import (
"context"
"io"
"net/http"
"os"
"sync" "sync"
"time"
mihomoOnce "github.com/metacubex/mihomo/common/once" mihomoOnce "github.com/metacubex/mihomo/common/once"
mihomoHttp "github.com/metacubex/mihomo/component/http"
C "github.com/metacubex/mihomo/constant" C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/log" "github.com/metacubex/mihomo/log"
@ -25,26 +19,26 @@ const (
) )
var ( var (
IPreader IPReader ipReader IPReader
ASNreader ASNReader asnReader ASNReader
IPonce sync.Once ipOnce sync.Once
ASNonce sync.Once asnOnce sync.Once
) )
func LoadFromBytes(buffer []byte) { func LoadFromBytes(buffer []byte) {
IPonce.Do(func() { ipOnce.Do(func() {
mmdb, err := maxminddb.FromBytes(buffer) mmdb, err := maxminddb.FromBytes(buffer)
if err != nil { if err != nil {
log.Fatalln("Can't load mmdb: %s", err.Error()) log.Fatalln("Can't load mmdb: %s", err.Error())
} }
IPreader = IPReader{Reader: mmdb} ipReader = IPReader{Reader: mmdb}
switch mmdb.Metadata.DatabaseType { switch mmdb.Metadata.DatabaseType {
case "sing-geoip": case "sing-geoip":
IPreader.databaseType = typeSing ipReader.databaseType = typeSing
case "Meta-geoip0": case "Meta-geoip0":
IPreader.databaseType = typeMetaV0 ipReader.databaseType = typeMetaV0
default: default:
IPreader.databaseType = typeMaxmind ipReader.databaseType = typeMaxmind
} }
}) })
} }
@ -58,83 +52,45 @@ func Verify(path string) bool {
} }
func IPInstance() IPReader { func IPInstance() IPReader {
IPonce.Do(func() { ipOnce.Do(func() {
mmdbPath := C.Path.MMDB() mmdbPath := C.Path.MMDB()
log.Infoln("Load MMDB file: %s", mmdbPath) log.Infoln("Load MMDB file: %s", mmdbPath)
mmdb, err := maxminddb.Open(mmdbPath) mmdb, err := maxminddb.Open(mmdbPath)
if err != nil { if err != nil {
log.Fatalln("Can't load MMDB: %s", err.Error()) log.Fatalln("Can't load MMDB: %s", err.Error())
} }
IPreader = IPReader{Reader: mmdb} ipReader = IPReader{Reader: mmdb}
switch mmdb.Metadata.DatabaseType { switch mmdb.Metadata.DatabaseType {
case "sing-geoip": case "sing-geoip":
IPreader.databaseType = typeSing ipReader.databaseType = typeSing
case "Meta-geoip0": case "Meta-geoip0":
IPreader.databaseType = typeMetaV0 ipReader.databaseType = typeMetaV0
default: default:
IPreader.databaseType = typeMaxmind ipReader.databaseType = typeMaxmind
} }
}) })
return IPreader return ipReader
}
func DownloadMMDB(path string) (err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
defer cancel()
resp, err := mihomoHttp.HttpRequest(ctx, C.MmdbUrl, http.MethodGet, http.Header{"User-Agent": {C.UA}}, nil)
if err != nil {
return
}
defer resp.Body.Close()
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0o644)
if err != nil {
return err
}
defer f.Close()
_, err = io.Copy(f, resp.Body)
return err
} }
func ASNInstance() ASNReader { func ASNInstance() ASNReader {
ASNonce.Do(func() { asnOnce.Do(func() {
ASNPath := C.Path.ASN() ASNPath := C.Path.ASN()
log.Infoln("Load ASN file: %s", ASNPath) log.Infoln("Load ASN file: %s", ASNPath)
asn, err := maxminddb.Open(ASNPath) asn, err := maxminddb.Open(ASNPath)
if err != nil { if err != nil {
log.Fatalln("Can't load ASN: %s", err.Error()) log.Fatalln("Can't load ASN: %s", err.Error())
} }
ASNreader = ASNReader{Reader: asn} asnReader = ASNReader{Reader: asn}
}) })
return ASNreader return asnReader
}
func DownloadASN(path string) (err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
defer cancel()
resp, err := mihomoHttp.HttpRequest(ctx, C.ASNUrl, http.MethodGet, http.Header{"User-Agent": {C.UA}}, nil)
if err != nil {
return
}
defer resp.Body.Close()
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0o644)
if err != nil {
return err
}
defer f.Close()
_, err = io.Copy(f, resp.Body)
return err
} }
func ReloadIP() { func ReloadIP() {
mihomoOnce.Reset(&IPonce) mihomoOnce.Reset(&ipOnce)
} }
func ReloadASN() { func ReloadASN() {
mihomoOnce.Reset(&ASNonce) mihomoOnce.Reset(&asnOnce)
} }

View File

@ -8,11 +8,11 @@ func InstallOverride(override *maxminddb.Reader) {
newReader := IPReader{Reader: override} newReader := IPReader{Reader: override}
switch override.Metadata.DatabaseType { switch override.Metadata.DatabaseType {
case "sing-geoip": case "sing-geoip":
IPreader.databaseType = typeSing ipReader.databaseType = typeSing
case "Meta-geoip0": case "Meta-geoip0":
IPreader.databaseType = typeMetaV0 ipReader.databaseType = typeMetaV0
default: default:
IPreader.databaseType = typeMaxmind ipReader.databaseType = typeMaxmind
} }
IPreader = newReader ipReader = newReader
} }

View File

@ -237,7 +237,7 @@ const MaxPackageFileSize = 32 * 1024 * 1024
func downloadPackageFile() (err error) { func downloadPackageFile() (err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*90) ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
defer cancel() defer cancel()
resp, err := mihomoHttp.HttpRequest(ctx, packageURL, http.MethodGet, http.Header{"User-Agent": {C.UA}}, nil) resp, err := mihomoHttp.HttpRequest(ctx, packageURL, http.MethodGet, nil, nil)
if err != nil { if err != nil {
return fmt.Errorf("http request failed: %w", err) return fmt.Errorf("http request failed: %w", err)
} }
@ -418,7 +418,7 @@ func copyFile(src, dst string) error {
func getLatestVersion() (version string, err error) { func getLatestVersion() (version string, err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel() defer cancel()
resp, err := mihomoHttp.HttpRequest(ctx, versionURL, http.MethodGet, http.Header{"User-Agent": {C.UA}}, nil) resp, err := mihomoHttp.HttpRequest(ctx, versionURL, http.MethodGet, nil, nil)
if err != nil { if err != nil {
return "", fmt.Errorf("get Latest Version fail: %w", err) return "", fmt.Errorf("get Latest Version fail: %w", err)
} }

View File

@ -20,12 +20,31 @@ import (
) )
var ( var (
autoUpdate bool
updateInterval int
updatingGeo atomic.Bool updatingGeo atomic.Bool
) )
func GeoAutoUpdate() bool {
return autoUpdate
}
func GeoUpdateInterval() int {
return updateInterval
}
func SetGeoAutoUpdate(newAutoUpdate bool) {
autoUpdate = newAutoUpdate
}
func SetGeoUpdateInterval(newGeoUpdateInterval int) {
updateInterval = newGeoUpdateInterval
}
func UpdateMMDB() (err error) { func UpdateMMDB() (err error) {
defer mmdb.ReloadIP() defer mmdb.ReloadIP()
data, err := downloadForBytes(C.MmdbUrl) data, err := downloadForBytes(geodata.MmdbUrl())
if err != nil { if err != nil {
return fmt.Errorf("can't download MMDB database file: %w", err) return fmt.Errorf("can't download MMDB database file: %w", err)
} }
@ -44,7 +63,7 @@ func UpdateMMDB() (err error) {
func UpdateASN() (err error) { func UpdateASN() (err error) {
defer mmdb.ReloadASN() defer mmdb.ReloadASN()
data, err := downloadForBytes(C.ASNUrl) data, err := downloadForBytes(geodata.ASNUrl())
if err != nil { if err != nil {
return fmt.Errorf("can't download ASN database file: %w", err) return fmt.Errorf("can't download ASN database file: %w", err)
} }
@ -65,7 +84,7 @@ func UpdateASN() (err error) {
func UpdateGeoIp() (err error) { func UpdateGeoIp() (err error) {
defer geodata.ClearGeoIPCache() defer geodata.ClearGeoIPCache()
geoLoader, err := geodata.GetGeoDataLoader("standard") geoLoader, err := geodata.GetGeoDataLoader("standard")
data, err := downloadForBytes(C.GeoIpUrl) data, err := downloadForBytes(geodata.GeoIpUrl())
if err != nil { if err != nil {
return fmt.Errorf("can't download GeoIP database file: %w", err) return fmt.Errorf("can't download GeoIP database file: %w", err)
} }
@ -81,7 +100,7 @@ func UpdateGeoIp() (err error) {
func UpdateGeoSite() (err error) { func UpdateGeoSite() (err error) {
defer geodata.ClearGeoSiteCache() defer geodata.ClearGeoSiteCache()
geoLoader, err := geodata.GetGeoDataLoader("standard") geoLoader, err := geodata.GetGeoDataLoader("standard")
data, err := downloadForBytes(C.GeoSiteUrl) data, err := downloadForBytes(geodata.GeoSiteUrl())
if err != nil { if err != nil {
return fmt.Errorf("can't download GeoSite database file: %w", err) return fmt.Errorf("can't download GeoSite database file: %w", err)
} }
@ -101,29 +120,33 @@ func updateGeoDatabases() error {
b, _ := batch.New[interface{}](context.Background()) b, _ := batch.New[interface{}](context.Background())
if C.GeodataMode { if geodata.GeoIpEnable() {
b.Go("UpdateGeoIp", func() (_ interface{}, err error) { if geodata.GeodataMode() {
err = UpdateGeoIp() b.Go("UpdateGeoIp", func() (_ interface{}, err error) {
return err = UpdateGeoIp()
}) return
} else { })
b.Go("UpdateMMDB", func() (_ interface{}, err error) { } else {
err = UpdateMMDB() b.Go("UpdateMMDB", func() (_ interface{}, err error) {
return err = UpdateMMDB()
}) return
})
}
} }
if C.ASNEnable { if geodata.ASNEnable() {
b.Go("UpdateASN", func() (_ interface{}, err error) { b.Go("UpdateASN", func() (_ interface{}, err error) {
err = UpdateASN() err = UpdateASN()
return return
}) })
} }
b.Go("UpdateGeoSite", func() (_ interface{}, err error) { if geodata.GeoSiteEnable() {
err = UpdateGeoSite() b.Go("UpdateGeoSite", func() (_ interface{}, err error) {
return err = UpdateGeoSite()
}) return
})
}
if e := b.Wait(); e != nil { if e := b.Wait(); e != nil {
return e.Err return e.Err
@ -156,7 +179,7 @@ func UpdateGeoDatabases() error {
func getUpdateTime() (err error, time time.Time) { func getUpdateTime() (err error, time time.Time) {
var fileInfo os.FileInfo var fileInfo os.FileInfo
if C.GeodataMode { if geodata.GeodataMode() {
fileInfo, err = os.Stat(C.Path.GeoIP()) fileInfo, err = os.Stat(C.Path.GeoIP())
if err != nil { if err != nil {
return err, time return err, time
@ -172,13 +195,13 @@ func getUpdateTime() (err error, time time.Time) {
} }
func RegisterGeoUpdater() { func RegisterGeoUpdater() {
if C.GeoUpdateInterval <= 0 { if updateInterval <= 0 {
log.Errorln("[GEO] Invalid update interval: %d", C.GeoUpdateInterval) log.Errorln("[GEO] Invalid update interval: %d", updateInterval)
return return
} }
go func() { go func() {
ticker := time.NewTicker(time.Duration(C.GeoUpdateInterval) * time.Hour) ticker := time.NewTicker(time.Duration(updateInterval) * time.Hour)
defer ticker.Stop() defer ticker.Stop()
err, lastUpdate := getUpdateTime() err, lastUpdate := getUpdateTime()
@ -188,8 +211,8 @@ func RegisterGeoUpdater() {
} }
log.Infoln("[GEO] last update time %s", lastUpdate) log.Infoln("[GEO] last update time %s", lastUpdate)
if lastUpdate.Add(time.Duration(C.GeoUpdateInterval) * time.Hour).Before(time.Now()) { if lastUpdate.Add(time.Duration(updateInterval) * time.Hour).Before(time.Now()) {
log.Infoln("[GEO] Database has not been updated for %v, update now", time.Duration(C.GeoUpdateInterval)*time.Hour) log.Infoln("[GEO] Database has not been updated for %v, update now", time.Duration(updateInterval)*time.Hour)
if err := UpdateGeoDatabases(); err != nil { if err := UpdateGeoDatabases(); err != nil {
log.Errorln("[GEO] Failed to update GEO database: %s", err.Error()) log.Errorln("[GEO] Failed to update GEO database: %s", err.Error())
return return
@ -197,7 +220,7 @@ func RegisterGeoUpdater() {
} }
for range ticker.C { for range ticker.C {
log.Infoln("[GEO] updating database every %d hours", C.GeoUpdateInterval) log.Infoln("[GEO] updating database every %d hours", updateInterval)
if err := UpdateGeoDatabases(); err != nil { if err := UpdateGeoDatabases(); err != nil {
log.Errorln("[GEO] Failed to update GEO database: %s", err.Error()) log.Errorln("[GEO] Failed to update GEO database: %s", err.Error())
} }

View File

@ -9,7 +9,6 @@ import (
"time" "time"
mihomoHttp "github.com/metacubex/mihomo/component/http" mihomoHttp "github.com/metacubex/mihomo/component/http"
C "github.com/metacubex/mihomo/constant"
"golang.org/x/exp/constraints" "golang.org/x/exp/constraints"
) )
@ -17,7 +16,7 @@ import (
func downloadForBytes(url string) ([]byte, error) { func downloadForBytes(url string) ([]byte, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*90) ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
defer cancel() defer cancel()
resp, err := mihomoHttp.HttpRequest(ctx, url, http.MethodGet, http.Header{"User-Agent": {C.UA}}, nil) resp, err := mihomoHttp.HttpRequest(ctx, url, http.MethodGet, nil, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -22,6 +22,7 @@ import (
"github.com/metacubex/mihomo/component/cidr" "github.com/metacubex/mihomo/component/cidr"
"github.com/metacubex/mihomo/component/fakeip" "github.com/metacubex/mihomo/component/fakeip"
"github.com/metacubex/mihomo/component/geodata" "github.com/metacubex/mihomo/component/geodata"
mihomoHttp "github.com/metacubex/mihomo/component/http"
P "github.com/metacubex/mihomo/component/process" P "github.com/metacubex/mihomo/component/process"
"github.com/metacubex/mihomo/component/resolver" "github.com/metacubex/mihomo/component/resolver"
"github.com/metacubex/mihomo/component/sniffer" "github.com/metacubex/mihomo/component/sniffer"
@ -433,7 +434,7 @@ func DefaultRawConfig() *RawConfig {
Mode: T.Rule, Mode: T.Rule,
GeoAutoUpdate: false, GeoAutoUpdate: false,
GeoUpdateInterval: 24, GeoUpdateInterval: 24,
GeodataMode: C.GeodataMode, GeodataMode: geodata.GeodataMode(),
GeodataLoader: "memconservative", GeodataLoader: "memconservative",
UnifiedDelay: false, UnifiedDelay: false,
Authentication: []string{}, Authentication: []string{},
@ -681,19 +682,16 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
} }
func parseGeneral(cfg *RawConfig) (*General, error) { func parseGeneral(cfg *RawConfig) (*General, error) {
updater.SetGeoAutoUpdate(cfg.GeoAutoUpdate)
updater.SetGeoUpdateInterval(cfg.GeoUpdateInterval)
geodata.SetGeodataMode(cfg.GeodataMode) geodata.SetGeodataMode(cfg.GeodataMode)
geodata.SetGeoAutoUpdate(cfg.GeoAutoUpdate)
geodata.SetGeoUpdateInterval(cfg.GeoUpdateInterval)
geodata.SetLoader(cfg.GeodataLoader) geodata.SetLoader(cfg.GeodataLoader)
geodata.SetSiteMatcher(cfg.GeositeMatcher) geodata.SetSiteMatcher(cfg.GeositeMatcher)
C.GeoAutoUpdate = cfg.GeoAutoUpdate geodata.SetGeoIpUrl(cfg.GeoXUrl.GeoIp)
C.GeoUpdateInterval = cfg.GeoUpdateInterval geodata.SetGeoSiteUrl(cfg.GeoXUrl.GeoSite)
C.GeoIpUrl = cfg.GeoXUrl.GeoIp geodata.SetMmdbUrl(cfg.GeoXUrl.Mmdb)
C.GeoSiteUrl = cfg.GeoXUrl.GeoSite geodata.SetASNUrl(cfg.GeoXUrl.ASN)
C.MmdbUrl = cfg.GeoXUrl.Mmdb mihomoHttp.SetUA(cfg.GlobalUA)
C.ASNUrl = cfg.GeoXUrl.ASN
C.GeodataMode = cfg.GeodataMode
C.UA = cfg.GlobalUA
if cfg.KeepAliveIdle != 0 { if cfg.KeepAliveIdle != 0 {
N.KeepAliveIdle = time.Duration(cfg.KeepAliveIdle) * time.Second N.KeepAliveIdle = time.Duration(cfg.KeepAliveIdle) * time.Second

View File

@ -1,12 +0,0 @@
package constant
var (
ASNEnable bool
GeodataMode bool
GeoAutoUpdate bool
GeoUpdateInterval int
GeoIpUrl string
MmdbUrl string
GeoSiteUrl string
ASNUrl string
)

View File

@ -1,5 +0,0 @@
package constant
var (
UA string
)

View File

@ -17,6 +17,7 @@ import (
"github.com/metacubex/mihomo/component/ca" "github.com/metacubex/mihomo/component/ca"
"github.com/metacubex/mihomo/component/dialer" "github.com/metacubex/mihomo/component/dialer"
G "github.com/metacubex/mihomo/component/geodata" G "github.com/metacubex/mihomo/component/geodata"
mihomoHttp "github.com/metacubex/mihomo/component/http"
"github.com/metacubex/mihomo/component/iface" "github.com/metacubex/mihomo/component/iface"
"github.com/metacubex/mihomo/component/profile" "github.com/metacubex/mihomo/component/profile"
"github.com/metacubex/mihomo/component/profile/cachefile" "github.com/metacubex/mihomo/component/profile/cachefile"
@ -81,6 +82,7 @@ func ParseWithBytes(buf []byte) (*config.Config, error) {
func ApplyConfig(cfg *config.Config, force bool) { func ApplyConfig(cfg *config.Config, force bool) {
mux.Lock() mux.Lock()
defer mux.Unlock() defer mux.Unlock()
log.SetLevel(cfg.General.LogLevel)
tunnel.OnSuspend() tunnel.OnSuspend()
@ -115,8 +117,6 @@ func ApplyConfig(cfg *config.Config, force bool) {
tunnel.OnRunning() tunnel.OnRunning()
hcCompatibleProvider(cfg.Providers) hcCompatibleProvider(cfg.Providers)
initExternalUI() initExternalUI()
log.SetLevel(cfg.General.LogLevel)
} }
func initInnerTcp() { func initInnerTcp() {
@ -157,13 +157,13 @@ func GetGeneral() *config.General {
Interface: dialer.DefaultInterface.Load(), Interface: dialer.DefaultInterface.Load(),
RoutingMark: int(dialer.DefaultRoutingMark.Load()), RoutingMark: int(dialer.DefaultRoutingMark.Load()),
GeoXUrl: config.GeoXUrl{ GeoXUrl: config.GeoXUrl{
GeoIp: C.GeoIpUrl, GeoIp: G.GeoIpUrl(),
Mmdb: C.MmdbUrl, Mmdb: G.MmdbUrl(),
ASN: C.ASNUrl, ASN: G.ASNUrl(),
GeoSite: C.GeoSiteUrl, GeoSite: G.GeoSiteUrl(),
}, },
GeoAutoUpdate: G.GeoAutoUpdate(), GeoAutoUpdate: updater.GeoAutoUpdate(),
GeoUpdateInterval: G.GeoUpdateInterval(), GeoUpdateInterval: updater.GeoUpdateInterval(),
GeodataMode: G.GeodataMode(), GeodataMode: G.GeodataMode(),
GeodataLoader: G.LoaderName(), GeodataLoader: G.LoaderName(),
GeositeMatcher: G.SiteMatcherName(), GeositeMatcher: G.SiteMatcherName(),
@ -171,7 +171,7 @@ func GetGeneral() *config.General {
FindProcessMode: tunnel.FindProcessMode(), FindProcessMode: tunnel.FindProcessMode(),
Sniffing: tunnel.IsSniffing(), Sniffing: tunnel.IsSniffing(),
GlobalClientFingerprint: tlsC.GetGlobalFingerprint(), GlobalClientFingerprint: tlsC.GetGlobalFingerprint(),
GlobalUA: C.UA, GlobalUA: mihomoHttp.UA(),
} }
return general return general

View File

@ -11,6 +11,7 @@ import (
"strings" "strings"
"syscall" "syscall"
"github.com/metacubex/mihomo/component/geodata"
"github.com/metacubex/mihomo/component/updater" "github.com/metacubex/mihomo/component/updater"
"github.com/metacubex/mihomo/config" "github.com/metacubex/mihomo/config"
C "github.com/metacubex/mihomo/constant" C "github.com/metacubex/mihomo/constant"
@ -78,7 +79,7 @@ func main() {
} }
if geodataMode { if geodataMode {
C.GeodataMode = true geodata.SetGeodataMode(true)
} }
if configString != "" { if configString != "" {
@ -140,7 +141,7 @@ func main() {
log.Fatalln("Parse config error: %s", err.Error()) log.Fatalln("Parse config error: %s", err.Error())
} }
if C.GeoAutoUpdate { if updater.GeoAutoUpdate() {
updater.RegisterGeoUpdater() updater.RegisterGeoUpdater()
} }

View File

@ -46,7 +46,7 @@ func (g *GEOIP) Match(metadata *C.Metadata) (bool, string) {
return g.isLan(ip), g.adapter return g.isLan(ip), g.adapter
} }
if C.GeodataMode { if geodata.GeodataMode() {
if g.isSourceIP { if g.isSourceIP {
if slices.Contains(metadata.SrcGeoIP, g.country) { if slices.Contains(metadata.SrcGeoIP, g.country) {
return true, g.adapter return true, g.adapter
@ -102,7 +102,7 @@ func (g *GEOIP) MatchIp(ip netip.Addr) bool {
return g.isLan(ip) return g.isLan(ip)
} }
if C.GeodataMode { if geodata.GeodataMode() {
matcher, err := g.getIPMatcher() matcher, err := g.getIPMatcher()
if err != nil { if err != nil {
return false return false
@ -124,7 +124,7 @@ func (g dnsFallbackFilter) MatchIp(ip netip.Addr) bool {
return false return false
} }
if C.GeodataMode { if geodata.GeodataMode() {
matcher, err := g.getIPMatcher() matcher, err := g.getIPMatcher()
if err != nil { if err != nil {
return false return false
@ -170,7 +170,7 @@ func (g *GEOIP) GetCountry() string {
} }
func (g *GEOIP) GetIPMatcher() (router.IPMatcher, error) { func (g *GEOIP) GetIPMatcher() (router.IPMatcher, error) {
if C.GeodataMode { if geodata.GeodataMode() {
return g.getIPMatcher() return g.getIPMatcher()
} }
return nil, errors.New("not geodata mode") return nil, errors.New("not geodata mode")
@ -193,10 +193,6 @@ func (g *GEOIP) GetRecodeSize() int {
} }
func NewGEOIP(country string, adapter string, isSrc, noResolveIP bool) (*GEOIP, error) { func NewGEOIP(country string, adapter string, isSrc, noResolveIP bool) (*GEOIP, error) {
if err := geodata.InitGeoIP(); err != nil {
log.Errorln("can't initial GeoIP: %s", err)
return nil, err
}
country = strings.ToLower(country) country = strings.ToLower(country)
geoip := &GEOIP{ geoip := &GEOIP{
@ -206,11 +202,17 @@ func NewGEOIP(country string, adapter string, isSrc, noResolveIP bool) (*GEOIP,
noResolveIP: noResolveIP, noResolveIP: noResolveIP,
isSourceIP: isSrc, isSourceIP: isSrc,
} }
if !C.GeodataMode || country == "lan" {
if country == "lan" {
return geoip, nil return geoip, nil
} }
if C.GeodataMode { if err := geodata.InitGeoIP(); err != nil {
log.Errorln("can't initial GeoIP: %s", err)
return nil, err
}
if geodata.GeodataMode() {
geoIPMatcher, err := geoip.getIPMatcher() // test load geoIPMatcher, err := geoip.getIPMatcher() // test load
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -63,7 +63,6 @@ func (a *ASN) GetASN() string {
} }
func NewIPASN(asn string, adapter string, isSrc, noResolveIP bool) (*ASN, error) { func NewIPASN(asn string, adapter string, isSrc, noResolveIP bool) (*ASN, error) {
C.ASNEnable = true
if err := geodata.InitASN(); err != nil { if err := geodata.InitASN(); err != nil {
log.Errorln("can't initial ASN: %s", err) log.Errorln("can't initial ASN: %s", err)
return nil, err return nil, err