Fix fakeip lookup

This commit is contained in:
世界
2023-07-11 14:05:14 +08:00
parent bb651db2d2
commit 120dae4eed
5 changed files with 94 additions and 20 deletions

View File

@@ -2,48 +2,78 @@ package fakeip
import (
"net/netip"
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing/common/cache"
"github.com/sagernet/sing/common/logger"
)
var _ adapter.FakeIPStorage = (*MemoryStorage)(nil)
type MemoryStorage struct {
metadata *adapter.FakeIPMetadata
domainCache *cache.LruCache[netip.Addr, string]
addressAccess sync.RWMutex
domainAccess sync.RWMutex
addressCache map[netip.Addr]string
domainCache4 map[string]netip.Addr
domainCache6 map[string]netip.Addr
}
func NewMemoryStorage() *MemoryStorage {
return &MemoryStorage{
domainCache: cache.New[netip.Addr, string](),
addressCache: make(map[netip.Addr]string),
domainCache4: make(map[string]netip.Addr),
domainCache6: make(map[string]netip.Addr),
}
}
func (s *MemoryStorage) FakeIPMetadata() *adapter.FakeIPMetadata {
return s.metadata
return nil
}
func (s *MemoryStorage) FakeIPSaveMetadata(metadata *adapter.FakeIPMetadata) error {
s.metadata = metadata
return nil
}
func (s *MemoryStorage) FakeIPStore(address netip.Addr, domain string) error {
s.domainCache.Store(address, domain)
s.addressAccess.Lock()
s.domainAccess.Lock()
s.addressCache[address] = domain
if address.Is4() {
s.domainCache4[domain] = address
} else {
s.domainCache6[domain] = address
}
s.domainAccess.Unlock()
s.addressAccess.Unlock()
return nil
}
func (s *MemoryStorage) FakeIPStoreAsync(address netip.Addr, domain string, logger logger.Logger) {
s.domainCache.Store(address, domain)
_ = s.FakeIPStore(address, domain)
}
func (s *MemoryStorage) FakeIPLoad(address netip.Addr) (string, bool) {
return s.domainCache.Load(address)
s.addressAccess.RLock()
defer s.addressAccess.RUnlock()
domain, loaded := s.addressCache[address]
return domain, loaded
}
func (s *MemoryStorage) FakeIPLoadDomain(domain string, isIPv6 bool) (netip.Addr, bool) {
s.domainAccess.RLock()
defer s.domainAccess.RUnlock()
if !isIPv6 {
address, loaded := s.domainCache4[domain]
return address, loaded
} else {
address, loaded := s.domainCache6[domain]
return address, loaded
}
}
func (s *MemoryStorage) FakeIPReset() error {
s.domainCache = cache.New[netip.Addr, string]()
s.addressCache = make(map[netip.Addr]string)
s.domainCache4 = make(map[string]netip.Addr)
s.domainCache6 = make(map[string]netip.Addr)
return nil
}

View File

@@ -69,14 +69,14 @@ func (s *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg,
func (s *Transport) Lookup(ctx context.Context, domain string, strategy dns.DomainStrategy) ([]netip.Addr, error) {
var addresses []netip.Addr
if strategy != dns.DomainStrategyUseIPv6 {
inet4Address, err := s.store.Create(domain, dns.DomainStrategyUseIPv4)
inet4Address, err := s.store.Create(domain, false)
if err != nil {
return nil, err
}
addresses = append(addresses, inet4Address)
}
if strategy != dns.DomainStrategyUseIPv4 {
inet6Address, err := s.store.Create(domain, dns.DomainStrategyUseIPv6)
inet6Address, err := s.store.Create(domain, true)
if err != nil {
return nil, err
}

View File

@@ -4,7 +4,6 @@ import (
"net/netip"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-dns"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
)
@@ -72,9 +71,12 @@ func (s *Store) Close() error {
})
}
func (s *Store) Create(domain string, strategy dns.DomainStrategy) (netip.Addr, error) {
func (s *Store) Create(domain string, isIPv6 bool) (netip.Addr, error) {
if address, loaded := s.storage.FakeIPLoadDomain(domain, isIPv6); loaded {
return address, nil
}
var address netip.Addr
if strategy == dns.DomainStrategyUseIPv4 {
if !isIPv6 {
if !s.inet4Current.IsValid() {
return netip.Addr{}, E.New("missing IPv4 fakeip address range")
}