Skip to content

Commit 4fecf68

Browse files
committed
chore: add sourceGeoIP and sourceIPASN to metadata
1 parent 8483178 commit 4fecf68

17 files changed

+210
-210
lines changed

component/cidr/ipcidr_set.go

+8
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ func (set *IpCidrSet) IsContain(ip netip.Addr) bool {
4646
return set.ToIPSet().Contains(ip.WithZone(""))
4747
}
4848

49+
// MatchIp implements C.IpMatcher
50+
func (set *IpCidrSet) MatchIp(ip netip.Addr) bool {
51+
if set.IsEmpty() {
52+
return false
53+
}
54+
return set.IsContain(ip)
55+
}
56+
4957
func (set *IpCidrSet) Merge() error {
5058
var b netipx.IPSetBuilder
5159
b.AddSet(set.ToIPSet())

component/fakeip/pool.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type Pool struct {
3535
offset netip.Addr
3636
cycle bool
3737
mux sync.Mutex
38-
host []C.Rule
38+
host []C.DomainMatcher
3939
ipnet netip.Prefix
4040
store store
4141
}
@@ -66,8 +66,8 @@ func (p *Pool) LookBack(ip netip.Addr) (string, bool) {
6666

6767
// ShouldSkipped return if domain should be skipped
6868
func (p *Pool) ShouldSkipped(domain string) bool {
69-
for _, rule := range p.host {
70-
if match, _ := rule.Match(&C.Metadata{Host: domain}); match {
69+
for _, matcher := range p.host {
70+
if matcher.MatchDomain(domain) {
7171
return true
7272
}
7373
}
@@ -156,7 +156,7 @@ func (p *Pool) restoreState() {
156156

157157
type Options struct {
158158
IPNet netip.Prefix
159-
Host []C.Rule
159+
Host []C.DomainMatcher
160160

161161
// Size sets the maximum number of entries in memory
162162
// and does not work if Persistence is true

component/fakeip/pool_test.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"github.com/metacubex/mihomo/component/profile/cachefile"
1111
"github.com/metacubex/mihomo/component/trie"
1212
C "github.com/metacubex/mihomo/constant"
13-
RP "github.com/metacubex/mihomo/rules/provider"
1413

1514
"github.com/metacubex/bbolt"
1615
"github.com/stretchr/testify/assert"
@@ -157,7 +156,7 @@ func TestPool_Skip(t *testing.T) {
157156
pools, tempfile, err := createPools(Options{
158157
IPNet: ipnet,
159158
Size: 10,
160-
Host: []C.Rule{RP.NewDomainSet(tree.NewDomainSet(), "")},
159+
Host: []C.DomainMatcher{tree.NewDomainSet()},
161160
})
162161
assert.Nil(t, err)
163162
defer os.Remove(tempfile)

component/sniffer/dispatcher.go

+16-16
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,23 @@ var (
2222
type Dispatcher struct {
2323
enable bool
2424
sniffers map[sniffer.Sniffer]SnifferConfig
25-
forceDomain []C.Rule
26-
skipSrcAddress []C.Rule
27-
skipDstAddress []C.Rule
28-
skipDomain []C.Rule
25+
forceDomain []C.DomainMatcher
26+
skipSrcAddress []C.IpMatcher
27+
skipDstAddress []C.IpMatcher
28+
skipDomain []C.DomainMatcher
2929
skipList *lru.LruCache[netip.AddrPort, uint8]
3030
forceDnsMapping bool
3131
parsePureIp bool
3232
}
3333

3434
func (sd *Dispatcher) shouldOverride(metadata *C.Metadata) bool {
35-
for _, rule := range sd.skipDstAddress {
36-
if ok, _ := rule.Match(&C.Metadata{DstIP: metadata.DstIP}); ok {
35+
for _, matcher := range sd.skipDstAddress {
36+
if matcher.MatchIp(metadata.DstIP) {
3737
return false
3838
}
3939
}
40-
for _, rule := range sd.skipSrcAddress {
41-
if ok, _ := rule.Match(&C.Metadata{DstIP: metadata.SrcIP}); ok {
40+
for _, matcher := range sd.skipSrcAddress {
41+
if matcher.MatchIp(metadata.SrcIP) {
4242
return false
4343
}
4444
}
@@ -48,8 +48,8 @@ func (sd *Dispatcher) shouldOverride(metadata *C.Metadata) bool {
4848
if metadata.DNSMode == C.DNSMapping && sd.forceDnsMapping {
4949
return true
5050
}
51-
for _, rule := range sd.forceDomain {
52-
if ok, _ := rule.Match(&C.Metadata{Host: metadata.Host}); ok {
51+
for _, matcher := range sd.forceDomain {
52+
if matcher.MatchDomain(metadata.Host) {
5353
return true
5454
}
5555
}
@@ -112,8 +112,8 @@ func (sd *Dispatcher) TCPSniff(conn *N.BufferedConn, metadata *C.Metadata) bool
112112
return false
113113
}
114114

115-
for _, rule := range sd.skipDomain {
116-
if ok, _ := rule.Match(&C.Metadata{Host: host}); ok {
115+
for _, matcher := range sd.skipDomain {
116+
if matcher.MatchDomain(host) {
117117
log.Debugln("[Sniffer] Skip sni[%s]", host)
118118
return false
119119
}
@@ -200,10 +200,10 @@ func (sd *Dispatcher) cacheSniffFailed(metadata *C.Metadata) {
200200
type Config struct {
201201
Enable bool
202202
Sniffers map[sniffer.Type]SnifferConfig
203-
ForceDomain []C.Rule
204-
SkipSrcAddress []C.Rule
205-
SkipDstAddress []C.Rule
206-
SkipDomain []C.Rule
203+
ForceDomain []C.DomainMatcher
204+
SkipSrcAddress []C.IpMatcher
205+
SkipDstAddress []C.IpMatcher
206+
SkipDomain []C.DomainMatcher
207207
ForceDnsMapping bool
208208
ParsePureIp bool
209209
}

component/trie/domain_set.go

+5
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ func (ss *DomainSet) Foreach(f func(key string) bool) {
172172
})
173173
}
174174

175+
// MatchDomain implements C.DomainMatcher
176+
func (ss *DomainSet) MatchDomain(domain string) bool {
177+
return ss.Has(domain)
178+
}
179+
175180
func setBit(bm *[]uint64, i int, v int) {
176181
for i>>6 >= len(*bm) {
177182
*bm = append(*bm, 0)

config/config.go

+36-37
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ type DNS struct {
143143
UseSystemHosts bool
144144
NameServer []dns.NameServer
145145
Fallback []dns.NameServer
146-
FallbackIPFilter []C.Rule
147-
FallbackDomainFilter []C.Rule
146+
FallbackIPFilter []C.IpMatcher
147+
FallbackDomainFilter []C.DomainMatcher
148148
Listen string
149149
EnhancedMode C.DNSMode
150150
DefaultNameserver []dns.NameServer
@@ -640,7 +640,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
640640
}
641641
config.Hosts = hosts
642642

643-
dnsCfg, err := parseDNS(rawCfg, hosts, rules, ruleProviders)
643+
dnsCfg, err := parseDNS(rawCfg, hosts, ruleProviders)
644644
if err != nil {
645645
return nil, err
646646
}
@@ -1297,7 +1297,7 @@ func parsePureDNSServer(server string) string {
12971297
}
12981298
}
12991299

1300-
func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], rules []C.Rule, ruleProviders map[string]providerTypes.RuleProvider, respectRules bool, preferH3 bool) ([]dns.Policy, error) {
1300+
func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], ruleProviders map[string]providerTypes.RuleProvider, respectRules bool, preferH3 bool) ([]dns.Policy, error) {
13011301
var policy []dns.Policy
13021302
re := regexp.MustCompile(`[a-zA-Z0-9\-]+\.[a-zA-Z]{2,}(\.[a-zA-Z]{2,})?`)
13031303

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

13511351
if strings.HasPrefix(domain, "rule-set:") {
13521352
domainSetName := domain[9:]
1353-
rule, err := parseDomainRuleSet(domainSetName, "dns.nameserver-policy", ruleProviders)
1353+
matcher, err := parseDomainRuleSet(domainSetName, "dns.nameserver-policy", ruleProviders)
13541354
if err != nil {
13551355
return nil, err
13561356
}
1357-
policy[idx] = dns.Policy{Rule: rule, NameServers: nameservers}
1357+
policy[idx] = dns.Policy{Matcher: matcher, NameServers: nameservers}
13581358
} else if strings.HasPrefix(domain, "geosite:") {
13591359
country := domain[8:]
1360-
rule, err := RC.NewGEOSITE(country, "dns.nameserver-policy")
1360+
matcher, err := RC.NewGEOSITE(country, "dns.nameserver-policy")
13611361
if err != nil {
13621362
return nil, err
13631363
}
1364-
policy[idx] = dns.Policy{Rule: rule, NameServers: nameservers}
1364+
policy[idx] = dns.Policy{Matcher: matcher, NameServers: nameservers}
13651365
} else {
13661366
if _, valid := trie.ValidAndSplitDomain(domain); !valid {
13671367
return nil, fmt.Errorf("DNS ResoverRule invalid domain: %s", domain)
@@ -1372,7 +1372,7 @@ func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], rules [
13721372
return policy, nil
13731373
}
13741374

1375-
func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rules []C.Rule, ruleProviders map[string]providerTypes.RuleProvider) (*DNS, error) {
1375+
func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], ruleProviders map[string]providerTypes.RuleProvider) (*DNS, error) {
13761376
cfg := rawCfg.DNS
13771377
if cfg.Enable && len(cfg.NameServer) == 0 {
13781378
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
14001400
return nil, err
14011401
}
14021402

1403-
if dnsCfg.NameServerPolicy, err = parseNameServerPolicy(cfg.NameServerPolicy, rules, ruleProviders, cfg.RespectRules, cfg.PreferH3); err != nil {
1403+
if dnsCfg.NameServerPolicy, err = parseNameServerPolicy(cfg.NameServerPolicy, ruleProviders, cfg.RespectRules, cfg.PreferH3); err != nil {
14041404
return nil, err
14051405
}
14061406

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

1470-
var rule C.Rule
14711470
if len(cfg.Fallback) != 0 {
14721471
if cfg.FallbackFilter.GeoIP {
1473-
rule, err = RC.NewGEOIP(cfg.FallbackFilter.GeoIPCode, "dns.fallback-filter.geoip", false, true)
1472+
matcher, err := RC.NewGEOIP(cfg.FallbackFilter.GeoIPCode, "dns.fallback-filter.geoip", false, true)
14741473
if err != nil {
14751474
return nil, fmt.Errorf("load GeoIP dns fallback filter error, %w", err)
14761475
}
1477-
dnsCfg.FallbackIPFilter = append(dnsCfg.FallbackIPFilter, rule)
1476+
dnsCfg.FallbackIPFilter = append(dnsCfg.FallbackIPFilter, matcher)
14781477
}
14791478
if len(cfg.FallbackFilter.IPCIDR) > 0 {
14801479
cidrSet := cidr.NewIpCidrSet()
@@ -1488,8 +1487,8 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
14881487
if err != nil {
14891488
return nil, err
14901489
}
1491-
rule = RP.NewIpCidrSet(cidrSet, "dns.fallback-filter.ipcidr")
1492-
dnsCfg.FallbackIPFilter = append(dnsCfg.FallbackIPFilter, rule)
1490+
matcher := cidrSet // dns.fallback-filter.ipcidr
1491+
dnsCfg.FallbackIPFilter = append(dnsCfg.FallbackIPFilter, matcher)
14931492
}
14941493
if len(cfg.FallbackFilter.Domain) > 0 {
14951494
domainTrie := trie.New[struct{}]()
@@ -1499,17 +1498,17 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
14991498
return nil, fmt.Errorf("DNS FallbackDomain[%d] format error: %w", idx, err)
15001499
}
15011500
}
1502-
rule = RP.NewDomainSet(domainTrie.NewDomainSet(), "dns.fallback-filter.domain")
1503-
dnsCfg.FallbackDomainFilter = append(dnsCfg.FallbackDomainFilter, rule)
1501+
matcher := domainTrie.NewDomainSet() // dns.fallback-filter.domain
1502+
dnsCfg.FallbackDomainFilter = append(dnsCfg.FallbackDomainFilter, matcher)
15041503
}
15051504
if len(cfg.FallbackFilter.GeoSite) > 0 {
15061505
log.Warnln("replace fallback-filter.geosite with nameserver-policy, it will be removed in the future")
15071506
for idx, geoSite := range cfg.FallbackFilter.GeoSite {
1508-
rule, err = RC.NewGEOSITE(geoSite, "dns.fallback-filter.geosite")
1507+
matcher, err := RC.NewGEOSITE(geoSite, "dns.fallback-filter.geosite")
15091508
if err != nil {
15101509
return nil, fmt.Errorf("DNS FallbackGeosite[%d] format error: %w", idx, err)
15111510
}
1512-
dnsCfg.FallbackDomainFilter = append(dnsCfg.FallbackDomainFilter, rule)
1511+
dnsCfg.FallbackDomainFilter = append(dnsCfg.FallbackDomainFilter, matcher)
15131512
}
15141513
}
15151514
}
@@ -1701,31 +1700,31 @@ func parseSniffer(snifferRaw RawSniffer, ruleProviders map[string]providerTypes.
17011700
return snifferConfig, nil
17021701
}
17031702

1704-
func parseIPCIDR(addresses []string, cidrSet *cidr.IpCidrSet, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (ipRules []C.Rule, err error) {
1705-
var rule C.Rule
1703+
func parseIPCIDR(addresses []string, cidrSet *cidr.IpCidrSet, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (matchers []C.IpMatcher, err error) {
1704+
var matcher C.IpMatcher
17061705
for _, ipcidr := range addresses {
17071706
ipcidrLower := strings.ToLower(ipcidr)
17081707
if strings.Contains(ipcidrLower, "geoip:") {
17091708
subkeys := strings.Split(ipcidr, ":")
17101709
subkeys = subkeys[1:]
17111710
subkeys = strings.Split(subkeys[0], ",")
17121711
for _, country := range subkeys {
1713-
rule, err = RC.NewGEOIP(country, adapterName, false, false)
1712+
matcher, err = RC.NewGEOIP(country, adapterName, false, false)
17141713
if err != nil {
17151714
return nil, err
17161715
}
1717-
ipRules = append(ipRules, rule)
1716+
matchers = append(matchers, matcher)
17181717
}
17191718
} else if strings.Contains(ipcidrLower, "rule-set:") {
17201719
subkeys := strings.Split(ipcidr, ":")
17211720
subkeys = subkeys[1:]
17221721
subkeys = strings.Split(subkeys[0], ",")
17231722
for _, domainSetName := range subkeys {
1724-
rule, err = parseIPRuleSet(domainSetName, adapterName, ruleProviders)
1723+
matcher, err = parseIPRuleSet(domainSetName, adapterName, ruleProviders)
17251724
if err != nil {
17261725
return nil, err
17271726
}
1728-
ipRules = append(ipRules, rule)
1727+
matchers = append(matchers, matcher)
17291728
}
17301729
} else {
17311730
if cidrSet == nil {
@@ -1742,37 +1741,37 @@ func parseIPCIDR(addresses []string, cidrSet *cidr.IpCidrSet, adapterName string
17421741
if err != nil {
17431742
return nil, err
17441743
}
1745-
rule = RP.NewIpCidrSet(cidrSet, adapterName)
1746-
ipRules = append(ipRules, rule)
1744+
matcher = cidrSet
1745+
matchers = append(matchers, matcher)
17471746
}
17481747
return
17491748
}
17501749

1751-
func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (domainRules []C.Rule, err error) {
1752-
var rule C.Rule
1750+
func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (matchers []C.DomainMatcher, err error) {
1751+
var matcher C.DomainMatcher
17531752
for _, domain := range domains {
17541753
domainLower := strings.ToLower(domain)
17551754
if strings.Contains(domainLower, "geosite:") {
17561755
subkeys := strings.Split(domain, ":")
17571756
subkeys = subkeys[1:]
17581757
subkeys = strings.Split(subkeys[0], ",")
17591758
for _, country := range subkeys {
1760-
rule, err = RC.NewGEOSITE(country, adapterName)
1759+
matcher, err = RC.NewGEOSITE(country, adapterName)
17611760
if err != nil {
17621761
return nil, err
17631762
}
1764-
domainRules = append(domainRules, rule)
1763+
matchers = append(matchers, matcher)
17651764
}
17661765
} else if strings.Contains(domainLower, "rule-set:") {
17671766
subkeys := strings.Split(domain, ":")
17681767
subkeys = subkeys[1:]
17691768
subkeys = strings.Split(subkeys[0], ",")
17701769
for _, domainSetName := range subkeys {
1771-
rule, err = parseDomainRuleSet(domainSetName, adapterName, ruleProviders)
1770+
matcher, err = parseDomainRuleSet(domainSetName, adapterName, ruleProviders)
17721771
if err != nil {
17731772
return nil, err
17741773
}
1775-
domainRules = append(domainRules, rule)
1774+
matchers = append(matchers, matcher)
17761775
}
17771776
} else {
17781777
if domainTrie == nil {
@@ -1785,13 +1784,13 @@ func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], adapte
17851784
}
17861785
}
17871786
if !domainTrie.IsEmpty() {
1788-
rule = RP.NewDomainSet(domainTrie.NewDomainSet(), adapterName)
1789-
domainRules = append(domainRules, rule)
1787+
matcher = domainTrie.NewDomainSet()
1788+
matchers = append(matchers, matcher)
17901789
}
17911790
return
17921791
}
17931792

1794-
func parseIPRuleSet(domainSetName string, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (C.Rule, error) {
1793+
func parseIPRuleSet(domainSetName string, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (C.IpMatcher, error) {
17951794
if rp, ok := ruleProviders[domainSetName]; !ok {
17961795
return nil, fmt.Errorf("not found rule-set: %s", domainSetName)
17971796
} else {
@@ -1806,7 +1805,7 @@ func parseIPRuleSet(domainSetName string, adapterName string, ruleProviders map[
18061805
return RP.NewRuleSet(domainSetName, adapterName, true)
18071806
}
18081807

1809-
func parseDomainRuleSet(domainSetName string, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (C.Rule, error) {
1808+
func parseDomainRuleSet(domainSetName string, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (C.DomainMatcher, error) {
18101809
if rp, ok := ruleProviders[domainSetName]; !ok {
18111810
return nil, fmt.Errorf("not found rule-set: %s", domainSetName)
18121811
} else {

constant/matcher.go

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package constant
2+
3+
import "net/netip"
4+
5+
type DomainMatcher interface {
6+
MatchDomain(domain string) bool
7+
}
8+
9+
type IpMatcher interface {
10+
MatchIp(ip netip.Addr) bool
11+
}

constant/metadata.go

+2
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,9 @@ type Metadata struct {
133133
Type Type `json:"type"`
134134
SrcIP netip.Addr `json:"sourceIP"`
135135
DstIP netip.Addr `json:"destinationIP"`
136+
SrcGeoIP []string `json:"sourceGeoIP"` // can be nil if never queried, empty slice if got no result
136137
DstGeoIP []string `json:"destinationGeoIP"` // can be nil if never queried, empty slice if got no result
138+
SrcIPASN string `json:"sourceIPASN"`
137139
DstIPASN string `json:"destinationIPASN"`
138140
SrcPort uint16 `json:"sourcePort,string"` // `,string` is used to compatible with old version json output
139141
DstPort uint16 `json:"destinationPort,string"` // `,string` is used to compatible with old version json output

0 commit comments

Comments
 (0)