Browse Source

Fix fakeip unsaved state

世界 2 years ago
parent
commit
e0058ca9c5
2 changed files with 46 additions and 11 deletions
  1. 14 7
      experimental/clashapi/cachefile/cache.go
  2. 32 4
      experimental/clashapi/cachefile/fakeip.go

+ 14 - 7
experimental/clashapi/cachefile/cache.go

@@ -17,10 +17,12 @@ var bucketSelected = []byte("selected")
 var _ adapter.ClashCacheFile = (*CacheFile)(nil)
 var _ adapter.ClashCacheFile = (*CacheFile)(nil)
 
 
 type CacheFile struct {
 type CacheFile struct {
-	DB         *bbolt.DB
-	cacheID    []byte
-	saveAccess sync.RWMutex
-	saveCache  map[netip.Addr]string
+	DB           *bbolt.DB
+	cacheID      []byte
+	saveAccess   sync.RWMutex
+	saveDomain   map[netip.Addr]string
+	saveAddress4 map[string]netip.Addr
+	saveAddress6 map[string]netip.Addr
 }
 }
 
 
 func Open(path string, cacheID string) (*CacheFile, error) {
 func Open(path string, cacheID string) (*CacheFile, error) {
@@ -53,10 +55,15 @@ func Open(path string, cacheID string) (*CacheFile, error) {
 			return nil
 			return nil
 		})
 		})
 	})
 	})
+	if err != nil {
+		return nil, err
+	}
 	return &CacheFile{
 	return &CacheFile{
-		DB:        db,
-		cacheID:   cacheIDBytes,
-		saveCache: make(map[netip.Addr]string),
+		DB:           db,
+		cacheID:      cacheIDBytes,
+		saveDomain:   make(map[netip.Addr]string),
+		saveAddress4: make(map[string]netip.Addr),
+		saveAddress6: make(map[string]netip.Addr),
 	}, nil
 	}, nil
 }
 }
 
 

+ 32 - 4
experimental/clashapi/cachefile/fakeip.go

@@ -22,7 +22,7 @@ var (
 
 
 func (c *CacheFile) FakeIPMetadata() *adapter.FakeIPMetadata {
 func (c *CacheFile) FakeIPMetadata() *adapter.FakeIPMetadata {
 	var metadata adapter.FakeIPMetadata
 	var metadata adapter.FakeIPMetadata
-	err := c.DB.View(func(tx *bbolt.Tx) error {
+	err := c.DB.Batch(func(tx *bbolt.Tx) error {
 		bucket := tx.Bucket(bucketFakeIP)
 		bucket := tx.Bucket(bucketFakeIP)
 		if bucket == nil {
 		if bucket == nil {
 			return nil
 			return nil
@@ -31,6 +31,10 @@ func (c *CacheFile) FakeIPMetadata() *adapter.FakeIPMetadata {
 		if len(metadataBinary) == 0 {
 		if len(metadataBinary) == 0 {
 			return os.ErrInvalid
 			return os.ErrInvalid
 		}
 		}
+		err := bucket.Delete(keyMetadata)
+		if err != nil {
+			return err
+		}
 		return metadata.UnmarshalBinary(metadataBinary)
 		return metadata.UnmarshalBinary(metadataBinary)
 	})
 	})
 	if err != nil {
 	if err != nil {
@@ -77,7 +81,12 @@ func (c *CacheFile) FakeIPStore(address netip.Addr, domain string) error {
 
 
 func (c *CacheFile) FakeIPStoreAsync(address netip.Addr, domain string, logger logger.Logger) {
 func (c *CacheFile) FakeIPStoreAsync(address netip.Addr, domain string, logger logger.Logger) {
 	c.saveAccess.Lock()
 	c.saveAccess.Lock()
-	c.saveCache[address] = domain
+	c.saveDomain[address] = domain
+	if address.Is4() {
+		c.saveAddress4[domain] = address
+	} else {
+		c.saveAddress6[domain] = address
+	}
 	c.saveAccess.Unlock()
 	c.saveAccess.Unlock()
 	go func() {
 	go func() {
 		err := c.FakeIPStore(address, domain)
 		err := c.FakeIPStore(address, domain)
@@ -85,14 +94,19 @@ func (c *CacheFile) FakeIPStoreAsync(address netip.Addr, domain string, logger l
 			logger.Warn("save FakeIP address pair: ", err)
 			logger.Warn("save FakeIP address pair: ", err)
 		}
 		}
 		c.saveAccess.Lock()
 		c.saveAccess.Lock()
-		delete(c.saveCache, address)
+		delete(c.saveDomain, address)
+		if address.Is4() {
+			delete(c.saveAddress4, domain)
+		} else {
+			delete(c.saveAddress6, domain)
+		}
 		c.saveAccess.Unlock()
 		c.saveAccess.Unlock()
 	}()
 	}()
 }
 }
 
 
 func (c *CacheFile) FakeIPLoad(address netip.Addr) (string, bool) {
 func (c *CacheFile) FakeIPLoad(address netip.Addr) (string, bool) {
 	c.saveAccess.RLock()
 	c.saveAccess.RLock()
-	cachedDomain, cached := c.saveCache[address]
+	cachedDomain, cached := c.saveDomain[address]
 	c.saveAccess.RUnlock()
 	c.saveAccess.RUnlock()
 	if cached {
 	if cached {
 		return cachedDomain, true
 		return cachedDomain, true
@@ -110,6 +124,20 @@ func (c *CacheFile) FakeIPLoad(address netip.Addr) (string, bool) {
 }
 }
 
 
 func (c *CacheFile) FakeIPLoadDomain(domain string, isIPv6 bool) (netip.Addr, bool) {
 func (c *CacheFile) FakeIPLoadDomain(domain string, isIPv6 bool) (netip.Addr, bool) {
+	var (
+		cachedAddress netip.Addr
+		cached        bool
+	)
+	c.saveAccess.RLock()
+	if !isIPv6 {
+		cachedAddress, cached = c.saveAddress4[domain]
+	} else {
+		cachedAddress, cached = c.saveAddress6[domain]
+	}
+	c.saveAccess.RUnlock()
+	if cached {
+		return cachedAddress, true
+	}
 	var address netip.Addr
 	var address netip.Addr
 	_ = c.DB.View(func(tx *bbolt.Tx) error {
 	_ = c.DB.View(func(tx *bbolt.Tx) error {
 		var bucket *bbolt.Bucket
 		var bucket *bbolt.Bucket