mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2024-11-15 21:51:23 +08:00
113 lines
2.2 KiB
Go
113 lines
2.2 KiB
Go
|
package router
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"net"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/Dreamacro/clash/rule/geodata/strmatcher"
|
||
|
)
|
||
|
|
||
|
var matcherTypeMap = map[Domain_Type]strmatcher.Type{
|
||
|
Domain_Plain: strmatcher.Substr,
|
||
|
Domain_Regex: strmatcher.Regex,
|
||
|
Domain_Domain: strmatcher.Domain,
|
||
|
Domain_Full: strmatcher.Full,
|
||
|
}
|
||
|
|
||
|
func domainToMatcher(domain *Domain) (strmatcher.Matcher, error) {
|
||
|
matcherType, f := matcherTypeMap[domain.Type]
|
||
|
if !f {
|
||
|
return nil, fmt.Errorf("unsupported domain type %v", domain.Type)
|
||
|
}
|
||
|
|
||
|
matcher, err := matcherType.New(domain.Value)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("failed to create domain matcher, base error: %s", err.Error())
|
||
|
}
|
||
|
|
||
|
return matcher, nil
|
||
|
}
|
||
|
|
||
|
type DomainMatcher struct {
|
||
|
matchers strmatcher.IndexMatcher
|
||
|
}
|
||
|
|
||
|
func NewMphMatcherGroup(domains []*Domain) (*DomainMatcher, error) {
|
||
|
g := strmatcher.NewMphMatcherGroup()
|
||
|
for _, d := range domains {
|
||
|
matcherType, f := matcherTypeMap[d.Type]
|
||
|
if !f {
|
||
|
return nil, fmt.Errorf("unsupported domain type %v", d.Type)
|
||
|
}
|
||
|
_, err := g.AddPattern(d.Value, matcherType)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
}
|
||
|
g.Build()
|
||
|
return &DomainMatcher{
|
||
|
matchers: g,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
func NewDomainMatcher(domains []*Domain) (*DomainMatcher, error) {
|
||
|
g := new(strmatcher.MatcherGroup)
|
||
|
for _, d := range domains {
|
||
|
m, err := domainToMatcher(d)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
g.Add(m)
|
||
|
}
|
||
|
|
||
|
return &DomainMatcher{
|
||
|
matchers: g,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
func (m *DomainMatcher) ApplyDomain(domain string) bool {
|
||
|
return len(m.matchers.Match(strings.ToLower(domain))) > 0
|
||
|
}
|
||
|
|
||
|
type MultiGeoIPMatcher struct {
|
||
|
matchers []*GeoIPMatcher
|
||
|
}
|
||
|
|
||
|
func NewMultiGeoIPMatcher(geoips []*GeoIP) (*MultiGeoIPMatcher, error) {
|
||
|
var matchers []*GeoIPMatcher
|
||
|
for _, geoip := range geoips {
|
||
|
matcher, err := globalGeoIPContainer.Add(geoip)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
matchers = append(matchers, matcher)
|
||
|
}
|
||
|
|
||
|
matcher := &MultiGeoIPMatcher{
|
||
|
matchers: matchers,
|
||
|
}
|
||
|
|
||
|
return matcher, nil
|
||
|
}
|
||
|
|
||
|
func (m *MultiGeoIPMatcher) ApplyIp(ip net.IP) bool {
|
||
|
|
||
|
for _, matcher := range m.matchers {
|
||
|
if matcher.Match(ip) {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
func NewGeoIPMatcher(geoip *GeoIP) (*GeoIPMatcher, error) {
|
||
|
matcher, err := globalGeoIPContainer.Add(geoip)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return matcher, nil
|
||
|
}
|