mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2024-11-14 21:31:16 +08:00
feat: sniffer
's force-domain
and skip-domain
support rule-set:
and geosite:
This commit is contained in:
parent
696b75ee37
commit
7fd0467aef
@ -8,7 +8,6 @@ import (
|
|||||||
|
|
||||||
"github.com/metacubex/mihomo/common/nnip"
|
"github.com/metacubex/mihomo/common/nnip"
|
||||||
"github.com/metacubex/mihomo/component/profile/cachefile"
|
"github.com/metacubex/mihomo/component/profile/cachefile"
|
||||||
"github.com/metacubex/mihomo/component/trie"
|
|
||||||
C "github.com/metacubex/mihomo/constant"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -36,8 +35,7 @@ type Pool struct {
|
|||||||
offset netip.Addr
|
offset netip.Addr
|
||||||
cycle bool
|
cycle bool
|
||||||
mux sync.Mutex
|
mux sync.Mutex
|
||||||
host *trie.DomainTrie[struct{}]
|
host []C.Rule
|
||||||
rules []C.Rule
|
|
||||||
ipnet netip.Prefix
|
ipnet netip.Prefix
|
||||||
store store
|
store store
|
||||||
}
|
}
|
||||||
@ -68,14 +66,8 @@ func (p *Pool) LookBack(ip netip.Addr) (string, bool) {
|
|||||||
|
|
||||||
// ShouldSkipped return if domain should be skipped
|
// ShouldSkipped return if domain should be skipped
|
||||||
func (p *Pool) ShouldSkipped(domain string) bool {
|
func (p *Pool) ShouldSkipped(domain string) bool {
|
||||||
if p.host != nil {
|
for _, rule := range p.host {
|
||||||
if p.host.Search(domain) != nil {
|
if match, _ := rule.Match(&C.Metadata{Host: domain}); match {
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, rule := range p.rules {
|
|
||||||
metadata := &C.Metadata{Host: domain}
|
|
||||||
if match, _ := rule.Match(metadata); match {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,9 +156,7 @@ func (p *Pool) restoreState() {
|
|||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
IPNet netip.Prefix
|
IPNet netip.Prefix
|
||||||
Host *trie.DomainTrie[struct{}]
|
Host []C.Rule
|
||||||
|
|
||||||
Rules []C.Rule
|
|
||||||
|
|
||||||
// Size sets the maximum number of entries in memory
|
// Size sets the maximum number of entries in memory
|
||||||
// and does not work if Persistence is true
|
// and does not work if Persistence is true
|
||||||
@ -197,7 +187,6 @@ func New(options Options) (*Pool, error) {
|
|||||||
offset: first.Prev(),
|
offset: first.Prev(),
|
||||||
cycle: false,
|
cycle: false,
|
||||||
host: options.Host,
|
host: options.Host,
|
||||||
rules: options.Rules,
|
|
||||||
ipnet: options.IPNet,
|
ipnet: options.IPNet,
|
||||||
}
|
}
|
||||||
if options.Persistence {
|
if options.Persistence {
|
||||||
|
@ -9,6 +9,8 @@ import (
|
|||||||
|
|
||||||
"github.com/metacubex/mihomo/component/profile/cachefile"
|
"github.com/metacubex/mihomo/component/profile/cachefile"
|
||||||
"github.com/metacubex/mihomo/component/trie"
|
"github.com/metacubex/mihomo/component/trie"
|
||||||
|
C "github.com/metacubex/mihomo/constant"
|
||||||
|
RP "github.com/metacubex/mihomo/rules/provider"
|
||||||
|
|
||||||
"github.com/sagernet/bbolt"
|
"github.com/sagernet/bbolt"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -154,7 +156,7 @@ func TestPool_Skip(t *testing.T) {
|
|||||||
pools, tempfile, err := createPools(Options{
|
pools, tempfile, err := createPools(Options{
|
||||||
IPNet: ipnet,
|
IPNet: ipnet,
|
||||||
Size: 10,
|
Size: 10,
|
||||||
Host: tree,
|
Host: []C.Rule{RP.NewDomainSet(tree.NewDomainSet(), "")},
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
defer os.Remove(tempfile)
|
defer os.Remove(tempfile)
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
|
|
||||||
"github.com/metacubex/mihomo/common/lru"
|
"github.com/metacubex/mihomo/common/lru"
|
||||||
N "github.com/metacubex/mihomo/common/net"
|
N "github.com/metacubex/mihomo/common/net"
|
||||||
"github.com/metacubex/mihomo/component/trie"
|
|
||||||
C "github.com/metacubex/mihomo/constant"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
"github.com/metacubex/mihomo/constant/sniffer"
|
"github.com/metacubex/mihomo/constant/sniffer"
|
||||||
"github.com/metacubex/mihomo/log"
|
"github.com/metacubex/mihomo/log"
|
||||||
@ -26,17 +25,26 @@ var Dispatcher *SnifferDispatcher
|
|||||||
type SnifferDispatcher struct {
|
type SnifferDispatcher struct {
|
||||||
enable bool
|
enable bool
|
||||||
sniffers map[sniffer.Sniffer]SnifferConfig
|
sniffers map[sniffer.Sniffer]SnifferConfig
|
||||||
forceDomain *trie.DomainSet
|
forceDomain []C.Rule
|
||||||
skipSNI *trie.DomainSet
|
skipDomain []C.Rule
|
||||||
skipList *lru.LruCache[string, uint8]
|
skipList *lru.LruCache[string, uint8]
|
||||||
forceDnsMapping bool
|
forceDnsMapping bool
|
||||||
parsePureIp bool
|
parsePureIp bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sd *SnifferDispatcher) shouldOverride(metadata *C.Metadata) bool {
|
func (sd *SnifferDispatcher) shouldOverride(metadata *C.Metadata) bool {
|
||||||
return (metadata.Host == "" && sd.parsePureIp) ||
|
if metadata.Host == "" && sd.parsePureIp {
|
||||||
sd.forceDomain.Has(metadata.Host) ||
|
return true
|
||||||
(metadata.DNSMode == C.DNSMapping && sd.forceDnsMapping)
|
}
|
||||||
|
if metadata.DNSMode == C.DNSMapping && sd.forceDnsMapping {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, rule := range sd.forceDomain {
|
||||||
|
if ok, _ := rule.Match(&C.Metadata{Host: metadata.Host}); ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sd *SnifferDispatcher) UDPSniff(packet C.PacketAdapter) bool {
|
func (sd *SnifferDispatcher) UDPSniff(packet C.PacketAdapter) bool {
|
||||||
@ -94,9 +102,11 @@ func (sd *SnifferDispatcher) TCPSniff(conn *N.BufferedConn, metadata *C.Metadata
|
|||||||
log.Debugln("[Sniffer] All sniffing sniff failed with from [%s:%d] to [%s:%d]", metadata.SrcIP, metadata.SrcPort, metadata.String(), metadata.DstPort)
|
log.Debugln("[Sniffer] All sniffing sniff failed with from [%s:%d] to [%s:%d]", metadata.SrcIP, metadata.SrcPort, metadata.String(), metadata.DstPort)
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
if sd.skipSNI.Has(host) {
|
for _, rule := range sd.skipDomain {
|
||||||
log.Debugln("[Sniffer] Skip sni[%s]", host)
|
if ok, _ := rule.Match(&C.Metadata{Host: host}); ok {
|
||||||
return false
|
log.Debugln("[Sniffer] Skip sni[%s]", host)
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sd.skipList.Delete(dst)
|
sd.skipList.Delete(dst)
|
||||||
@ -187,12 +197,12 @@ func NewCloseSnifferDispatcher() (*SnifferDispatcher, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewSnifferDispatcher(snifferConfig map[sniffer.Type]SnifferConfig,
|
func NewSnifferDispatcher(snifferConfig map[sniffer.Type]SnifferConfig,
|
||||||
forceDomain *trie.DomainSet, skipSNI *trie.DomainSet,
|
forceDomain []C.Rule, skipDomain []C.Rule,
|
||||||
forceDnsMapping bool, parsePureIp bool) (*SnifferDispatcher, error) {
|
forceDnsMapping bool, parsePureIp bool) (*SnifferDispatcher, error) {
|
||||||
dispatcher := SnifferDispatcher{
|
dispatcher := SnifferDispatcher{
|
||||||
enable: true,
|
enable: true,
|
||||||
forceDomain: forceDomain,
|
forceDomain: forceDomain,
|
||||||
skipSNI: skipSNI,
|
skipDomain: skipDomain,
|
||||||
skipList: lru.New(lru.WithSize[string, uint8](128), lru.WithAge[string, uint8](600)),
|
skipList: lru.New(lru.WithSize[string, uint8](128), lru.WithAge[string, uint8](600)),
|
||||||
forceDnsMapping: forceDnsMapping,
|
forceDnsMapping: forceDnsMapping,
|
||||||
parsePureIp: parsePureIp,
|
parsePureIp: parsePureIp,
|
||||||
|
@ -134,6 +134,13 @@ func (t *DomainTrie[T]) Foreach(fn func(domain string, data T) bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *DomainTrie[T]) IsEmpty() bool {
|
||||||
|
if t == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return t.root.isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
func recursion[T any](items []string, node *Node[T], fn func(domain string, data T) bool) bool {
|
func recursion[T any](items []string, node *Node[T], fn func(domain string, data T) bool) bool {
|
||||||
for key, data := range node.getChildren() {
|
for key, data := range node.getChildren() {
|
||||||
newItems := append([]string{key}, items...)
|
newItems := append([]string{key}, items...)
|
||||||
|
170
config/config.go
170
config/config.go
@ -164,8 +164,8 @@ type IPTables struct {
|
|||||||
type Sniffer struct {
|
type Sniffer struct {
|
||||||
Enable bool
|
Enable bool
|
||||||
Sniffers map[snifferTypes.Type]SNIFF.SnifferConfig
|
Sniffers map[snifferTypes.Type]SNIFF.SnifferConfig
|
||||||
ForceDomain *trie.DomainSet
|
ForceDomain []C.Rule
|
||||||
SkipDomain *trie.DomainSet
|
SkipDomain []C.Rule
|
||||||
ForceDnsMapping bool
|
ForceDnsMapping bool
|
||||||
ParsePureIp bool
|
ParsePureIp bool
|
||||||
}
|
}
|
||||||
@ -627,7 +627,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Sniffer, err = parseSniffer(rawCfg.Sniffer)
|
config.Sniffer, err = parseSniffer(rawCfg.Sniffer, rules, ruleProviders)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1408,87 +1408,27 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var host *trie.DomainTrie[struct{}]
|
var fakeIPTrie *trie.DomainTrie[struct{}]
|
||||||
var fakeIPRules []C.Rule
|
|
||||||
// fake ip skip host filter
|
|
||||||
if len(cfg.FakeIPFilter) != 0 {
|
|
||||||
host = trie.New[struct{}]()
|
|
||||||
for _, domain := range cfg.FakeIPFilter {
|
|
||||||
if strings.Contains(strings.ToLower(domain), ",") {
|
|
||||||
if strings.Contains(domain, "geosite:") {
|
|
||||||
subkeys := strings.Split(domain, ":")
|
|
||||||
subkeys = subkeys[1:]
|
|
||||||
subkeys = strings.Split(subkeys[0], ",")
|
|
||||||
for _, country := range subkeys {
|
|
||||||
found := false
|
|
||||||
for _, rule := range rules {
|
|
||||||
if rule.RuleType() == C.GEOSITE {
|
|
||||||
if strings.EqualFold(country, rule.Payload()) {
|
|
||||||
found = true
|
|
||||||
fakeIPRules = append(fakeIPRules, rule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
rule, err := RC.NewGEOSITE(country, "")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
fakeIPRules = append(fakeIPRules, rule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} else if strings.Contains(strings.ToLower(domain), "rule-set:") {
|
|
||||||
subkeys := strings.Split(domain, ":")
|
|
||||||
subkeys = subkeys[1:]
|
|
||||||
subkeys = strings.Split(subkeys[0], ",")
|
|
||||||
for _, domainSetName := range subkeys {
|
|
||||||
if rp, ok := ruleProviders[domainSetName]; !ok {
|
|
||||||
return nil, fmt.Errorf("not found rule-set: %s", domainSetName)
|
|
||||||
} else {
|
|
||||||
switch rp.Behavior() {
|
|
||||||
case providerTypes.IPCIDR:
|
|
||||||
return nil, fmt.Errorf("rule provider type error, except domain,actual %s", rp.Behavior())
|
|
||||||
case providerTypes.Classical:
|
|
||||||
log.Warnln("%s provider is %s, only matching it contain domain rule", rp.Name(), rp.Behavior())
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rule, err := RP.NewRuleSet(domainSetName, "", true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
fakeIPRules = append(fakeIPRules, rule)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_ = host.Insert(domain, struct{}{})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(dnsCfg.Fallback) != 0 {
|
if len(dnsCfg.Fallback) != 0 {
|
||||||
if host == nil {
|
fakeIPTrie = trie.New[struct{}]()
|
||||||
host = trie.New[struct{}]()
|
|
||||||
}
|
|
||||||
for _, fb := range dnsCfg.Fallback {
|
for _, fb := range dnsCfg.Fallback {
|
||||||
if net.ParseIP(fb.Addr) != nil {
|
if net.ParseIP(fb.Addr) != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_ = host.Insert(fb.Addr, struct{}{})
|
_ = fakeIPTrie.Insert(fb.Addr, struct{}{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if host != nil {
|
// fake ip skip host filter
|
||||||
host.Optimize()
|
host, err := parseDomain(cfg.FakeIPFilter, fakeIPTrie, rules, ruleProviders)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pool, err := fakeip.New(fakeip.Options{
|
pool, err := fakeip.New(fakeip.Options{
|
||||||
IPNet: fakeIPRange,
|
IPNet: fakeIPRange,
|
||||||
Size: 1000,
|
Size: 1000,
|
||||||
Host: host,
|
Host: host,
|
||||||
Rules: fakeIPRules,
|
|
||||||
Persistence: rawCfg.Profile.StoreFakeIP,
|
Persistence: rawCfg.Profile.StoreFakeIP,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1609,7 +1549,7 @@ func parseTuicServer(rawTuic RawTuicServer, general *General) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseSniffer(snifferRaw RawSniffer) (*Sniffer, error) {
|
func parseSniffer(snifferRaw RawSniffer, rules []C.Rule, ruleProviders map[string]providerTypes.RuleProvider) (*Sniffer, error) {
|
||||||
sniffer := &Sniffer{
|
sniffer := &Sniffer{
|
||||||
Enable: snifferRaw.Enable,
|
Enable: snifferRaw.Enable,
|
||||||
ForceDnsMapping: snifferRaw.ForceDnsMapping,
|
ForceDnsMapping: snifferRaw.ForceDnsMapping,
|
||||||
@ -1672,23 +1612,83 @@ func parseSniffer(snifferRaw RawSniffer) (*Sniffer, error) {
|
|||||||
|
|
||||||
sniffer.Sniffers = loadSniffer
|
sniffer.Sniffers = loadSniffer
|
||||||
|
|
||||||
forceDomainTrie := trie.New[struct{}]()
|
forceDomain, err := parseDomain(snifferRaw.ForceDomain, nil, rules, ruleProviders)
|
||||||
for _, domain := range snifferRaw.ForceDomain {
|
if err != nil {
|
||||||
err := forceDomainTrie.Insert(domain, struct{}{})
|
return nil, fmt.Errorf("error in force-domain, error:%w", err)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error domian[%s] in force-domain, error:%v", domain, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sniffer.ForceDomain = forceDomainTrie.NewDomainSet()
|
sniffer.ForceDomain = forceDomain
|
||||||
|
|
||||||
skipDomainTrie := trie.New[struct{}]()
|
skipDomain, err := parseDomain(snifferRaw.SkipDomain, nil, rules, ruleProviders)
|
||||||
for _, domain := range snifferRaw.SkipDomain {
|
if err != nil {
|
||||||
err := skipDomainTrie.Insert(domain, struct{}{})
|
return nil, fmt.Errorf("error in skip-domain, error:%w", err)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error domian[%s] in force-domain, error:%v", domain, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sniffer.SkipDomain = skipDomainTrie.NewDomainSet()
|
sniffer.SkipDomain = skipDomain
|
||||||
|
|
||||||
return sniffer, nil
|
return sniffer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], rules []C.Rule, ruleProviders map[string]providerTypes.RuleProvider) (domainRules []C.Rule, err error) {
|
||||||
|
var rule C.Rule
|
||||||
|
for _, domain := range domains {
|
||||||
|
domainLower := strings.ToLower(domain)
|
||||||
|
if strings.Contains(domainLower, "geosite:") {
|
||||||
|
subkeys := strings.Split(domain, ":")
|
||||||
|
subkeys = subkeys[1:]
|
||||||
|
subkeys = strings.Split(subkeys[0], ",")
|
||||||
|
for _, country := range subkeys {
|
||||||
|
found := false
|
||||||
|
for _, rule = range rules {
|
||||||
|
if rule.RuleType() == C.GEOSITE {
|
||||||
|
if strings.EqualFold(country, rule.Payload()) {
|
||||||
|
found = true
|
||||||
|
domainRules = append(domainRules, rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
rule, err = RC.NewGEOSITE(country, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
domainRules = append(domainRules, rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if strings.Contains(domainLower, "rule-set:") {
|
||||||
|
subkeys := strings.Split(domain, ":")
|
||||||
|
subkeys = subkeys[1:]
|
||||||
|
subkeys = strings.Split(subkeys[0], ",")
|
||||||
|
for _, domainSetName := range subkeys {
|
||||||
|
if rp, ok := ruleProviders[domainSetName]; !ok {
|
||||||
|
return nil, fmt.Errorf("not found rule-set: %s", domainSetName)
|
||||||
|
} else {
|
||||||
|
switch rp.Behavior() {
|
||||||
|
case providerTypes.IPCIDR:
|
||||||
|
return nil, fmt.Errorf("rule provider type error, except domain,actual %s", rp.Behavior())
|
||||||
|
case providerTypes.Classical:
|
||||||
|
log.Warnln("%s provider is %s, only matching it contain domain rule", rp.Name(), rp.Behavior())
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rule, err = RP.NewRuleSet(domainSetName, "", true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
domainRules = append(domainRules, rule)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if domainTrie == nil {
|
||||||
|
domainTrie = trie.New[struct{}]()
|
||||||
|
}
|
||||||
|
err = domainTrie.Insert(domain, struct{}{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !domainTrie.IsEmpty() {
|
||||||
|
rule = RP.NewDomainSet(domainTrie.NewDomainSet(), "")
|
||||||
|
domainRules = append(domainRules, rule)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@ -27,6 +27,7 @@ const (
|
|||||||
ProcessNameRegex
|
ProcessNameRegex
|
||||||
ProcessPathRegex
|
ProcessPathRegex
|
||||||
RuleSet
|
RuleSet
|
||||||
|
DomainSet
|
||||||
Network
|
Network
|
||||||
Uid
|
Uid
|
||||||
SubRules
|
SubRules
|
||||||
@ -90,6 +91,8 @@ func (rt RuleType) String() string {
|
|||||||
return "Match"
|
return "Match"
|
||||||
case RuleSet:
|
case RuleSet:
|
||||||
return "RuleSet"
|
return "RuleSet"
|
||||||
|
case DomainSet:
|
||||||
|
return "DomainSet"
|
||||||
case Network:
|
case Network:
|
||||||
return "Network"
|
return "Network"
|
||||||
case DSCP:
|
case DSCP:
|
||||||
|
43
rules/provider/domain_set.go
Normal file
43
rules/provider/domain_set.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/metacubex/mihomo/component/trie"
|
||||||
|
C "github.com/metacubex/mihomo/constant"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DomainSet struct {
|
||||||
|
*domainStrategy
|
||||||
|
adapter string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DomainSet) ProviderNames() []string {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DomainSet) RuleType() C.RuleType {
|
||||||
|
return C.DomainSet
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DomainSet) Match(metadata *C.Metadata) (bool, string) {
|
||||||
|
if d.domainSet == nil {
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
return d.domainSet.Has(metadata.RuleHost()), d.adapter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DomainSet) Adapter() string {
|
||||||
|
return d.adapter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DomainSet) Payload() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDomainSet(domainSet *trie.DomainSet, adapter string) *DomainSet {
|
||||||
|
return &DomainSet{
|
||||||
|
domainStrategy: &domainStrategy{domainSet: domainSet},
|
||||||
|
adapter: adapter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ C.Rule = (*DomainSet)(nil)
|
Loading…
Reference in New Issue
Block a user