Feature: flush fakeip pool
This commit is contained in:
parent
b7798b8c9d
commit
c38ae18a59
12 changed files with 137 additions and 2 deletions
2
Makefile
2
Makefile
|
@ -130,7 +130,7 @@ all-arch: $(PLATFORM_LIST) $(WINDOWS_ARCH_LIST)
|
||||||
releases: $(gz_releases) $(zip_releases)
|
releases: $(gz_releases) $(zip_releases)
|
||||||
|
|
||||||
vet:
|
vet:
|
||||||
go vet ./...
|
go test ./...
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
golangci-lint run ./...
|
golangci-lint run ./...
|
||||||
|
|
|
@ -40,6 +40,8 @@ Documentations are now moved to [GitHub Wiki](https://github.com/Dreamacro/clash
|
||||||
Support resolve ip with a proxy tunnel.
|
Support resolve ip with a proxy tunnel.
|
||||||
|
|
||||||
Support `geosite` with `fallback-filter`.
|
Support `geosite` with `fallback-filter`.
|
||||||
|
|
||||||
|
Use curl -X POST controllerip:port/cache/fakeip/flush to flush persistence fakeip
|
||||||
```yaml
|
```yaml
|
||||||
dns:
|
dns:
|
||||||
enable: true
|
enable: true
|
||||||
|
|
9
common/cache/lrucache.go
vendored
9
common/cache/lrucache.go
vendored
|
@ -216,6 +216,15 @@ func (c *LruCache) deleteElement(le *list.Element) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *LruCache) Clear() error {
|
||||||
|
c.mu.Lock()
|
||||||
|
|
||||||
|
c.cache = make(map[any]*list.Element)
|
||||||
|
|
||||||
|
c.mu.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type entry struct {
|
type entry struct {
|
||||||
key any
|
key any
|
||||||
value any
|
value any
|
||||||
|
|
|
@ -53,3 +53,8 @@ func (c *cachefileStore) Exist(ip net.IP) bool {
|
||||||
// CloneTo implements store.CloneTo
|
// CloneTo implements store.CloneTo
|
||||||
// already persistence
|
// already persistence
|
||||||
func (c *cachefileStore) CloneTo(store store) {}
|
func (c *cachefileStore) CloneTo(store store) {}
|
||||||
|
|
||||||
|
// FlushFakeIP implements store.FlushFakeIP
|
||||||
|
func (c *cachefileStore) FlushFakeIP() error {
|
||||||
|
return c.cache.FlushFakeIP()
|
||||||
|
}
|
||||||
|
|
|
@ -67,3 +67,8 @@ func (m *memoryStore) CloneTo(store store) {
|
||||||
m.cache.CloneTo(ms.cache)
|
m.cache.CloneTo(ms.cache)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FlushFakeIP implements store.FlushFakeIP
|
||||||
|
func (m *memoryStore) FlushFakeIP() error {
|
||||||
|
return m.cache.Clear()
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ type store interface {
|
||||||
DelByIP(ip net.IP)
|
DelByIP(ip net.IP)
|
||||||
Exist(ip net.IP) bool
|
Exist(ip net.IP) bool
|
||||||
CloneTo(store)
|
CloneTo(store)
|
||||||
|
FlushFakeIP() error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pool is a implementation about fake ip generator without storage
|
// Pool is a implementation about fake ip generator without storage
|
||||||
|
@ -120,6 +121,10 @@ func (p *Pool) get(host string) net.IP {
|
||||||
return ip
|
return ip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Pool) FlushFakeIP() error {
|
||||||
|
return p.store.FlushFakeIP()
|
||||||
|
}
|
||||||
|
|
||||||
func ipToUint(ip net.IP) uint32 {
|
func ipToUint(ip net.IP) uint32 {
|
||||||
v := uint32(ip[0]) << 24
|
v := uint32(ip[0]) << 24
|
||||||
v += uint32(ip[1]) << 16
|
v += uint32(ip[1]) << 16
|
||||||
|
|
|
@ -193,3 +193,59 @@ func TestPool_Error(t *testing.T) {
|
||||||
|
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPool_FlushFileCache(t *testing.T) {
|
||||||
|
_, ipnet, _ := net.ParseCIDR("192.168.0.1/28")
|
||||||
|
pools, tempfile, err := createPools(Options{
|
||||||
|
IPNet: ipnet,
|
||||||
|
Size: 10,
|
||||||
|
})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
defer os.Remove(tempfile)
|
||||||
|
|
||||||
|
for _, pool := range pools {
|
||||||
|
foo := pool.Lookup("foo.com")
|
||||||
|
bar := pool.Lookup("baz.com")
|
||||||
|
bax := pool.Lookup("baz.com")
|
||||||
|
fox := pool.Lookup("foo.com")
|
||||||
|
|
||||||
|
err = pool.FlushFakeIP()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
baz := pool.Lookup("foo.com")
|
||||||
|
next := pool.Lookup("baz.com")
|
||||||
|
nero := pool.Lookup("foo.com")
|
||||||
|
|
||||||
|
assert.Equal(t, foo, fox)
|
||||||
|
assert.NotEqual(t, foo, baz)
|
||||||
|
assert.Equal(t, bar, bax)
|
||||||
|
assert.NotEqual(t, bar, next)
|
||||||
|
assert.Equal(t, baz, nero)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPool_FlushMemoryCache(t *testing.T) {
|
||||||
|
_, ipnet, _ := net.ParseCIDR("192.168.0.1/28")
|
||||||
|
pool, _ := New(Options{
|
||||||
|
IPNet: ipnet,
|
||||||
|
Size: 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
foo := pool.Lookup("foo.com")
|
||||||
|
bar := pool.Lookup("baz.com")
|
||||||
|
bax := pool.Lookup("baz.com")
|
||||||
|
fox := pool.Lookup("foo.com")
|
||||||
|
|
||||||
|
err := pool.FlushFakeIP()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
baz := pool.Lookup("foo.com")
|
||||||
|
next := pool.Lookup("baz.com")
|
||||||
|
nero := pool.Lookup("foo.com")
|
||||||
|
|
||||||
|
assert.Equal(t, foo, fox)
|
||||||
|
assert.NotEqual(t, foo, baz)
|
||||||
|
assert.Equal(t, bar, bax)
|
||||||
|
assert.NotEqual(t, bar, next)
|
||||||
|
assert.Equal(t, baz, nero)
|
||||||
|
}
|
||||||
|
|
|
@ -132,6 +132,17 @@ func (c *CacheFile) GetFakeip(key []byte) []byte {
|
||||||
return bucket.Get(key)
|
return bucket.Get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *CacheFile) FlushFakeIP() error {
|
||||||
|
err := c.DB.Batch(func(t *bbolt.Tx) error {
|
||||||
|
bucket := t.Bucket(bucketFakeip)
|
||||||
|
if bucket == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return t.DeleteBucket(bucketFakeip)
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (c *CacheFile) Close() error {
|
func (c *CacheFile) Close() error {
|
||||||
return c.DB.Close()
|
return c.DB.Close()
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ type Enhancer interface {
|
||||||
IsFakeBroadcastIP(net.IP) bool
|
IsFakeBroadcastIP(net.IP) bool
|
||||||
IsExistFakeIP(net.IP) bool
|
IsExistFakeIP(net.IP) bool
|
||||||
FindHostByIP(net.IP) (string, bool)
|
FindHostByIP(net.IP) (string, bool)
|
||||||
|
FlushFakeIP() error
|
||||||
}
|
}
|
||||||
|
|
||||||
func FakeIPEnabled() bool {
|
func FakeIPEnabled() bool {
|
||||||
|
@ -62,3 +63,10 @@ func FindHostByIP(ip net.IP) (string, bool) {
|
||||||
|
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FlushFakeIP() error {
|
||||||
|
if mapper := DefaultHostMapper; mapper != nil {
|
||||||
|
return mapper.FlushFakeIP()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -84,6 +84,13 @@ func (h *ResolverEnhancer) PatchFrom(o *ResolverEnhancer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *ResolverEnhancer) FlushFakeIP() error {
|
||||||
|
if h.fakePool != nil {
|
||||||
|
return h.fakePool.FlushFakeIP()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewEnhancer(cfg Config) *ResolverEnhancer {
|
func NewEnhancer(cfg Config) *ResolverEnhancer {
|
||||||
var fakePool *fakeip.Pool
|
var fakePool *fakeip.Pool
|
||||||
var mapping *cache.LruCache
|
var mapping *cache.LruCache
|
||||||
|
|
26
hub/route/cache.go
Normal file
26
hub/route/cache.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package route
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/Dreamacro/clash/component/resolver"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
|
"github.com/go-chi/render"
|
||||||
|
)
|
||||||
|
|
||||||
|
func cacheRouter() http.Handler {
|
||||||
|
r := chi.NewRouter()
|
||||||
|
r.Post("/fakeip/flush", flushFakeIPPool)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func flushFakeIPPool(w http.ResponseWriter, r *http.Request) {
|
||||||
|
err := resolver.FlushFakeIP()
|
||||||
|
if err != nil {
|
||||||
|
render.Status(r, http.StatusBadRequest)
|
||||||
|
render.JSON(w, r, newError(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
render.NoContent(w, r)
|
||||||
|
}
|
|
@ -71,6 +71,7 @@ func Start(addr string, secret string) {
|
||||||
r.Mount("/rules", ruleRouter())
|
r.Mount("/rules", ruleRouter())
|
||||||
r.Mount("/connections", connectionRouter())
|
r.Mount("/connections", connectionRouter())
|
||||||
r.Mount("/providers/proxies", proxyProviderRouter())
|
r.Mount("/providers/proxies", proxyProviderRouter())
|
||||||
|
r.Mount("/cache", cacheRouter())
|
||||||
})
|
})
|
||||||
|
|
||||||
if uiPath != "" {
|
if uiPath != "" {
|
||||||
|
@ -130,7 +131,7 @@ func authentication(next http.Handler) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
func hello(w http.ResponseWriter, r *http.Request) {
|
func hello(w http.ResponseWriter, r *http.Request) {
|
||||||
render.JSON(w, r, render.M{"hello": "clash"})
|
render.JSON(w, r, render.M{"hello": "clash with tun"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func traffic(w http.ResponseWriter, r *http.Request) {
|
func traffic(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
Loading…
Reference in a new issue