Skip to content

Commit

Permalink
chore: add sourceGeoIP and sourceIPASN to metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
wwqgtxx committed Aug 28, 2024
1 parent 8483178 commit 4fecf68
Show file tree
Hide file tree
Showing 17 changed files with 210 additions and 210 deletions.
8 changes: 8 additions & 0 deletions component/cidr/ipcidr_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ func (set *IpCidrSet) IsContain(ip netip.Addr) bool {
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 {
var b netipx.IPSetBuilder
b.AddSet(set.ToIPSet())
Expand Down
8 changes: 4 additions & 4 deletions component/fakeip/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type Pool struct {
offset netip.Addr
cycle bool
mux sync.Mutex
host []C.Rule
host []C.DomainMatcher
ipnet netip.Prefix
store store
}
Expand Down Expand Up @@ -66,8 +66,8 @@ func (p *Pool) LookBack(ip netip.Addr) (string, bool) {

// ShouldSkipped return if domain should be skipped
func (p *Pool) ShouldSkipped(domain string) bool {
for _, rule := range p.host {
if match, _ := rule.Match(&C.Metadata{Host: domain}); match {
for _, matcher := range p.host {
if matcher.MatchDomain(domain) {
return true
}
}
Expand Down Expand Up @@ -156,7 +156,7 @@ func (p *Pool) restoreState() {

type Options struct {
IPNet netip.Prefix
Host []C.Rule
Host []C.DomainMatcher

// Size sets the maximum number of entries in memory
// and does not work if Persistence is true
Expand Down
3 changes: 1 addition & 2 deletions component/fakeip/pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/metacubex/mihomo/component/profile/cachefile"
"github.com/metacubex/mihomo/component/trie"
C "github.com/metacubex/mihomo/constant"
RP "github.com/metacubex/mihomo/rules/provider"

"github.com/metacubex/bbolt"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -157,7 +156,7 @@ func TestPool_Skip(t *testing.T) {
pools, tempfile, err := createPools(Options{
IPNet: ipnet,
Size: 10,
Host: []C.Rule{RP.NewDomainSet(tree.NewDomainSet(), "")},
Host: []C.DomainMatcher{tree.NewDomainSet()},
})
assert.Nil(t, err)
defer os.Remove(tempfile)
Expand Down
32 changes: 16 additions & 16 deletions component/sniffer/dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,23 @@ var (
type Dispatcher struct {
enable bool
sniffers map[sniffer.Sniffer]SnifferConfig
forceDomain []C.Rule
skipSrcAddress []C.Rule
skipDstAddress []C.Rule
skipDomain []C.Rule
forceDomain []C.DomainMatcher
skipSrcAddress []C.IpMatcher
skipDstAddress []C.IpMatcher
skipDomain []C.DomainMatcher
skipList *lru.LruCache[netip.AddrPort, uint8]
forceDnsMapping bool
parsePureIp bool
}

func (sd *Dispatcher) shouldOverride(metadata *C.Metadata) bool {
for _, rule := range sd.skipDstAddress {
if ok, _ := rule.Match(&C.Metadata{DstIP: metadata.DstIP}); ok {
for _, matcher := range sd.skipDstAddress {
if matcher.MatchIp(metadata.DstIP) {
return false
}
}
for _, rule := range sd.skipSrcAddress {
if ok, _ := rule.Match(&C.Metadata{DstIP: metadata.SrcIP}); ok {
for _, matcher := range sd.skipSrcAddress {
if matcher.MatchIp(metadata.SrcIP) {
return false
}
}
Expand All @@ -48,8 +48,8 @@ func (sd *Dispatcher) shouldOverride(metadata *C.Metadata) bool {
if metadata.DNSMode == C.DNSMapping && sd.forceDnsMapping {
return true
}
for _, rule := range sd.forceDomain {
if ok, _ := rule.Match(&C.Metadata{Host: metadata.Host}); ok {
for _, matcher := range sd.forceDomain {
if matcher.MatchDomain(metadata.Host) {
return true
}
}
Expand Down Expand Up @@ -112,8 +112,8 @@ func (sd *Dispatcher) TCPSniff(conn *N.BufferedConn, metadata *C.Metadata) bool
return false
}

for _, rule := range sd.skipDomain {
if ok, _ := rule.Match(&C.Metadata{Host: host}); ok {
for _, matcher := range sd.skipDomain {
if matcher.MatchDomain(host) {
log.Debugln("[Sniffer] Skip sni[%s]", host)
return false
}
Expand Down Expand Up @@ -200,10 +200,10 @@ func (sd *Dispatcher) cacheSniffFailed(metadata *C.Metadata) {
type Config struct {
Enable bool
Sniffers map[sniffer.Type]SnifferConfig
ForceDomain []C.Rule
SkipSrcAddress []C.Rule
SkipDstAddress []C.Rule
SkipDomain []C.Rule
ForceDomain []C.DomainMatcher
SkipSrcAddress []C.IpMatcher
SkipDstAddress []C.IpMatcher
SkipDomain []C.DomainMatcher
ForceDnsMapping bool
ParsePureIp bool
}
Expand Down
5 changes: 5 additions & 0 deletions component/trie/domain_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
for i>>6 >= len(*bm) {
*bm = append(*bm, 0)
Expand Down
73 changes: 36 additions & 37 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ type DNS struct {
UseSystemHosts bool
NameServer []dns.NameServer
Fallback []dns.NameServer
FallbackIPFilter []C.Rule
FallbackDomainFilter []C.Rule
FallbackIPFilter []C.IpMatcher
FallbackDomainFilter []C.DomainMatcher
Listen string
EnhancedMode C.DNSMode
DefaultNameserver []dns.NameServer
Expand Down Expand Up @@ -640,7 +640,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
}
config.Hosts = hosts

dnsCfg, err := parseDNS(rawCfg, hosts, rules, ruleProviders)
dnsCfg, err := parseDNS(rawCfg, hosts, ruleProviders)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -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
re := regexp.MustCompile(`[a-zA-Z0-9\-]+\.[a-zA-Z]{2,}(\.[a-zA-Z]{2,})?`)

Expand Down Expand Up @@ -1350,18 +1350,18 @@ func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], rules [

if strings.HasPrefix(domain, "rule-set:") {
domainSetName := domain[9:]
rule, err := parseDomainRuleSet(domainSetName, "dns.nameserver-policy", ruleProviders)
matcher, err := parseDomainRuleSet(domainSetName, "dns.nameserver-policy", ruleProviders)
if err != nil {
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:") {
country := domain[8:]
rule, err := RC.NewGEOSITE(country, "dns.nameserver-policy")
matcher, err := RC.NewGEOSITE(country, "dns.nameserver-policy")
if err != nil {
return nil, err
}
policy[idx] = dns.Policy{Rule: rule, NameServers: nameservers}
policy[idx] = dns.Policy{Matcher: matcher, NameServers: nameservers}
} else {
if _, valid := trie.ValidAndSplitDomain(domain); !valid {
return nil, fmt.Errorf("DNS ResoverRule invalid domain: %s", domain)
Expand All @@ -1372,7 +1372,7 @@ func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], rules [
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
if cfg.Enable && len(cfg.NameServer) == 0 {
return nil, fmt.Errorf("if DNS configuration is turned on, NameServer cannot be empty")
Expand Down Expand Up @@ -1400,7 +1400,7 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
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
}

Expand Down Expand Up @@ -1467,14 +1467,13 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
dnsCfg.FakeIPRange = pool
}

var rule C.Rule
if len(cfg.Fallback) != 0 {
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 {
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 {
cidrSet := cidr.NewIpCidrSet()
Expand All @@ -1488,8 +1487,8 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
if err != nil {
return nil, err
}
rule = RP.NewIpCidrSet(cidrSet, "dns.fallback-filter.ipcidr")
dnsCfg.FallbackIPFilter = append(dnsCfg.FallbackIPFilter, rule)
matcher := cidrSet // dns.fallback-filter.ipcidr
dnsCfg.FallbackIPFilter = append(dnsCfg.FallbackIPFilter, matcher)
}
if len(cfg.FallbackFilter.Domain) > 0 {
domainTrie := trie.New[struct{}]()
Expand All @@ -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)
}
}
rule = RP.NewDomainSet(domainTrie.NewDomainSet(), "dns.fallback-filter.domain")
dnsCfg.FallbackDomainFilter = append(dnsCfg.FallbackDomainFilter, rule)
matcher := domainTrie.NewDomainSet() // dns.fallback-filter.domain
dnsCfg.FallbackDomainFilter = append(dnsCfg.FallbackDomainFilter, matcher)
}
if len(cfg.FallbackFilter.GeoSite) > 0 {
log.Warnln("replace fallback-filter.geosite with nameserver-policy, it will be removed in the future")
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 {
return nil, fmt.Errorf("DNS FallbackGeosite[%d] format error: %w", idx, err)
}
dnsCfg.FallbackDomainFilter = append(dnsCfg.FallbackDomainFilter, rule)
dnsCfg.FallbackDomainFilter = append(dnsCfg.FallbackDomainFilter, matcher)
}
}
}
Expand Down Expand Up @@ -1701,31 +1700,31 @@ func parseSniffer(snifferRaw RawSniffer, ruleProviders map[string]providerTypes.
return snifferConfig, nil
}

func parseIPCIDR(addresses []string, cidrSet *cidr.IpCidrSet, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (ipRules []C.Rule, err error) {
var rule C.Rule
func parseIPCIDR(addresses []string, cidrSet *cidr.IpCidrSet, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (matchers []C.IpMatcher, err error) {
var matcher C.IpMatcher
for _, ipcidr := range addresses {
ipcidrLower := strings.ToLower(ipcidr)
if strings.Contains(ipcidrLower, "geoip:") {
subkeys := strings.Split(ipcidr, ":")
subkeys = subkeys[1:]
subkeys = strings.Split(subkeys[0], ",")
for _, country := range subkeys {
rule, err = RC.NewGEOIP(country, adapterName, false, false)
matcher, err = RC.NewGEOIP(country, adapterName, false, false)
if err != nil {
return nil, err
}
ipRules = append(ipRules, rule)
matchers = append(matchers, matcher)
}
} else if strings.Contains(ipcidrLower, "rule-set:") {
subkeys := strings.Split(ipcidr, ":")
subkeys = subkeys[1:]
subkeys = strings.Split(subkeys[0], ",")
for _, domainSetName := range subkeys {
rule, err = parseIPRuleSet(domainSetName, adapterName, ruleProviders)
matcher, err = parseIPRuleSet(domainSetName, adapterName, ruleProviders)
if err != nil {
return nil, err
}
ipRules = append(ipRules, rule)
matchers = append(matchers, matcher)
}
} else {
if cidrSet == nil {
Expand All @@ -1742,37 +1741,37 @@ func parseIPCIDR(addresses []string, cidrSet *cidr.IpCidrSet, adapterName string
if err != nil {
return nil, err
}
rule = RP.NewIpCidrSet(cidrSet, adapterName)
ipRules = append(ipRules, rule)
matcher = cidrSet
matchers = append(matchers, matcher)
}
return
}

func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (domainRules []C.Rule, err error) {
var rule C.Rule
func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (matchers []C.DomainMatcher, err error) {
var matcher C.DomainMatcher
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 {
rule, err = RC.NewGEOSITE(country, adapterName)
matcher, err = RC.NewGEOSITE(country, adapterName)
if err != nil {
return nil, err
}
domainRules = append(domainRules, rule)
matchers = append(matchers, matcher)
}
} else if strings.Contains(domainLower, "rule-set:") {
subkeys := strings.Split(domain, ":")
subkeys = subkeys[1:]
subkeys = strings.Split(subkeys[0], ",")
for _, domainSetName := range subkeys {
rule, err = parseDomainRuleSet(domainSetName, adapterName, ruleProviders)
matcher, err = parseDomainRuleSet(domainSetName, adapterName, ruleProviders)
if err != nil {
return nil, err
}
domainRules = append(domainRules, rule)
matchers = append(matchers, matcher)
}
} else {
if domainTrie == nil {
Expand All @@ -1785,13 +1784,13 @@ func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], adapte
}
}
if !domainTrie.IsEmpty() {
rule = RP.NewDomainSet(domainTrie.NewDomainSet(), adapterName)
domainRules = append(domainRules, rule)
matcher = domainTrie.NewDomainSet()
matchers = append(matchers, matcher)
}
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 {
return nil, fmt.Errorf("not found rule-set: %s", domainSetName)
} else {
Expand All @@ -1806,7 +1805,7 @@ func parseIPRuleSet(domainSetName string, adapterName string, ruleProviders map[
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 {
return nil, fmt.Errorf("not found rule-set: %s", domainSetName)
} else {
Expand Down
11 changes: 11 additions & 0 deletions constant/matcher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package constant

import "net/netip"

type DomainMatcher interface {
MatchDomain(domain string) bool
}

type IpMatcher interface {
MatchIp(ip netip.Addr) bool
}
2 changes: 2 additions & 0 deletions constant/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@ type Metadata struct {
Type Type `json:"type"`
SrcIP netip.Addr `json:"sourceIP"`
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
SrcIPASN string `json:"sourceIPASN"`
DstIPASN string `json:"destinationIPASN"`
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
Expand Down
Loading

0 comments on commit 4fecf68

Please sign in to comment.