Refactor: load geo domain matcher
This commit is contained in:
parent
763929997b
commit
c1821e28d3
@ -2,9 +2,11 @@ package geodata
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Dreamacro/clash/component/geodata/router"
|
"github.com/Dreamacro/clash/component/geodata/router"
|
||||||
|
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
)
|
)
|
||||||
|
|
||||||
func LoadGeoSiteMatcher(countryCode string) (*router.DomainMatcher, int, error) {
|
func loadGeoSiteMatcher(countryCode string) (*router.DomainMatcher, int, error) {
|
||||||
geoLoaderName := "standard"
|
geoLoaderName := "standard"
|
||||||
geoLoader, err := GetGeoDataLoader(geoLoaderName)
|
geoLoader, err := GetGeoDataLoader(geoLoaderName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -28,3 +30,33 @@ func LoadGeoSiteMatcher(countryCode string) (*router.DomainMatcher, int, error)
|
|||||||
|
|
||||||
return matcher, len(domains), nil
|
return matcher, len(domains), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ruleProviders = make(map[string]*router.DomainMatcher)
|
||||||
|
|
||||||
|
// HasProvider has geo site provider by county code
|
||||||
|
func HasProvider(countyCode string) (ok bool) {
|
||||||
|
_, ok = ruleProviders[countyCode]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetProvidersList get geo site providers
|
||||||
|
func GetProvidersList(countyCode string) []*router.DomainMatcher {
|
||||||
|
return maps.Values(ruleProviders)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetProviderByCode get geo site provider by county code
|
||||||
|
func GetProviderByCode(countyCode string) (matcher *router.DomainMatcher, ok bool) {
|
||||||
|
matcher, ok = ruleProviders[countyCode]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadProviderByCode(countyCode string) (matcher *router.DomainMatcher, count int, err error) {
|
||||||
|
var ok bool
|
||||||
|
matcher, ok = ruleProviders[countyCode]
|
||||||
|
if !ok {
|
||||||
|
if matcher, count, err = loadGeoSiteMatcher(countyCode); err == nil {
|
||||||
|
ruleProviders[countyCode] = matcher
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"github.com/Dreamacro/clash/component/fakeip"
|
"github.com/Dreamacro/clash/component/fakeip"
|
||||||
"github.com/Dreamacro/clash/component/geodata"
|
"github.com/Dreamacro/clash/component/geodata"
|
||||||
"github.com/Dreamacro/clash/component/geodata/router"
|
"github.com/Dreamacro/clash/component/geodata/router"
|
||||||
|
_ "github.com/Dreamacro/clash/component/geodata/standard"
|
||||||
"github.com/Dreamacro/clash/component/trie"
|
"github.com/Dreamacro/clash/component/trie"
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
providerTypes "github.com/Dreamacro/clash/constant/provider"
|
providerTypes "github.com/Dreamacro/clash/constant/provider"
|
||||||
@ -316,7 +317,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
|
|||||||
}
|
}
|
||||||
config.Hosts = hosts
|
config.Hosts = hosts
|
||||||
|
|
||||||
dnsCfg, err := parseDNS(rawCfg, hosts, rules)
|
dnsCfg, err := parseDNS(rawCfg, hosts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -674,37 +675,27 @@ func parseFallbackIPCIDR(ips []string) ([]*netip.Prefix, error) {
|
|||||||
return ipNets, nil
|
return ipNets, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseFallbackGeoSite(countries []string, rules []C.Rule) ([]*router.DomainMatcher, error) {
|
func parseFallbackGeoSite(countries []string) ([]*router.DomainMatcher, error) {
|
||||||
var sites []*router.DomainMatcher
|
var sites []*router.DomainMatcher
|
||||||
|
|
||||||
for _, country := range countries {
|
for _, country := range countries {
|
||||||
found := false
|
matcher, recordsCount, err := geodata.LoadProviderByCode(country)
|
||||||
for _, rule := range rules {
|
if err != nil {
|
||||||
if rule.RuleType() == C.GEOSITE {
|
return nil, err
|
||||||
if strings.EqualFold(country, rule.Payload()) {
|
|
||||||
found = true
|
|
||||||
sites = append(sites, rule.(C.RuleGeoSite).GetDomainMatcher())
|
|
||||||
log.Infoln("Start initial GeoSite dns fallback filter from rule `%s`", country)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
sites = append(sites, matcher)
|
||||||
matcher, recordsCount, err := geodata.LoadGeoSiteMatcher(country)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sites = append(sites, matcher)
|
cont := fmt.Sprintf("%d", recordsCount)
|
||||||
|
if recordsCount == 0 {
|
||||||
log.Infoln("Start initial GeoSite dns fallback filter `%s`, records: %d", country, recordsCount)
|
cont = "from cache"
|
||||||
}
|
}
|
||||||
|
log.Infoln("Start initial GeoSite dns fallback filter `%s`, records: %s", country, cont)
|
||||||
}
|
}
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
return sites, nil
|
return sites, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[netip.Addr], rules []C.Rule) (*DNS, error) {
|
func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[netip.Addr]) (*DNS, error) {
|
||||||
cfg := rawCfg.DNS
|
cfg := rawCfg.DNS
|
||||||
if cfg.Enable && len(cfg.NameServer) == 0 {
|
if cfg.Enable && len(cfg.NameServer) == 0 {
|
||||||
return nil, fmt.Errorf("if DNS configuration is turned on, NameServer cannot be empty")
|
return nil, fmt.Errorf("if DNS configuration is turned on, NameServer cannot be empty")
|
||||||
@ -798,7 +789,7 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[netip.Addr], rules []C.R
|
|||||||
dnsCfg.FallbackFilter.IPCIDR = fallbackip
|
dnsCfg.FallbackFilter.IPCIDR = fallbackip
|
||||||
}
|
}
|
||||||
dnsCfg.FallbackFilter.Domain = cfg.FallbackFilter.Domain
|
dnsCfg.FallbackFilter.Domain = cfg.FallbackFilter.Domain
|
||||||
fallbackGeoSite, err := parseFallbackGeoSite(cfg.FallbackFilter.GeoSite, rules)
|
fallbackGeoSite, err := parseFallbackGeoSite(cfg.FallbackFilter.GeoSite)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("load GeoSite dns fallback filter error, %w", err)
|
return nil, fmt.Errorf("load GeoSite dns fallback filter error, %w", err)
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
|
|
||||||
"github.com/Dreamacro/clash/component/geodata"
|
"github.com/Dreamacro/clash/component/geodata"
|
||||||
"github.com/Dreamacro/clash/component/geodata/router"
|
"github.com/Dreamacro/clash/component/geodata/router"
|
||||||
_ "github.com/Dreamacro/clash/component/geodata/standard"
|
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
"github.com/Dreamacro/clash/log"
|
"github.com/Dreamacro/clash/log"
|
||||||
)
|
)
|
||||||
@ -47,12 +46,16 @@ func (gs *GEOSITE) GetDomainMatcher() *router.DomainMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewGEOSITE(country string, adapter string) (*GEOSITE, error) {
|
func NewGEOSITE(country string, adapter string) (*GEOSITE, error) {
|
||||||
matcher, recordsCount, err := geodata.LoadGeoSiteMatcher(country)
|
matcher, recordsCount, err := geodata.LoadProviderByCode(country)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("load GeoSite data error, %s", err.Error())
|
return nil, fmt.Errorf("load GeoSite data error, %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infoln("Start initial GeoSite rule %s => %s, records: %d", country, adapter, recordsCount)
|
cont := fmt.Sprintf("%d", recordsCount)
|
||||||
|
if recordsCount == 0 {
|
||||||
|
cont = "from cache"
|
||||||
|
}
|
||||||
|
log.Infoln("Start initial GeoSite rule %s => %s, records: %s", country, adapter, cont)
|
||||||
|
|
||||||
geoSite := &GEOSITE{
|
geoSite := &GEOSITE{
|
||||||
Base: &Base{},
|
Base: &Base{},
|
||||||
|
Reference in New Issue
Block a user