github.com/v2fly/v2ray-core/v4@v4.45.2/infra/conf/geodata/geodata.go (about) 1 package geodata 2 3 import ( 4 "strings" 5 6 "github.com/v2fly/v2ray-core/v4/app/router" 7 ) 8 9 type loader struct { 10 LoaderImplementation 11 } 12 13 func (l *loader) LoadGeoSite(list string) ([]*router.Domain, error) { 14 return l.LoadGeoSiteWithAttr("geosite.dat", list) 15 } 16 17 func (l *loader) LoadGeoSiteWithAttr(file string, siteWithAttr string) ([]*router.Domain, error) { 18 parts := strings.Split(siteWithAttr, "@") 19 if len(parts) == 0 { 20 return nil, newError("empty rule") 21 } 22 list := strings.TrimSpace(parts[0]) 23 attrVal := parts[1:] 24 25 if len(list) == 0 { 26 return nil, newError("empty listname in rule: ", siteWithAttr) 27 } 28 29 domains, err := l.LoadSite(file, list) 30 if err != nil { 31 return nil, err 32 } 33 34 attrs := parseAttrs(attrVal) 35 if attrs.IsEmpty() { 36 if strings.Contains(siteWithAttr, "@") { 37 newError("empty attribute list: ", siteWithAttr) 38 } 39 return domains, nil 40 } 41 42 filteredDomains := make([]*router.Domain, 0, len(domains)) 43 hasAttrMatched := false 44 for _, domain := range domains { 45 if attrs.Match(domain) { 46 hasAttrMatched = true 47 filteredDomains = append(filteredDomains, domain) 48 } 49 } 50 if !hasAttrMatched { 51 newError("attribute match no rule: geosite:", siteWithAttr) 52 } 53 54 return filteredDomains, nil 55 } 56 57 func (l *loader) LoadGeoIP(country string) ([]*router.CIDR, error) { 58 return l.LoadIP("geoip.dat", country) 59 } 60 61 var loaders map[string]func() LoaderImplementation 62 63 func RegisterGeoDataLoaderImplementationCreator(name string, loader func() LoaderImplementation) { 64 if loaders == nil { 65 loaders = map[string]func() LoaderImplementation{} 66 } 67 loaders[name] = loader 68 } 69 70 func getGeoDataLoaderImplementation(name string) (LoaderImplementation, error) { 71 if geoLoader, ok := loaders[name]; ok { 72 return geoLoader(), nil 73 } 74 return nil, newError("unable to locate GeoData loader ", name) 75 } 76 77 func GetGeoDataLoader(name string) (Loader, error) { 78 loadImpl, err := getGeoDataLoaderImplementation(name) 79 if err == nil { 80 return &loader{loadImpl}, nil 81 } 82 return nil, err 83 }