geodata.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package conf
  2. import (
  3. "runtime"
  4. "strings"
  5. "github.com/v2fly/v2ray-core/v4/app/router"
  6. "github.com/v2fly/v2ray-core/v4/common/geodata"
  7. )
  8. func loadGeoIP(country string) ([]*router.CIDR, error) {
  9. return geodata.LoadIP("geoip.dat", country)
  10. }
  11. func loadGeosite(list string) ([]*router.Domain, error) {
  12. return loadGeositeWithAttr("geosite.dat", list)
  13. }
  14. func loadGeositeWithAttr(filename string, siteWithAttr string) ([]*router.Domain, error) {
  15. parts := strings.Split(siteWithAttr, "@")
  16. if len(parts) == 0 {
  17. return nil, newError("empty rule")
  18. }
  19. list := strings.TrimSpace(parts[0])
  20. attrVal := parts[1:]
  21. if len(list) == 0 {
  22. return nil, newError("empty listname in rule: ", siteWithAttr)
  23. }
  24. domains, err := geodata.LoadSite(filename, list)
  25. if err != nil {
  26. return nil, err
  27. }
  28. attrs := parseAttrs(attrVal)
  29. if attrs.IsEmpty() {
  30. if strings.Contains(siteWithAttr, "@") {
  31. newError("empty attribute list: ", siteWithAttr)
  32. }
  33. return domains, nil
  34. }
  35. filteredDomains := make([]*router.Domain, 0, len(domains))
  36. hasAttrMatched := false
  37. for _, domain := range domains {
  38. if attrs.Match(domain) {
  39. hasAttrMatched = true
  40. filteredDomains = append(filteredDomains, domain)
  41. }
  42. }
  43. if !hasAttrMatched {
  44. newError("attribute match no rule: geosite:", siteWithAttr)
  45. }
  46. runtime.GC()
  47. return filteredDomains, nil
  48. }