Xray-core/common/matcher/domain/conf/domain.go

95 lines
2.6 KiB
Go
Raw Normal View History

2021-03-24 15:01:20 +00:00
package conf
import (
"strings"
dm "github.com/xtls/xray-core/common/matcher/domain"
"github.com/xtls/xray-core/common/matcher/geosite"
)
2021-03-26 08:56:43 +00:00
func ParseDomainRule(domain string) ([]*dm.Domain, error) {
2021-03-24 15:01:20 +00:00
if strings.HasPrefix(domain, "geosite:") {
country := strings.ToUpper(domain[8:])
domains, err := geosite.LoadGeositeWithAttr("geosite.dat", country)
if err != nil {
return nil, newError("failed to load geosite: ", country).Base(err)
}
return domains, nil
}
var isExtDatFile = 0
{
const prefix = "ext:"
if strings.HasPrefix(domain, prefix) {
isExtDatFile = len(prefix)
}
const prefixQualified = "ext-domain:"
if strings.HasPrefix(domain, prefixQualified) {
isExtDatFile = len(prefixQualified)
}
}
if isExtDatFile != 0 {
kv := strings.Split(domain[isExtDatFile:], ":")
if len(kv) != 2 {
return nil, newError("invalid external resource: ", domain)
}
filename := kv[0]
country := kv[1]
domains, err := geosite.LoadGeositeWithAttr(filename, country)
if err != nil {
return nil, newError("failed to load external sites: ", country, " from ", filename).Base(err)
}
return domains, nil
}
domainRule := new(dm.Domain)
switch {
case strings.HasPrefix(domain, "regexp:"):
2021-04-08 05:19:25 +00:00
regexpVal := domain[7:]
if len(regexpVal) == 0 {
return nil, newError("empty regexp type of rule: ", domain)
}
2021-03-24 15:01:20 +00:00
domainRule.Type = dm.MatchingType_Regex
2021-04-08 05:19:25 +00:00
domainRule.Value = regexpVal
2021-03-24 15:01:20 +00:00
case strings.HasPrefix(domain, "domain:"):
2021-04-08 05:19:25 +00:00
domainName := domain[7:]
if len(domainName) == 0 {
return nil, newError("empty domain type of rule: ", domain)
}
2021-03-24 15:01:20 +00:00
domainRule.Type = dm.MatchingType_Subdomain
2021-04-08 05:19:25 +00:00
domainRule.Value = domainName
2021-03-24 15:01:20 +00:00
case strings.HasPrefix(domain, "full:"):
2021-04-08 05:19:25 +00:00
fullVal := domain[5:]
if len(fullVal) == 0 {
return nil, newError("empty full domain type of rule: ", domain)
}
2021-03-24 15:01:20 +00:00
domainRule.Type = dm.MatchingType_Full
2021-04-08 05:19:25 +00:00
domainRule.Value = fullVal
2021-03-24 15:01:20 +00:00
case strings.HasPrefix(domain, "keyword:"):
2021-04-08 05:19:25 +00:00
keywordVal := domain[8:]
if len(keywordVal) == 0 {
return nil, newError("empty keyword type of rule: ", domain)
}
2021-03-24 15:01:20 +00:00
domainRule.Type = dm.MatchingType_Keyword
2021-04-08 05:19:25 +00:00
domainRule.Value = keywordVal
2021-03-24 15:01:20 +00:00
case strings.HasPrefix(domain, "dotless:"):
domainRule.Type = dm.MatchingType_Regex
switch substr := domain[8:]; {
case substr == "":
domainRule.Value = "^[^.]*$"
case !strings.Contains(substr, "."):
domainRule.Value = "^[^.]*" + substr + "[^.]*$"
default:
return nil, newError("substr in dotless rule should not contain a dot: ", substr)
}
default:
domainRule.Type = dm.MatchingType_Keyword
domainRule.Value = domain
}
return []*dm.Domain{domainRule}, nil
}