Bläddra i källkod

Fix async FakeIP save

世界 2 år sedan
förälder
incheckning
9d75385bbb

+ 2 - 0
adapter/fakeip.go

@@ -4,6 +4,7 @@ import (
 	"net/netip"
 	"net/netip"
 
 
 	"github.com/sagernet/sing-dns"
 	"github.com/sagernet/sing-dns"
+	"github.com/sagernet/sing/common/logger"
 )
 )
 
 
 type FakeIPStore interface {
 type FakeIPStore interface {
@@ -18,6 +19,7 @@ type FakeIPStorage interface {
 	FakeIPMetadata() *FakeIPMetadata
 	FakeIPMetadata() *FakeIPMetadata
 	FakeIPSaveMetadata(metadata *FakeIPMetadata) error
 	FakeIPSaveMetadata(metadata *FakeIPMetadata) error
 	FakeIPStore(address netip.Addr, domain string) error
 	FakeIPStore(address netip.Addr, domain string) error
+	FakeIPStoreAsync(address netip.Addr, domain string, logger logger.Logger)
 	FakeIPLoad(address netip.Addr) (string, bool)
 	FakeIPLoad(address netip.Addr) (string, bool)
 	FakeIPReset() error
 	FakeIPReset() error
 }
 }

+ 11 - 3
experimental/clashapi/cachefile/cache.go

@@ -1,7 +1,9 @@
 package cachefile
 package cachefile
 
 
 import (
 import (
+	"net/netip"
 	"os"
 	"os"
+	"sync"
 	"time"
 	"time"
 
 
 	"github.com/sagernet/sing-box/adapter"
 	"github.com/sagernet/sing-box/adapter"
@@ -14,8 +16,10 @@ 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
+	DB         *bbolt.DB
+	cacheID    []byte
+	saveAccess sync.RWMutex
+	saveCache  map[netip.Addr]string
 }
 }
 
 
 func Open(path string, cacheID string) (*CacheFile, error) {
 func Open(path string, cacheID string) (*CacheFile, error) {
@@ -36,7 +40,11 @@ func Open(path string, cacheID string) (*CacheFile, error) {
 	if cacheID != "" {
 	if cacheID != "" {
 		cacheIDBytes = append([]byte{0}, []byte(cacheID)...)
 		cacheIDBytes = append([]byte{0}, []byte(cacheID)...)
 	}
 	}
-	return &CacheFile{db, cacheIDBytes}, nil
+	return &CacheFile{
+		DB:        db,
+		cacheID:   cacheIDBytes,
+		saveCache: make(map[netip.Addr]string),
+	}, nil
 }
 }
 
 
 func (c *CacheFile) bucket(t *bbolt.Tx, key []byte) *bbolt.Bucket {
 func (c *CacheFile) bucket(t *bbolt.Tx, key []byte) *bbolt.Bucket {

+ 22 - 0
experimental/clashapi/cachefile/fakeip.go

@@ -5,6 +5,7 @@ import (
 	"os"
 	"os"
 
 
 	"github.com/sagernet/sing-box/adapter"
 	"github.com/sagernet/sing-box/adapter"
+	"github.com/sagernet/sing/common/logger"
 
 
 	"go.etcd.io/bbolt"
 	"go.etcd.io/bbolt"
 )
 )
@@ -57,7 +58,28 @@ func (c *CacheFile) FakeIPStore(address netip.Addr, domain string) error {
 	})
 	})
 }
 }
 
 
+func (c *CacheFile) FakeIPStoreAsync(address netip.Addr, domain string, logger logger.Logger) {
+	c.saveAccess.Lock()
+	c.saveCache[address] = domain
+	c.saveAccess.Unlock()
+	go func() {
+		err := c.FakeIPStore(address, domain)
+		if err != nil {
+			logger.Warn("save FakeIP address pair: ", err)
+		}
+		c.saveAccess.Lock()
+		delete(c.saveCache, address)
+		c.saveAccess.Unlock()
+	}()
+}
+
 func (c *CacheFile) FakeIPLoad(address netip.Addr) (string, bool) {
 func (c *CacheFile) FakeIPLoad(address netip.Addr) (string, bool) {
+	c.saveAccess.RLock()
+	cachedDomain, cached := c.saveCache[address]
+	c.saveAccess.RUnlock()
+	if cached {
+		return cachedDomain, true
+	}
 	var domain string
 	var domain string
 	_ = c.DB.View(func(tx *bbolt.Tx) error {
 	_ = c.DB.View(func(tx *bbolt.Tx) error {
 		bucket := tx.Bucket(bucketFakeIP)
 		bucket := tx.Bucket(bucketFakeIP)

+ 5 - 0
transport/fakeip/memory.go

@@ -5,6 +5,7 @@ import (
 
 
 	"github.com/sagernet/sing-box/adapter"
 	"github.com/sagernet/sing-box/adapter"
 	"github.com/sagernet/sing/common/cache"
 	"github.com/sagernet/sing/common/cache"
+	"github.com/sagernet/sing/common/logger"
 )
 )
 
 
 var _ adapter.FakeIPStorage = (*MemoryStorage)(nil)
 var _ adapter.FakeIPStorage = (*MemoryStorage)(nil)
@@ -34,6 +35,10 @@ func (s *MemoryStorage) FakeIPStore(address netip.Addr, domain string) error {
 	return nil
 	return nil
 }
 }
 
 
+func (s *MemoryStorage) FakeIPStoreAsync(address netip.Addr, domain string, logger logger.Logger) {
+	s.domainCache.Store(address, domain)
+}
+
 func (s *MemoryStorage) FakeIPLoad(address netip.Addr) (string, bool) {
 func (s *MemoryStorage) FakeIPLoad(address netip.Addr) (string, bool) {
 	return s.domainCache.Load(address)
 	return s.domainCache.Load(address)
 }
 }

+ 1 - 6
transport/fakeip/store.go

@@ -95,12 +95,7 @@ func (s *Store) Create(domain string, strategy dns.DomainStrategy) (netip.Addr,
 		s.inet6Current = nextAddress
 		s.inet6Current = nextAddress
 		address = nextAddress
 		address = nextAddress
 	}
 	}
-	go func() {
-		err := s.storage.FakeIPStore(address, domain)
-		if err != nil {
-			s.logger.Warn("save FakeIP address pair: ", err)
-		}
-	}()
+	s.storage.FakeIPStoreAsync(address, domain, s.logger)
 	return address, nil
 	return address, nil
 }
 }