store.go 3.0 KB

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