mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-01-04 00:23:43 +08:00
chore: add sourceGeoIP
and sourceIPASN
to metadata
This commit is contained in:
parent
8483178524
commit
4fecf68b8b
@ -46,6 +46,14 @@ func (set *IpCidrSet) IsContain(ip netip.Addr) bool {
|
|||||||
return set.ToIPSet().Contains(ip.WithZone(""))
|
return set.ToIPSet().Contains(ip.WithZone(""))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MatchIp implements C.IpMatcher
|
||||||
|
func (set *IpCidrSet) MatchIp(ip netip.Addr) bool {
|
||||||
|
if set.IsEmpty() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return set.IsContain(ip)
|
||||||
|
}
|
||||||
|
|
||||||
func (set *IpCidrSet) Merge() error {
|
func (set *IpCidrSet) Merge() error {
|
||||||
var b netipx.IPSetBuilder
|
var b netipx.IPSetBuilder
|
||||||
b.AddSet(set.ToIPSet())
|
b.AddSet(set.ToIPSet())
|
||||||
|
@ -35,7 +35,7 @@ type Pool struct {
|
|||||||
offset netip.Addr
|
offset netip.Addr
|
||||||
cycle bool
|
cycle bool
|
||||||
mux sync.Mutex
|
mux sync.Mutex
|
||||||
host []C.Rule
|
host []C.DomainMatcher
|
||||||
ipnet netip.Prefix
|
ipnet netip.Prefix
|
||||||
store store
|
store store
|
||||||
}
|
}
|
||||||
@ -66,8 +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 {
|
||||||
for _, rule := range p.host {
|
for _, matcher := range p.host {
|
||||||
if match, _ := rule.Match(&C.Metadata{Host: domain}); match {
|
if matcher.MatchDomain(domain) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,7 +156,7 @@ func (p *Pool) restoreState() {
|
|||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
IPNet netip.Prefix
|
IPNet netip.Prefix
|
||||||
Host []C.Rule
|
Host []C.DomainMatcher
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -10,7 +10,6 @@ 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"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
RP "github.com/metacubex/mihomo/rules/provider"
|
|
||||||
|
|
||||||
"github.com/metacubex/bbolt"
|
"github.com/metacubex/bbolt"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -157,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: []C.Rule{RP.NewDomainSet(tree.NewDomainSet(), "")},
|
Host: []C.DomainMatcher{tree.NewDomainSet()},
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
defer os.Remove(tempfile)
|
defer os.Remove(tempfile)
|
||||||
|
@ -22,23 +22,23 @@ var (
|
|||||||
type Dispatcher struct {
|
type Dispatcher struct {
|
||||||
enable bool
|
enable bool
|
||||||
sniffers map[sniffer.Sniffer]SnifferConfig
|
sniffers map[sniffer.Sniffer]SnifferConfig
|
||||||
forceDomain []C.Rule
|
forceDomain []C.DomainMatcher
|
||||||
skipSrcAddress []C.Rule
|
skipSrcAddress []C.IpMatcher
|
||||||
skipDstAddress []C.Rule
|
skipDstAddress []C.IpMatcher
|
||||||
skipDomain []C.Rule
|
skipDomain []C.DomainMatcher
|
||||||
skipList *lru.LruCache[netip.AddrPort, uint8]
|
skipList *lru.LruCache[netip.AddrPort, uint8]
|
||||||
forceDnsMapping bool
|
forceDnsMapping bool
|
||||||
parsePureIp bool
|
parsePureIp bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sd *Dispatcher) shouldOverride(metadata *C.Metadata) bool {
|
func (sd *Dispatcher) shouldOverride(metadata *C.Metadata) bool {
|
||||||
for _, rule := range sd.skipDstAddress {
|
for _, matcher := range sd.skipDstAddress {
|
||||||
if ok, _ := rule.Match(&C.Metadata{DstIP: metadata.DstIP}); ok {
|
if matcher.MatchIp(metadata.DstIP) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, rule := range sd.skipSrcAddress {
|
for _, matcher := range sd.skipSrcAddress {
|
||||||
if ok, _ := rule.Match(&C.Metadata{DstIP: metadata.SrcIP}); ok {
|
if matcher.MatchIp(metadata.SrcIP) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,8 +48,8 @@ func (sd *Dispatcher) shouldOverride(metadata *C.Metadata) bool {
|
|||||||
if metadata.DNSMode == C.DNSMapping && sd.forceDnsMapping {
|
if metadata.DNSMode == C.DNSMapping && sd.forceDnsMapping {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
for _, rule := range sd.forceDomain {
|
for _, matcher := range sd.forceDomain {
|
||||||
if ok, _ := rule.Match(&C.Metadata{Host: metadata.Host}); ok {
|
if matcher.MatchDomain(metadata.Host) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,8 +112,8 @@ func (sd *Dispatcher) TCPSniff(conn *N.BufferedConn, metadata *C.Metadata) bool
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rule := range sd.skipDomain {
|
for _, matcher := range sd.skipDomain {
|
||||||
if ok, _ := rule.Match(&C.Metadata{Host: host}); ok {
|
if matcher.MatchDomain(host) {
|
||||||
log.Debugln("[Sniffer] Skip sni[%s]", host)
|
log.Debugln("[Sniffer] Skip sni[%s]", host)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -200,10 +200,10 @@ func (sd *Dispatcher) cacheSniffFailed(metadata *C.Metadata) {
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
Enable bool
|
Enable bool
|
||||||
Sniffers map[sniffer.Type]SnifferConfig
|
Sniffers map[sniffer.Type]SnifferConfig
|
||||||
ForceDomain []C.Rule
|
ForceDomain []C.DomainMatcher
|
||||||
SkipSrcAddress []C.Rule
|
SkipSrcAddress []C.IpMatcher
|
||||||
SkipDstAddress []C.Rule
|
SkipDstAddress []C.IpMatcher
|
||||||
SkipDomain []C.Rule
|
SkipDomain []C.DomainMatcher
|
||||||
ForceDnsMapping bool
|
ForceDnsMapping bool
|
||||||
ParsePureIp bool
|
ParsePureIp bool
|
||||||
}
|
}
|
||||||
|
@ -172,6 +172,11 @@ func (ss *DomainSet) Foreach(f func(key string) bool) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MatchDomain implements C.DomainMatcher
|
||||||
|
func (ss *DomainSet) MatchDomain(domain string) bool {
|
||||||
|
return ss.Has(domain)
|
||||||
|
}
|
||||||
|
|
||||||
func setBit(bm *[]uint64, i int, v int) {
|
func setBit(bm *[]uint64, i int, v int) {
|
||||||
for i>>6 >= len(*bm) {
|
for i>>6 >= len(*bm) {
|
||||||
*bm = append(*bm, 0)
|
*bm = append(*bm, 0)
|
||||||
|
@ -143,8 +143,8 @@ type DNS struct {
|
|||||||
UseSystemHosts bool
|
UseSystemHosts bool
|
||||||
NameServer []dns.NameServer
|
NameServer []dns.NameServer
|
||||||
Fallback []dns.NameServer
|
Fallback []dns.NameServer
|
||||||
FallbackIPFilter []C.Rule
|
FallbackIPFilter []C.IpMatcher
|
||||||
FallbackDomainFilter []C.Rule
|
FallbackDomainFilter []C.DomainMatcher
|
||||||
Listen string
|
Listen string
|
||||||
EnhancedMode C.DNSMode
|
EnhancedMode C.DNSMode
|
||||||
DefaultNameserver []dns.NameServer
|
DefaultNameserver []dns.NameServer
|
||||||
@ -640,7 +640,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
|
|||||||
}
|
}
|
||||||
config.Hosts = hosts
|
config.Hosts = hosts
|
||||||
|
|
||||||
dnsCfg, err := parseDNS(rawCfg, hosts, rules, ruleProviders)
|
dnsCfg, err := parseDNS(rawCfg, hosts, ruleProviders)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1297,7 +1297,7 @@ func parsePureDNSServer(server string) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], rules []C.Rule, ruleProviders map[string]providerTypes.RuleProvider, respectRules bool, preferH3 bool) ([]dns.Policy, error) {
|
func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], ruleProviders map[string]providerTypes.RuleProvider, respectRules bool, preferH3 bool) ([]dns.Policy, error) {
|
||||||
var policy []dns.Policy
|
var policy []dns.Policy
|
||||||
re := regexp.MustCompile(`[a-zA-Z0-9\-]+\.[a-zA-Z]{2,}(\.[a-zA-Z]{2,})?`)
|
re := regexp.MustCompile(`[a-zA-Z0-9\-]+\.[a-zA-Z]{2,}(\.[a-zA-Z]{2,})?`)
|
||||||
|
|
||||||
@ -1350,18 +1350,18 @@ func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], rules [
|
|||||||
|
|
||||||
if strings.HasPrefix(domain, "rule-set:") {
|
if strings.HasPrefix(domain, "rule-set:") {
|
||||||
domainSetName := domain[9:]
|
domainSetName := domain[9:]
|
||||||
rule, err := parseDomainRuleSet(domainSetName, "dns.nameserver-policy", ruleProviders)
|
matcher, err := parseDomainRuleSet(domainSetName, "dns.nameserver-policy", ruleProviders)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
policy[idx] = dns.Policy{Rule: rule, NameServers: nameservers}
|
policy[idx] = dns.Policy{Matcher: matcher, NameServers: nameservers}
|
||||||
} else if strings.HasPrefix(domain, "geosite:") {
|
} else if strings.HasPrefix(domain, "geosite:") {
|
||||||
country := domain[8:]
|
country := domain[8:]
|
||||||
rule, err := RC.NewGEOSITE(country, "dns.nameserver-policy")
|
matcher, err := RC.NewGEOSITE(country, "dns.nameserver-policy")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
policy[idx] = dns.Policy{Rule: rule, NameServers: nameservers}
|
policy[idx] = dns.Policy{Matcher: matcher, NameServers: nameservers}
|
||||||
} else {
|
} else {
|
||||||
if _, valid := trie.ValidAndSplitDomain(domain); !valid {
|
if _, valid := trie.ValidAndSplitDomain(domain); !valid {
|
||||||
return nil, fmt.Errorf("DNS ResoverRule invalid domain: %s", domain)
|
return nil, fmt.Errorf("DNS ResoverRule invalid domain: %s", domain)
|
||||||
@ -1372,7 +1372,7 @@ func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], rules [
|
|||||||
return policy, nil
|
return policy, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rules []C.Rule, ruleProviders map[string]providerTypes.RuleProvider) (*DNS, error) {
|
func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], ruleProviders map[string]providerTypes.RuleProvider) (*DNS, error) {
|
||||||
cfg := rawCfg.DNS
|
cfg := rawCfg.DNS
|
||||||
if cfg.Enable && len(cfg.NameServer) == 0 {
|
if cfg.Enable && len(cfg.NameServer) == 0 {
|
||||||
return nil, fmt.Errorf("if DNS configuration is turned on, NameServer cannot be empty")
|
return nil, fmt.Errorf("if DNS configuration is turned on, NameServer cannot be empty")
|
||||||
@ -1400,7 +1400,7 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if dnsCfg.NameServerPolicy, err = parseNameServerPolicy(cfg.NameServerPolicy, rules, ruleProviders, cfg.RespectRules, cfg.PreferH3); err != nil {
|
if dnsCfg.NameServerPolicy, err = parseNameServerPolicy(cfg.NameServerPolicy, ruleProviders, cfg.RespectRules, cfg.PreferH3); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1467,14 +1467,13 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
|
|||||||
dnsCfg.FakeIPRange = pool
|
dnsCfg.FakeIPRange = pool
|
||||||
}
|
}
|
||||||
|
|
||||||
var rule C.Rule
|
|
||||||
if len(cfg.Fallback) != 0 {
|
if len(cfg.Fallback) != 0 {
|
||||||
if cfg.FallbackFilter.GeoIP {
|
if cfg.FallbackFilter.GeoIP {
|
||||||
rule, err = RC.NewGEOIP(cfg.FallbackFilter.GeoIPCode, "dns.fallback-filter.geoip", false, true)
|
matcher, err := RC.NewGEOIP(cfg.FallbackFilter.GeoIPCode, "dns.fallback-filter.geoip", false, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("load GeoIP dns fallback filter error, %w", err)
|
return nil, fmt.Errorf("load GeoIP dns fallback filter error, %w", err)
|
||||||
}
|
}
|
||||||
dnsCfg.FallbackIPFilter = append(dnsCfg.FallbackIPFilter, rule)
|
dnsCfg.FallbackIPFilter = append(dnsCfg.FallbackIPFilter, matcher)
|
||||||
}
|
}
|
||||||
if len(cfg.FallbackFilter.IPCIDR) > 0 {
|
if len(cfg.FallbackFilter.IPCIDR) > 0 {
|
||||||
cidrSet := cidr.NewIpCidrSet()
|
cidrSet := cidr.NewIpCidrSet()
|
||||||
@ -1488,8 +1487,8 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rule = RP.NewIpCidrSet(cidrSet, "dns.fallback-filter.ipcidr")
|
matcher := cidrSet // dns.fallback-filter.ipcidr
|
||||||
dnsCfg.FallbackIPFilter = append(dnsCfg.FallbackIPFilter, rule)
|
dnsCfg.FallbackIPFilter = append(dnsCfg.FallbackIPFilter, matcher)
|
||||||
}
|
}
|
||||||
if len(cfg.FallbackFilter.Domain) > 0 {
|
if len(cfg.FallbackFilter.Domain) > 0 {
|
||||||
domainTrie := trie.New[struct{}]()
|
domainTrie := trie.New[struct{}]()
|
||||||
@ -1499,17 +1498,17 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
|
|||||||
return nil, fmt.Errorf("DNS FallbackDomain[%d] format error: %w", idx, err)
|
return nil, fmt.Errorf("DNS FallbackDomain[%d] format error: %w", idx, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rule = RP.NewDomainSet(domainTrie.NewDomainSet(), "dns.fallback-filter.domain")
|
matcher := domainTrie.NewDomainSet() // dns.fallback-filter.domain
|
||||||
dnsCfg.FallbackDomainFilter = append(dnsCfg.FallbackDomainFilter, rule)
|
dnsCfg.FallbackDomainFilter = append(dnsCfg.FallbackDomainFilter, matcher)
|
||||||
}
|
}
|
||||||
if len(cfg.FallbackFilter.GeoSite) > 0 {
|
if len(cfg.FallbackFilter.GeoSite) > 0 {
|
||||||
log.Warnln("replace fallback-filter.geosite with nameserver-policy, it will be removed in the future")
|
log.Warnln("replace fallback-filter.geosite with nameserver-policy, it will be removed in the future")
|
||||||
for idx, geoSite := range cfg.FallbackFilter.GeoSite {
|
for idx, geoSite := range cfg.FallbackFilter.GeoSite {
|
||||||
rule, err = RC.NewGEOSITE(geoSite, "dns.fallback-filter.geosite")
|
matcher, err := RC.NewGEOSITE(geoSite, "dns.fallback-filter.geosite")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("DNS FallbackGeosite[%d] format error: %w", idx, err)
|
return nil, fmt.Errorf("DNS FallbackGeosite[%d] format error: %w", idx, err)
|
||||||
}
|
}
|
||||||
dnsCfg.FallbackDomainFilter = append(dnsCfg.FallbackDomainFilter, rule)
|
dnsCfg.FallbackDomainFilter = append(dnsCfg.FallbackDomainFilter, matcher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1701,8 +1700,8 @@ func parseSniffer(snifferRaw RawSniffer, ruleProviders map[string]providerTypes.
|
|||||||
return snifferConfig, nil
|
return snifferConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseIPCIDR(addresses []string, cidrSet *cidr.IpCidrSet, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (ipRules []C.Rule, err error) {
|
func parseIPCIDR(addresses []string, cidrSet *cidr.IpCidrSet, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (matchers []C.IpMatcher, err error) {
|
||||||
var rule C.Rule
|
var matcher C.IpMatcher
|
||||||
for _, ipcidr := range addresses {
|
for _, ipcidr := range addresses {
|
||||||
ipcidrLower := strings.ToLower(ipcidr)
|
ipcidrLower := strings.ToLower(ipcidr)
|
||||||
if strings.Contains(ipcidrLower, "geoip:") {
|
if strings.Contains(ipcidrLower, "geoip:") {
|
||||||
@ -1710,22 +1709,22 @@ func parseIPCIDR(addresses []string, cidrSet *cidr.IpCidrSet, adapterName string
|
|||||||
subkeys = subkeys[1:]
|
subkeys = subkeys[1:]
|
||||||
subkeys = strings.Split(subkeys[0], ",")
|
subkeys = strings.Split(subkeys[0], ",")
|
||||||
for _, country := range subkeys {
|
for _, country := range subkeys {
|
||||||
rule, err = RC.NewGEOIP(country, adapterName, false, false)
|
matcher, err = RC.NewGEOIP(country, adapterName, false, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ipRules = append(ipRules, rule)
|
matchers = append(matchers, matcher)
|
||||||
}
|
}
|
||||||
} else if strings.Contains(ipcidrLower, "rule-set:") {
|
} else if strings.Contains(ipcidrLower, "rule-set:") {
|
||||||
subkeys := strings.Split(ipcidr, ":")
|
subkeys := strings.Split(ipcidr, ":")
|
||||||
subkeys = subkeys[1:]
|
subkeys = subkeys[1:]
|
||||||
subkeys = strings.Split(subkeys[0], ",")
|
subkeys = strings.Split(subkeys[0], ",")
|
||||||
for _, domainSetName := range subkeys {
|
for _, domainSetName := range subkeys {
|
||||||
rule, err = parseIPRuleSet(domainSetName, adapterName, ruleProviders)
|
matcher, err = parseIPRuleSet(domainSetName, adapterName, ruleProviders)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ipRules = append(ipRules, rule)
|
matchers = append(matchers, matcher)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if cidrSet == nil {
|
if cidrSet == nil {
|
||||||
@ -1742,14 +1741,14 @@ func parseIPCIDR(addresses []string, cidrSet *cidr.IpCidrSet, adapterName string
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rule = RP.NewIpCidrSet(cidrSet, adapterName)
|
matcher = cidrSet
|
||||||
ipRules = append(ipRules, rule)
|
matchers = append(matchers, matcher)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (domainRules []C.Rule, err error) {
|
func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (matchers []C.DomainMatcher, err error) {
|
||||||
var rule C.Rule
|
var matcher C.DomainMatcher
|
||||||
for _, domain := range domains {
|
for _, domain := range domains {
|
||||||
domainLower := strings.ToLower(domain)
|
domainLower := strings.ToLower(domain)
|
||||||
if strings.Contains(domainLower, "geosite:") {
|
if strings.Contains(domainLower, "geosite:") {
|
||||||
@ -1757,22 +1756,22 @@ func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], adapte
|
|||||||
subkeys = subkeys[1:]
|
subkeys = subkeys[1:]
|
||||||
subkeys = strings.Split(subkeys[0], ",")
|
subkeys = strings.Split(subkeys[0], ",")
|
||||||
for _, country := range subkeys {
|
for _, country := range subkeys {
|
||||||
rule, err = RC.NewGEOSITE(country, adapterName)
|
matcher, err = RC.NewGEOSITE(country, adapterName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
domainRules = append(domainRules, rule)
|
matchers = append(matchers, matcher)
|
||||||
}
|
}
|
||||||
} else if strings.Contains(domainLower, "rule-set:") {
|
} else if strings.Contains(domainLower, "rule-set:") {
|
||||||
subkeys := strings.Split(domain, ":")
|
subkeys := strings.Split(domain, ":")
|
||||||
subkeys = subkeys[1:]
|
subkeys = subkeys[1:]
|
||||||
subkeys = strings.Split(subkeys[0], ",")
|
subkeys = strings.Split(subkeys[0], ",")
|
||||||
for _, domainSetName := range subkeys {
|
for _, domainSetName := range subkeys {
|
||||||
rule, err = parseDomainRuleSet(domainSetName, adapterName, ruleProviders)
|
matcher, err = parseDomainRuleSet(domainSetName, adapterName, ruleProviders)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
domainRules = append(domainRules, rule)
|
matchers = append(matchers, matcher)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if domainTrie == nil {
|
if domainTrie == nil {
|
||||||
@ -1785,13 +1784,13 @@ func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], adapte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !domainTrie.IsEmpty() {
|
if !domainTrie.IsEmpty() {
|
||||||
rule = RP.NewDomainSet(domainTrie.NewDomainSet(), adapterName)
|
matcher = domainTrie.NewDomainSet()
|
||||||
domainRules = append(domainRules, rule)
|
matchers = append(matchers, matcher)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseIPRuleSet(domainSetName string, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (C.Rule, error) {
|
func parseIPRuleSet(domainSetName string, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (C.IpMatcher, error) {
|
||||||
if rp, ok := ruleProviders[domainSetName]; !ok {
|
if rp, ok := ruleProviders[domainSetName]; !ok {
|
||||||
return nil, fmt.Errorf("not found rule-set: %s", domainSetName)
|
return nil, fmt.Errorf("not found rule-set: %s", domainSetName)
|
||||||
} else {
|
} else {
|
||||||
@ -1806,7 +1805,7 @@ func parseIPRuleSet(domainSetName string, adapterName string, ruleProviders map[
|
|||||||
return RP.NewRuleSet(domainSetName, adapterName, true)
|
return RP.NewRuleSet(domainSetName, adapterName, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseDomainRuleSet(domainSetName string, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (C.Rule, error) {
|
func parseDomainRuleSet(domainSetName string, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (C.DomainMatcher, error) {
|
||||||
if rp, ok := ruleProviders[domainSetName]; !ok {
|
if rp, ok := ruleProviders[domainSetName]; !ok {
|
||||||
return nil, fmt.Errorf("not found rule-set: %s", domainSetName)
|
return nil, fmt.Errorf("not found rule-set: %s", domainSetName)
|
||||||
} else {
|
} else {
|
||||||
|
11
constant/matcher.go
Normal file
11
constant/matcher.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package constant
|
||||||
|
|
||||||
|
import "net/netip"
|
||||||
|
|
||||||
|
type DomainMatcher interface {
|
||||||
|
MatchDomain(domain string) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type IpMatcher interface {
|
||||||
|
MatchIp(ip netip.Addr) bool
|
||||||
|
}
|
@ -133,7 +133,9 @@ type Metadata struct {
|
|||||||
Type Type `json:"type"`
|
Type Type `json:"type"`
|
||||||
SrcIP netip.Addr `json:"sourceIP"`
|
SrcIP netip.Addr `json:"sourceIP"`
|
||||||
DstIP netip.Addr `json:"destinationIP"`
|
DstIP netip.Addr `json:"destinationIP"`
|
||||||
|
SrcGeoIP []string `json:"sourceGeoIP"` // can be nil if never queried, empty slice if got no result
|
||||||
DstGeoIP []string `json:"destinationGeoIP"` // can be nil if never queried, empty slice if got no result
|
DstGeoIP []string `json:"destinationGeoIP"` // can be nil if never queried, empty slice if got no result
|
||||||
|
SrcIPASN string `json:"sourceIPASN"`
|
||||||
DstIPASN string `json:"destinationIPASN"`
|
DstIPASN string `json:"destinationIPASN"`
|
||||||
SrcPort uint16 `json:"sourcePort,string"` // `,string` is used to compatible with old version json output
|
SrcPort uint16 `json:"sourcePort,string"` // `,string` is used to compatible with old version json output
|
||||||
DstPort uint16 `json:"destinationPort,string"` // `,string` is used to compatible with old version json output
|
DstPort uint16 `json:"destinationPort,string"` // `,string` is used to compatible with old version json output
|
||||||
|
@ -27,8 +27,6 @@ const (
|
|||||||
ProcessNameRegex
|
ProcessNameRegex
|
||||||
ProcessPathRegex
|
ProcessPathRegex
|
||||||
RuleSet
|
RuleSet
|
||||||
DomainSet
|
|
||||||
IpCidrSet
|
|
||||||
Network
|
Network
|
||||||
Uid
|
Uid
|
||||||
SubRules
|
SubRules
|
||||||
@ -92,10 +90,6 @@ func (rt RuleType) String() string {
|
|||||||
return "Match"
|
return "Match"
|
||||||
case RuleSet:
|
case RuleSet:
|
||||||
return "RuleSet"
|
return "RuleSet"
|
||||||
case DomainSet:
|
|
||||||
return "DomainSet"
|
|
||||||
case IpCidrSet:
|
|
||||||
return "IpCidrSet"
|
|
||||||
case Network:
|
case Network:
|
||||||
return "Network"
|
return "Network"
|
||||||
case DSCP:
|
case DSCP:
|
||||||
|
@ -21,13 +21,13 @@ func (p domainTriePolicy) Match(domain string) []dnsClient {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type domainRulePolicy struct {
|
type domainMatcherPolicy struct {
|
||||||
rule C.Rule
|
matcher C.DomainMatcher
|
||||||
dnsClients []dnsClient
|
dnsClients []dnsClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p domainRulePolicy) Match(domain string) []dnsClient {
|
func (p domainMatcherPolicy) Match(domain string) []dnsClient {
|
||||||
if ok, _ := p.rule.Match(&C.Metadata{Host: domain}); ok {
|
if p.matcher.MatchDomain(domain) {
|
||||||
return p.dnsClients
|
return p.dnsClients
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -42,8 +42,8 @@ type Resolver struct {
|
|||||||
hosts *trie.DomainTrie[resolver.HostValue]
|
hosts *trie.DomainTrie[resolver.HostValue]
|
||||||
main []dnsClient
|
main []dnsClient
|
||||||
fallback []dnsClient
|
fallback []dnsClient
|
||||||
fallbackDomainFilters []C.Rule
|
fallbackDomainFilters []C.DomainMatcher
|
||||||
fallbackIPFilters []C.Rule
|
fallbackIPFilters []C.IpMatcher
|
||||||
group singleflight.Group[*D.Msg]
|
group singleflight.Group[*D.Msg]
|
||||||
cache dnsCache
|
cache dnsCache
|
||||||
policy []dnsPolicy
|
policy []dnsPolicy
|
||||||
@ -119,7 +119,7 @@ func (r *Resolver) LookupIPv6(ctx context.Context, host string) ([]netip.Addr, e
|
|||||||
|
|
||||||
func (r *Resolver) shouldIPFallback(ip netip.Addr) bool {
|
func (r *Resolver) shouldIPFallback(ip netip.Addr) bool {
|
||||||
for _, filter := range r.fallbackIPFilters {
|
for _, filter := range r.fallbackIPFilters {
|
||||||
if ok, _ := filter.Match(&C.Metadata{DstIP: ip}); ok {
|
if filter.MatchIp(ip) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -275,7 +275,7 @@ func (r *Resolver) shouldOnlyQueryFallback(m *D.Msg) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, df := range r.fallbackDomainFilters {
|
for _, df := range r.fallbackDomainFilters {
|
||||||
if ok, _ := df.Match(&C.Metadata{Host: domain}); ok {
|
if df.MatchDomain(domain) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -398,7 +398,7 @@ func (ns NameServer) Equal(ns2 NameServer) bool {
|
|||||||
|
|
||||||
type Policy struct {
|
type Policy struct {
|
||||||
Domain string
|
Domain string
|
||||||
Rule C.Rule
|
Matcher C.DomainMatcher
|
||||||
NameServers []NameServer
|
NameServers []NameServer
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,8 +409,8 @@ type Config struct {
|
|||||||
IPv6 bool
|
IPv6 bool
|
||||||
IPv6Timeout uint
|
IPv6Timeout uint
|
||||||
EnhancedMode C.DNSMode
|
EnhancedMode C.DNSMode
|
||||||
FallbackIPFilter []C.Rule
|
FallbackIPFilter []C.IpMatcher
|
||||||
FallbackDomainFilter []C.Rule
|
FallbackDomainFilter []C.DomainMatcher
|
||||||
Pool *fakeip.Pool
|
Pool *fakeip.Pool
|
||||||
Hosts *trie.DomainTrie[resolver.HostValue]
|
Hosts *trie.DomainTrie[resolver.HostValue]
|
||||||
Policy []Policy
|
Policy []Policy
|
||||||
@ -495,8 +495,8 @@ func NewResolver(config Config) *Resolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, policy := range config.Policy {
|
for _, policy := range config.Policy {
|
||||||
if policy.Rule != nil {
|
if policy.Matcher != nil {
|
||||||
insertPolicy(domainRulePolicy{rule: policy.Rule, dnsClients: cacheTransform(policy.NameServers)})
|
insertPolicy(domainMatcherPolicy{matcher: policy.Matcher, dnsClients: cacheTransform(policy.NameServers)})
|
||||||
} else {
|
} else {
|
||||||
if triePolicy == nil {
|
if triePolicy == nil {
|
||||||
triePolicy = trie.New[[]dnsClient]()
|
triePolicy = trie.New[[]dnsClient]()
|
||||||
|
@ -3,6 +3,7 @@ package common
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/netip"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/metacubex/mihomo/component/geodata"
|
"github.com/metacubex/mihomo/component/geodata"
|
||||||
@ -11,6 +12,8 @@ import (
|
|||||||
"github.com/metacubex/mihomo/component/resolver"
|
"github.com/metacubex/mihomo/component/resolver"
|
||||||
C "github.com/metacubex/mihomo/constant"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
"github.com/metacubex/mihomo/log"
|
"github.com/metacubex/mihomo/log"
|
||||||
|
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GEOIP struct {
|
type GEOIP struct {
|
||||||
@ -41,52 +44,84 @@ func (g *GEOIP) Match(metadata *C.Metadata) (bool, string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if g.country == "lan" {
|
if g.country == "lan" {
|
||||||
return ip.IsPrivate() ||
|
return g.isLan(ip), g.adapter
|
||||||
ip.IsUnspecified() ||
|
|
||||||
ip.IsLoopback() ||
|
|
||||||
ip.IsMulticast() ||
|
|
||||||
ip.IsLinkLocalUnicast() ||
|
|
||||||
resolver.IsFakeBroadcastIP(ip), g.adapter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, code := range metadata.DstGeoIP {
|
if C.GeodataMode {
|
||||||
if g.country == code {
|
|
||||||
return true, g.adapter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !C.GeodataMode {
|
|
||||||
if g.isSourceIP {
|
if g.isSourceIP {
|
||||||
codes := mmdb.IPInstance().LookupCode(ip.AsSlice())
|
if slices.Contains(metadata.SrcGeoIP, g.country) {
|
||||||
for _, code := range codes {
|
return true, g.adapter
|
||||||
if g.country == code {
|
|
||||||
return true, g.adapter
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false, g.adapter
|
} else {
|
||||||
}
|
if slices.Contains(metadata.DstGeoIP, g.country) {
|
||||||
|
|
||||||
if metadata.DstGeoIP != nil {
|
|
||||||
return false, g.adapter
|
|
||||||
}
|
|
||||||
metadata.DstGeoIP = mmdb.IPInstance().LookupCode(ip.AsSlice())
|
|
||||||
for _, code := range metadata.DstGeoIP {
|
|
||||||
if g.country == code {
|
|
||||||
return true, g.adapter
|
return true, g.adapter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false, g.adapter
|
matcher, err := g.getIPMatcher()
|
||||||
|
if err != nil {
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
match := matcher.Match(ip)
|
||||||
|
if match {
|
||||||
|
if g.isSourceIP {
|
||||||
|
metadata.SrcGeoIP = append(metadata.SrcGeoIP, g.country)
|
||||||
|
} else {
|
||||||
|
metadata.DstGeoIP = append(metadata.DstGeoIP, g.country)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return match, g.adapter
|
||||||
}
|
}
|
||||||
|
|
||||||
matcher, err := g.GetIPMatcher()
|
if g.isSourceIP {
|
||||||
if err != nil {
|
if metadata.SrcGeoIP != nil {
|
||||||
return false, ""
|
return slices.Contains(metadata.SrcGeoIP, g.country), g.adapter
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if metadata.DstGeoIP != nil {
|
||||||
|
return slices.Contains(metadata.DstGeoIP, g.country), g.adapter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
match := matcher.Match(ip)
|
codes := mmdb.IPInstance().LookupCode(ip.AsSlice())
|
||||||
if match && !g.isSourceIP {
|
if g.isSourceIP {
|
||||||
metadata.DstGeoIP = append(metadata.DstGeoIP, g.country)
|
metadata.SrcGeoIP = codes
|
||||||
|
} else {
|
||||||
|
metadata.DstGeoIP = codes
|
||||||
}
|
}
|
||||||
return match, g.adapter
|
if slices.Contains(codes, g.country) {
|
||||||
|
return true, g.adapter
|
||||||
|
}
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatchIp implements C.IpMatcher
|
||||||
|
func (g *GEOIP) MatchIp(ip netip.Addr) bool {
|
||||||
|
if !ip.IsValid() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if g.country == "lan" {
|
||||||
|
return g.isLan(ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
if C.GeodataMode {
|
||||||
|
matcher, err := g.getIPMatcher()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return matcher.Match(ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
codes := mmdb.IPInstance().LookupCode(ip.AsSlice())
|
||||||
|
return slices.Contains(codes, g.country)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GEOIP) isLan(ip netip.Addr) bool {
|
||||||
|
return ip.IsPrivate() ||
|
||||||
|
ip.IsUnspecified() ||
|
||||||
|
ip.IsLoopback() ||
|
||||||
|
ip.IsMulticast() ||
|
||||||
|
ip.IsLinkLocalUnicast() ||
|
||||||
|
resolver.IsFakeBroadcastIP(ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GEOIP) Adapter() string {
|
func (g *GEOIP) Adapter() string {
|
||||||
@ -106,14 +141,19 @@ func (g *GEOIP) GetCountry() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GEOIP) GetIPMatcher() (router.IPMatcher, error) {
|
func (g *GEOIP) GetIPMatcher() (router.IPMatcher, error) {
|
||||||
if g.geodata {
|
if C.GeodataMode {
|
||||||
geoIPMatcher, err := geodata.LoadGeoIPMatcher(g.country)
|
return g.getIPMatcher()
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("[GeoIP] %w", err)
|
|
||||||
}
|
|
||||||
return geoIPMatcher, nil
|
|
||||||
}
|
}
|
||||||
return nil, errors.New("geoip country not set")
|
return nil, errors.New("not geodata mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GEOIP) getIPMatcher() (router.IPMatcher, error) {
|
||||||
|
geoIPMatcher, err := geodata.LoadGeoIPMatcher(g.country)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("[GeoIP] %w", err)
|
||||||
|
}
|
||||||
|
return geoIPMatcher, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GEOIP) GetRecodeSize() int {
|
func (g *GEOIP) GetRecodeSize() int {
|
||||||
@ -141,12 +181,13 @@ func NewGEOIP(country string, adapter string, isSrc, noResolveIP bool) (*GEOIP,
|
|||||||
return geoip, nil
|
return geoip, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
geoip.geodata = true
|
if C.GeodataMode {
|
||||||
geoIPMatcher, err := geoip.GetIPMatcher() // test load
|
geoIPMatcher, err := geoip.getIPMatcher() // test load
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
}
|
||||||
|
log.Infoln("Finished initial GeoIP rule %s => %s, records: %d", country, adapter, geoIPMatcher.Count())
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infoln("Finished initial GeoIP rule %s => %s, records: %d", country, adapter, geoIPMatcher.Count())
|
|
||||||
return geoip, nil
|
return geoip, nil
|
||||||
}
|
}
|
||||||
|
@ -23,15 +23,19 @@ func (gs *GEOSITE) RuleType() C.RuleType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gs *GEOSITE) Match(metadata *C.Metadata) (bool, string) {
|
func (gs *GEOSITE) Match(metadata *C.Metadata) (bool, string) {
|
||||||
domain := metadata.RuleHost()
|
return gs.MatchDomain(metadata.RuleHost()), gs.adapter
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatchDomain implements C.DomainMatcher
|
||||||
|
func (gs *GEOSITE) MatchDomain(domain string) bool {
|
||||||
if len(domain) == 0 {
|
if len(domain) == 0 {
|
||||||
return false, ""
|
return false
|
||||||
}
|
}
|
||||||
matcher, err := gs.GetDomainMatcher()
|
matcher, err := gs.GetDomainMatcher()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, ""
|
return false
|
||||||
}
|
}
|
||||||
return matcher.ApplyDomain(domain), gs.adapter
|
return matcher.ApplyDomain(domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gs *GEOSITE) Adapter() string {
|
func (gs *GEOSITE) Adapter() string {
|
||||||
|
@ -28,8 +28,11 @@ func (a *ASN) Match(metadata *C.Metadata) (bool, string) {
|
|||||||
|
|
||||||
result := mmdb.ASNInstance().LookupASN(ip.AsSlice())
|
result := mmdb.ASNInstance().LookupASN(ip.AsSlice())
|
||||||
asnNumber := strconv.FormatUint(uint64(result.AutonomousSystemNumber), 10)
|
asnNumber := strconv.FormatUint(uint64(result.AutonomousSystemNumber), 10)
|
||||||
if !a.isSourceIP {
|
ipASN := asnNumber + " " + result.AutonomousSystemOrganization
|
||||||
metadata.DstIPASN = asnNumber + " " + result.AutonomousSystemOrganization
|
if a.isSourceIP {
|
||||||
|
metadata.SrcIPASN = ipASN
|
||||||
|
} else {
|
||||||
|
metadata.DstIPASN = ipASN
|
||||||
}
|
}
|
||||||
|
|
||||||
match := a.asn == asnNumber
|
match := a.asn == asnNumber
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
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) {
|
|
||||||
return d.domainStrategy.Match(metadata), 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)
|
|
@ -1,40 +0,0 @@
|
|||||||
package provider
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/metacubex/mihomo/component/cidr"
|
|
||||||
C "github.com/metacubex/mihomo/constant"
|
|
||||||
)
|
|
||||||
|
|
||||||
type IpCidrSet struct {
|
|
||||||
*ipcidrStrategy
|
|
||||||
adapter string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *IpCidrSet) ProviderNames() []string {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *IpCidrSet) RuleType() C.RuleType {
|
|
||||||
return C.IpCidrSet
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *IpCidrSet) Match(metadata *C.Metadata) (bool, string) {
|
|
||||||
return d.ipcidrStrategy.Match(metadata), d.adapter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *IpCidrSet) Adapter() string {
|
|
||||||
return d.adapter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *IpCidrSet) Payload() string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewIpCidrSet(cidrSet *cidr.IpCidrSet, adapter string) *IpCidrSet {
|
|
||||||
return &IpCidrSet{
|
|
||||||
ipcidrStrategy: &ipcidrStrategy{cidrSet: cidrSet},
|
|
||||||
adapter: adapter,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ C.Rule = (*IpCidrSet)(nil)
|
|
@ -1,6 +1,8 @@
|
|||||||
package provider
|
package provider
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
C "github.com/metacubex/mihomo/constant"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
P "github.com/metacubex/mihomo/constant/provider"
|
P "github.com/metacubex/mihomo/constant/provider"
|
||||||
"github.com/metacubex/mihomo/rules/common"
|
"github.com/metacubex/mihomo/rules/common"
|
||||||
@ -35,6 +37,18 @@ func (rs *RuleSet) Match(metadata *C.Metadata) (bool, string) {
|
|||||||
return false, ""
|
return false, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MatchDomain implements C.DomainMatcher
|
||||||
|
func (rs *RuleSet) MatchDomain(domain string) bool {
|
||||||
|
ok, _ := rs.Match(&C.Metadata{Host: domain})
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatchIp implements C.IpMatcher
|
||||||
|
func (rs *RuleSet) MatchIp(ip netip.Addr) bool {
|
||||||
|
ok, _ := rs.Match(&C.Metadata{DstIP: ip})
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
func (rs *RuleSet) Adapter() string {
|
func (rs *RuleSet) Adapter() string {
|
||||||
return rs.adapter
|
return rs.adapter
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user