sing-box/transport/fakeip/store.go

119 lines
3 KiB
Go
Raw Permalink Normal View History

2023-03-25 04:03:23 +00:00
package fakeip
import (
2023-11-28 04:00:28 +00:00
"context"
2023-03-25 04:03:23 +00:00
"net/netip"
"github.com/sagernet/sing-box/adapter"
E "github.com/sagernet/sing/common/exceptions"
2023-07-07 04:48:26 +00:00
"github.com/sagernet/sing/common/logger"
2023-11-28 04:00:28 +00:00
"github.com/sagernet/sing/service"
2023-03-25 04:03:23 +00:00
)
var _ adapter.FakeIPStore = (*Store)(nil)
type Store struct {
2023-11-28 04:00:28 +00:00
ctx context.Context
2023-07-07 04:48:26 +00:00
logger logger.Logger
2023-03-25 04:03:23 +00:00
inet4Range netip.Prefix
inet6Range netip.Prefix
storage adapter.FakeIPStorage
inet4Current netip.Addr
inet6Current netip.Addr
}
2023-11-28 04:00:28 +00:00
func NewStore(ctx context.Context, logger logger.Logger, inet4Range netip.Prefix, inet6Range netip.Prefix) *Store {
2023-03-25 04:03:23 +00:00
return &Store{
2023-11-28 04:00:28 +00:00
ctx: ctx,
2023-07-07 04:48:26 +00:00
logger: logger,
2023-03-25 04:03:23 +00:00
inet4Range: inet4Range,
inet6Range: inet6Range,
}
}
func (s *Store) Start() error {
var storage adapter.FakeIPStorage
2023-11-28 04:00:28 +00:00
cacheFile := service.FromContext[adapter.CacheFile](s.ctx)
if cacheFile != nil && cacheFile.StoreFakeIP() {
storage = cacheFile
2023-03-25 04:03:23 +00:00
}
if storage == nil {
storage = NewMemoryStorage()
}
metadata := storage.FakeIPMetadata()
if metadata != nil && metadata.Inet4Range == s.inet4Range && metadata.Inet6Range == s.inet6Range {
s.inet4Current = metadata.Inet4Current
s.inet6Current = metadata.Inet6Current
} else {
if s.inet4Range.IsValid() {
s.inet4Current = s.inet4Range.Addr().Next().Next()
}
if s.inet6Range.IsValid() {
s.inet6Current = s.inet6Range.Addr().Next().Next()
}
2023-07-19 12:40:34 +00:00
_ = storage.FakeIPReset()
2023-03-25 04:03:23 +00:00
}
s.storage = storage
return nil
}
func (s *Store) Contains(address netip.Addr) bool {
return s.inet4Range.Contains(address) || s.inet6Range.Contains(address)
}
func (s *Store) Close() error {
if s.storage == nil {
return nil
}
return s.storage.FakeIPSaveMetadata(&adapter.FakeIPMetadata{
Inet4Range: s.inet4Range,
Inet6Range: s.inet6Range,
Inet4Current: s.inet4Current,
Inet6Current: s.inet6Current,
})
}
2023-07-11 06:05:14 +00:00
func (s *Store) Create(domain string, isIPv6 bool) (netip.Addr, error) {
if address, loaded := s.storage.FakeIPLoadDomain(domain, isIPv6); loaded {
return address, nil
}
2023-03-25 04:03:23 +00:00
var address netip.Addr
2023-07-11 06:05:14 +00:00
if !isIPv6 {
2023-03-25 04:03:23 +00:00
if !s.inet4Current.IsValid() {
return netip.Addr{}, E.New("missing IPv4 fakeip address range")
}
nextAddress := s.inet4Current.Next()
if !s.inet4Range.Contains(nextAddress) {
nextAddress = s.inet4Range.Addr().Next().Next()
}
s.inet4Current = nextAddress
address = nextAddress
} else {
if !s.inet6Current.IsValid() {
return netip.Addr{}, E.New("missing IPv6 fakeip address range")
}
nextAddress := s.inet6Current.Next()
if !s.inet6Range.Contains(nextAddress) {
nextAddress = s.inet6Range.Addr().Next().Next()
}
s.inet6Current = nextAddress
address = nextAddress
}
2023-07-08 08:08:46 +00:00
s.storage.FakeIPStoreAsync(address, domain, s.logger)
2023-08-07 13:53:19 +00:00
s.storage.FakeIPSaveMetadataAsync(&adapter.FakeIPMetadata{
Inet4Range: s.inet4Range,
Inet6Range: s.inet6Range,
Inet4Current: s.inet4Current,
Inet6Current: s.inet6Current,
})
2023-03-25 04:03:23 +00:00
return address, nil
}
func (s *Store) Lookup(address netip.Addr) (string, bool) {
return s.storage.FakeIPLoad(address)
}
func (s *Store) Reset() error {
return s.storage.FakeIPReset()
}