Add fakeip support
This commit is contained in:
108
transport/fakeip/store.go
Normal file
108
transport/fakeip/store.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package fakeip
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-dns"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
var _ adapter.FakeIPStore = (*Store)(nil)
|
||||
|
||||
type Store struct {
|
||||
router adapter.Router
|
||||
inet4Range netip.Prefix
|
||||
inet6Range netip.Prefix
|
||||
storage adapter.FakeIPStorage
|
||||
inet4Current netip.Addr
|
||||
inet6Current netip.Addr
|
||||
}
|
||||
|
||||
func NewStore(router adapter.Router, inet4Range netip.Prefix, inet6Range netip.Prefix) *Store {
|
||||
return &Store{
|
||||
router: router,
|
||||
inet4Range: inet4Range,
|
||||
inet6Range: inet6Range,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Store) Start() error {
|
||||
var storage adapter.FakeIPStorage
|
||||
if clashServer := s.router.ClashServer(); clashServer != nil && clashServer.StoreFakeIP() {
|
||||
if cacheFile := clashServer.CacheFile(); cacheFile != nil {
|
||||
storage = cacheFile
|
||||
}
|
||||
}
|
||||
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()
|
||||
}
|
||||
}
|
||||
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,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Store) Create(domain string, strategy dns.DomainStrategy) (netip.Addr, error) {
|
||||
var address netip.Addr
|
||||
if strategy == dns.DomainStrategyUseIPv4 {
|
||||
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
|
||||
}
|
||||
err := s.storage.FakeIPStore(address, domain)
|
||||
if err != nil {
|
||||
return netip.Addr{}, err
|
||||
}
|
||||
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()
|
||||
}
|
||||
Reference in New Issue
Block a user