Skip to content

Commit c8af92a

Browse files
committed
feat: support fake-ip-range6 in dns module
1 parent ff62386 commit c8af92a

File tree

13 files changed

+233
-152
lines changed

13 files changed

+233
-152
lines changed

component/fakeip/cachefile.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ func (c *cachefileStore) FlushFakeIP() error {
5050
return c.cache.FlushFakeIP()
5151
}
5252

53-
func newCachefileStore(cache *cachefile.CacheFile) *cachefileStore {
54-
return &cachefileStore{cache.FakeIpStore()}
53+
func newCachefileStore(cache *cachefile.CacheFile, prefix netip.Prefix) *cachefileStore {
54+
if prefix.Addr().Is6() {
55+
return &cachefileStore{cache.FakeIpStore6()}
56+
} else {
57+
return &cachefileStore{cache.FakeIpStore()}
58+
}
5559
}

component/fakeip/pool.go

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"sync"
88

99
"github.com/metacubex/mihomo/component/profile/cachefile"
10-
C "github.com/metacubex/mihomo/constant"
1110

1211
"go4.org/netipx"
1312
)
@@ -36,8 +35,6 @@ type Pool struct {
3635
offset netip.Addr
3736
cycle bool
3837
mux sync.Mutex
39-
host []C.DomainMatcher
40-
mode C.FilterMode
4138
ipnet netip.Prefix
4239
store store
4340
}
@@ -66,24 +63,6 @@ func (p *Pool) LookBack(ip netip.Addr) (string, bool) {
6663
return p.store.GetByIP(ip)
6764
}
6865

69-
// ShouldSkipped return if domain should be skipped
70-
func (p *Pool) ShouldSkipped(domain string) bool {
71-
should := p.shouldSkipped(domain)
72-
if p.mode == C.FilterWhiteList {
73-
return !should
74-
}
75-
return should
76-
}
77-
78-
func (p *Pool) shouldSkipped(domain string) bool {
79-
for _, matcher := range p.host {
80-
if matcher.MatchDomain(domain) {
81-
return true
82-
}
83-
}
84-
return false
85-
}
86-
8766
// Exist returns if given ip exists in fake-ip pool
8867
func (p *Pool) Exist(ip netip.Addr) bool {
8968
p.mux.Lock()
@@ -166,8 +145,6 @@ func (p *Pool) restoreState() {
166145

167146
type Options struct {
168147
IPNet netip.Prefix
169-
Host []C.DomainMatcher
170-
Mode C.FilterMode
171148

172149
// Size sets the maximum number of entries in memory
173150
// and does not work if Persistence is true
@@ -197,12 +174,10 @@ func New(options Options) (*Pool, error) {
197174
last: last,
198175
offset: first.Prev(),
199176
cycle: false,
200-
host: options.Host,
201-
mode: options.Mode,
202177
ipnet: options.IPNet,
203178
}
204179
if options.Persistence {
205-
pool.store = newCachefileStore(cachefile.Cache())
180+
pool.store = newCachefileStore(cachefile.Cache(), options.IPNet)
206181
} else {
207182
pool.store = newMemoryStore(options.Size)
208183
}

component/fakeip/pool_test.go

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import (
88
"time"
99

1010
"github.com/metacubex/mihomo/component/profile/cachefile"
11-
"github.com/metacubex/mihomo/component/trie"
12-
C "github.com/metacubex/mihomo/constant"
1311

1412
"github.com/metacubex/bbolt"
1513
"github.com/stretchr/testify/assert"
@@ -43,7 +41,7 @@ func createCachefileStore(options Options) (*Pool, string, error) {
4341
return nil, "", err
4442
}
4543

46-
pool.store = newCachefileStore(&cachefile.CacheFile{DB: db})
44+
pool.store = newCachefileStore(&cachefile.CacheFile{DB: db}, options.IPNet)
4745
return pool, f.Name(), nil
4846
}
4947

@@ -146,47 +144,6 @@ func TestPool_CycleUsed(t *testing.T) {
146144
}
147145
}
148146

149-
func TestPool_Skip(t *testing.T) {
150-
ipnet := netip.MustParsePrefix("192.168.0.1/29")
151-
tree := trie.New[struct{}]()
152-
assert.NoError(t, tree.Insert("example.com", struct{}{}))
153-
assert.False(t, tree.IsEmpty())
154-
pools, tempfile, err := createPools(Options{
155-
IPNet: ipnet,
156-
Size: 10,
157-
Host: []C.DomainMatcher{tree.NewDomainSet()},
158-
})
159-
assert.Nil(t, err)
160-
defer os.Remove(tempfile)
161-
162-
for _, pool := range pools {
163-
assert.True(t, pool.ShouldSkipped("example.com"))
164-
assert.False(t, pool.ShouldSkipped("foo.com"))
165-
assert.False(t, pool.shouldSkipped("baz.com"))
166-
}
167-
}
168-
169-
func TestPool_SkipWhiteList(t *testing.T) {
170-
ipnet := netip.MustParsePrefix("192.168.0.1/29")
171-
tree := trie.New[struct{}]()
172-
assert.NoError(t, tree.Insert("example.com", struct{}{}))
173-
assert.False(t, tree.IsEmpty())
174-
pools, tempfile, err := createPools(Options{
175-
IPNet: ipnet,
176-
Size: 10,
177-
Host: []C.DomainMatcher{tree.NewDomainSet()},
178-
Mode: C.FilterWhiteList,
179-
})
180-
assert.Nil(t, err)
181-
defer os.Remove(tempfile)
182-
183-
for _, pool := range pools {
184-
assert.False(t, pool.ShouldSkipped("example.com"))
185-
assert.True(t, pool.ShouldSkipped("foo.com"))
186-
assert.True(t, pool.ShouldSkipped("baz.com"))
187-
}
188-
}
189-
190147
func TestPool_MaxCacheSize(t *testing.T) {
191148
ipnet := netip.MustParsePrefix("192.168.0.1/24")
192149
pool, _ := New(Options{

component/fakeip/skipper.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package fakeip
2+
3+
import (
4+
C "github.com/metacubex/mihomo/constant"
5+
)
6+
7+
type Skipper struct {
8+
Host []C.DomainMatcher
9+
Mode C.FilterMode
10+
}
11+
12+
// ShouldSkipped return if domain should be skipped
13+
func (p *Skipper) ShouldSkipped(domain string) bool {
14+
should := p.shouldSkipped(domain)
15+
if p.Mode == C.FilterWhiteList {
16+
return !should
17+
}
18+
return should
19+
}
20+
21+
func (p *Skipper) shouldSkipped(domain string) bool {
22+
for _, matcher := range p.Host {
23+
if matcher.MatchDomain(domain) {
24+
return true
25+
}
26+
}
27+
return false
28+
}

component/fakeip/skipper_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package fakeip
2+
3+
import (
4+
"testing"
5+
6+
"github.com/metacubex/mihomo/component/trie"
7+
C "github.com/metacubex/mihomo/constant"
8+
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestSkipper_BlackList(t *testing.T) {
13+
tree := trie.New[struct{}]()
14+
assert.NoError(t, tree.Insert("example.com", struct{}{}))
15+
assert.False(t, tree.IsEmpty())
16+
skipper := &Skipper{
17+
Host: []C.DomainMatcher{tree.NewDomainSet()},
18+
}
19+
assert.True(t, skipper.ShouldSkipped("example.com"))
20+
assert.False(t, skipper.ShouldSkipped("foo.com"))
21+
assert.False(t, skipper.shouldSkipped("baz.com"))
22+
}
23+
24+
func TestSkipper_WhiteList(t *testing.T) {
25+
tree := trie.New[struct{}]()
26+
assert.NoError(t, tree.Insert("example.com", struct{}{}))
27+
assert.False(t, tree.IsEmpty())
28+
skipper := &Skipper{
29+
Host: []C.DomainMatcher{tree.NewDomainSet()},
30+
Mode: C.FilterWhiteList,
31+
}
32+
assert.False(t, skipper.ShouldSkipped("example.com"))
33+
assert.True(t, skipper.ShouldSkipped("foo.com"))
34+
assert.True(t, skipper.ShouldSkipped("baz.com"))
35+
}

component/profile/cachefile/cache.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ var (
1919

2020
bucketSelected = []byte("selected")
2121
bucketFakeip = []byte("fakeip")
22+
bucketFakeip6 = []byte("fakeip6")
2223
bucketETag = []byte("etag")
2324
bucketSubscriptionInfo = []byte("subscriptioninfo")
2425
)

component/profile/cachefile/fakeip.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,23 @@ import (
1010

1111
type FakeIpStore struct {
1212
*CacheFile
13+
bucketName []byte
1314
}
1415

1516
func (c *CacheFile) FakeIpStore() *FakeIpStore {
16-
return &FakeIpStore{c}
17+
return &FakeIpStore{c, bucketFakeip}
18+
}
19+
20+
func (c *CacheFile) FakeIpStore6() *FakeIpStore {
21+
return &FakeIpStore{c, bucketFakeip6}
1722
}
1823

1924
func (c *FakeIpStore) GetByHost(host string) (ip netip.Addr, exist bool) {
2025
if c.DB == nil {
2126
return
2227
}
2328
c.DB.View(func(t *bbolt.Tx) error {
24-
if bucket := t.Bucket(bucketFakeip); bucket != nil {
29+
if bucket := t.Bucket(c.bucketName); bucket != nil {
2530
if v := bucket.Get([]byte(host)); v != nil {
2631
ip, exist = netip.AddrFromSlice(v)
2732
}
@@ -36,7 +41,7 @@ func (c *FakeIpStore) PutByHost(host string, ip netip.Addr) {
3641
return
3742
}
3843
err := c.DB.Batch(func(t *bbolt.Tx) error {
39-
bucket, err := t.CreateBucketIfNotExists(bucketFakeip)
44+
bucket, err := t.CreateBucketIfNotExists(c.bucketName)
4045
if err != nil {
4146
return err
4247
}
@@ -52,7 +57,7 @@ func (c *FakeIpStore) GetByIP(ip netip.Addr) (host string, exist bool) {
5257
return
5358
}
5459
c.DB.View(func(t *bbolt.Tx) error {
55-
if bucket := t.Bucket(bucketFakeip); bucket != nil {
60+
if bucket := t.Bucket(c.bucketName); bucket != nil {
5661
if v := bucket.Get(ip.AsSlice()); v != nil {
5762
host, exist = string(v), true
5863
}
@@ -67,7 +72,7 @@ func (c *FakeIpStore) PutByIP(ip netip.Addr, host string) {
6772
return
6873
}
6974
err := c.DB.Batch(func(t *bbolt.Tx) error {
70-
bucket, err := t.CreateBucketIfNotExists(bucketFakeip)
75+
bucket, err := t.CreateBucketIfNotExists(c.bucketName)
7176
if err != nil {
7277
return err
7378
}
@@ -85,7 +90,7 @@ func (c *FakeIpStore) DelByIP(ip netip.Addr) {
8590

8691
addr := ip.AsSlice()
8792
err := c.DB.Batch(func(t *bbolt.Tx) error {
88-
bucket, err := t.CreateBucketIfNotExists(bucketFakeip)
93+
bucket, err := t.CreateBucketIfNotExists(c.bucketName)
8994
if err != nil {
9095
return err
9196
}
@@ -105,11 +110,11 @@ func (c *FakeIpStore) DelByIP(ip netip.Addr) {
105110

106111
func (c *FakeIpStore) FlushFakeIP() error {
107112
err := c.DB.Batch(func(t *bbolt.Tx) error {
108-
bucket := t.Bucket(bucketFakeip)
113+
bucket := t.Bucket(c.bucketName)
109114
if bucket == nil {
110115
return nil
111116
}
112-
return t.DeleteBucket(bucketFakeip)
117+
return t.DeleteBucket(c.bucketName)
113118
})
114119
return err
115120
}

0 commit comments

Comments
 (0)