github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/transport/fakeip/store.go (about) 1 package fakeip 2 3 import ( 4 "net/netip" 5 6 "github.com/inazumav/sing-box/adapter" 7 E "github.com/sagernet/sing/common/exceptions" 8 "github.com/sagernet/sing/common/logger" 9 ) 10 11 var _ adapter.FakeIPStore = (*Store)(nil) 12 13 type Store struct { 14 router adapter.Router 15 logger logger.Logger 16 inet4Range netip.Prefix 17 inet6Range netip.Prefix 18 storage adapter.FakeIPStorage 19 inet4Current netip.Addr 20 inet6Current netip.Addr 21 } 22 23 func NewStore(router adapter.Router, logger logger.Logger, inet4Range netip.Prefix, inet6Range netip.Prefix) *Store { 24 return &Store{ 25 router: router, 26 logger: logger, 27 inet4Range: inet4Range, 28 inet6Range: inet6Range, 29 } 30 } 31 32 func (s *Store) Start() error { 33 var storage adapter.FakeIPStorage 34 if clashServer := s.router.ClashServer(); clashServer != nil && clashServer.StoreFakeIP() { 35 if cacheFile := clashServer.CacheFile(); cacheFile != nil { 36 storage = cacheFile 37 } 38 } 39 if storage == nil { 40 storage = NewMemoryStorage() 41 } 42 metadata := storage.FakeIPMetadata() 43 if metadata != nil && metadata.Inet4Range == s.inet4Range && metadata.Inet6Range == s.inet6Range { 44 s.inet4Current = metadata.Inet4Current 45 s.inet6Current = metadata.Inet6Current 46 } else { 47 if s.inet4Range.IsValid() { 48 s.inet4Current = s.inet4Range.Addr().Next().Next() 49 } 50 if s.inet6Range.IsValid() { 51 s.inet6Current = s.inet6Range.Addr().Next().Next() 52 } 53 _ = storage.FakeIPReset() 54 } 55 s.storage = storage 56 return nil 57 } 58 59 func (s *Store) Contains(address netip.Addr) bool { 60 return s.inet4Range.Contains(address) || s.inet6Range.Contains(address) 61 } 62 63 func (s *Store) Close() error { 64 if s.storage == nil { 65 return nil 66 } 67 return s.storage.FakeIPSaveMetadata(&adapter.FakeIPMetadata{ 68 Inet4Range: s.inet4Range, 69 Inet6Range: s.inet6Range, 70 Inet4Current: s.inet4Current, 71 Inet6Current: s.inet6Current, 72 }) 73 } 74 75 func (s *Store) Create(domain string, isIPv6 bool) (netip.Addr, error) { 76 if address, loaded := s.storage.FakeIPLoadDomain(domain, isIPv6); loaded { 77 return address, nil 78 } 79 var address netip.Addr 80 if !isIPv6 { 81 if !s.inet4Current.IsValid() { 82 return netip.Addr{}, E.New("missing IPv4 fakeip address range") 83 } 84 nextAddress := s.inet4Current.Next() 85 if !s.inet4Range.Contains(nextAddress) { 86 nextAddress = s.inet4Range.Addr().Next().Next() 87 } 88 s.inet4Current = nextAddress 89 address = nextAddress 90 } else { 91 if !s.inet6Current.IsValid() { 92 return netip.Addr{}, E.New("missing IPv6 fakeip address range") 93 } 94 nextAddress := s.inet6Current.Next() 95 if !s.inet6Range.Contains(nextAddress) { 96 nextAddress = s.inet6Range.Addr().Next().Next() 97 } 98 s.inet6Current = nextAddress 99 address = nextAddress 100 } 101 s.storage.FakeIPStoreAsync(address, domain, s.logger) 102 s.storage.FakeIPSaveMetadataAsync(&adapter.FakeIPMetadata{ 103 Inet4Range: s.inet4Range, 104 Inet6Range: s.inet6Range, 105 Inet4Current: s.inet4Current, 106 Inet6Current: s.inet6Current, 107 }) 108 return address, nil 109 } 110 111 func (s *Store) Lookup(address netip.Addr) (string, bool) { 112 return s.storage.FakeIPLoad(address) 113 } 114 115 func (s *Store) Reset() error { 116 return s.storage.FakeIPReset() 117 }