2021-10-11 12:48:58 +00:00
|
|
|
package fakeip
|
|
|
|
|
|
|
|
import (
|
2022-04-11 16:31:04 +00:00
|
|
|
"net/netip"
|
2021-10-11 12:48:58 +00:00
|
|
|
|
|
|
|
"github.com/Dreamacro/clash/common/cache"
|
|
|
|
)
|
|
|
|
|
|
|
|
type memoryStore struct {
|
2022-04-11 16:31:04 +00:00
|
|
|
cacheIP *cache.LruCache[string, netip.Addr]
|
|
|
|
cacheHost *cache.LruCache[netip.Addr, string]
|
2021-10-11 12:48:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetByHost implements store.GetByHost
|
2022-04-11 16:31:04 +00:00
|
|
|
func (m *memoryStore) GetByHost(host string) (netip.Addr, bool) {
|
2022-04-05 12:23:16 +00:00
|
|
|
if ip, exist := m.cacheIP.Get(host); exist {
|
2021-10-11 12:48:58 +00:00
|
|
|
// ensure ip --> host on head of linked list
|
2022-04-11 16:31:04 +00:00
|
|
|
m.cacheHost.Get(ip)
|
2021-10-11 12:48:58 +00:00
|
|
|
return ip, true
|
|
|
|
}
|
|
|
|
|
2022-04-11 16:31:04 +00:00
|
|
|
return netip.Addr{}, false
|
2021-10-11 12:48:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// PutByHost implements store.PutByHost
|
2022-04-11 16:31:04 +00:00
|
|
|
func (m *memoryStore) PutByHost(host string, ip netip.Addr) {
|
2022-04-05 12:23:16 +00:00
|
|
|
m.cacheIP.Set(host, ip)
|
2021-10-11 12:48:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetByIP implements store.GetByIP
|
2022-04-11 16:31:04 +00:00
|
|
|
func (m *memoryStore) GetByIP(ip netip.Addr) (string, bool) {
|
|
|
|
if host, exist := m.cacheHost.Get(ip); exist {
|
2021-10-11 12:48:58 +00:00
|
|
|
// ensure host --> ip on head of linked list
|
2022-04-05 12:23:16 +00:00
|
|
|
m.cacheIP.Get(host)
|
2021-10-11 12:48:58 +00:00
|
|
|
return host, true
|
|
|
|
}
|
|
|
|
|
|
|
|
return "", false
|
|
|
|
}
|
|
|
|
|
|
|
|
// PutByIP implements store.PutByIP
|
2022-04-11 16:31:04 +00:00
|
|
|
func (m *memoryStore) PutByIP(ip netip.Addr, host string) {
|
|
|
|
m.cacheHost.Set(ip, host)
|
2021-10-11 12:48:58 +00:00
|
|
|
}
|
|
|
|
|
2021-11-23 14:01:49 +00:00
|
|
|
// DelByIP implements store.DelByIP
|
2022-04-11 16:31:04 +00:00
|
|
|
func (m *memoryStore) DelByIP(ip netip.Addr) {
|
|
|
|
if host, exist := m.cacheHost.Get(ip); exist {
|
2022-04-05 12:23:16 +00:00
|
|
|
m.cacheIP.Delete(host)
|
2021-11-23 14:01:49 +00:00
|
|
|
}
|
2022-04-11 16:31:04 +00:00
|
|
|
m.cacheHost.Delete(ip)
|
2021-11-23 14:01:49 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 12:48:58 +00:00
|
|
|
// Exist implements store.Exist
|
2022-04-11 16:31:04 +00:00
|
|
|
func (m *memoryStore) Exist(ip netip.Addr) bool {
|
|
|
|
return m.cacheHost.Exist(ip)
|
2021-10-11 12:48:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// CloneTo implements store.CloneTo
|
|
|
|
// only for memoryStore to memoryStore
|
|
|
|
func (m *memoryStore) CloneTo(store store) {
|
|
|
|
if ms, ok := store.(*memoryStore); ok {
|
2022-04-05 12:23:16 +00:00
|
|
|
m.cacheIP.CloneTo(ms.cacheIP)
|
|
|
|
m.cacheHost.CloneTo(ms.cacheHost)
|
2021-10-11 12:48:58 +00:00
|
|
|
}
|
|
|
|
}
|
2022-03-22 17:05:43 +00:00
|
|
|
|
|
|
|
// FlushFakeIP implements store.FlushFakeIP
|
|
|
|
func (m *memoryStore) FlushFakeIP() error {
|
2022-04-05 12:23:16 +00:00
|
|
|
_ = m.cacheIP.Clear()
|
|
|
|
return m.cacheHost.Clear()
|
|
|
|
}
|
|
|
|
|
|
|
|
func newMemoryStore(size int) *memoryStore {
|
|
|
|
return &memoryStore{
|
2022-11-12 12:43:48 +00:00
|
|
|
cacheIP: cache.New[string, netip.Addr](cache.WithSize[string, netip.Addr](size)),
|
|
|
|
cacheHost: cache.New[netip.Addr, string](cache.WithSize[netip.Addr, string](size)),
|
2022-04-05 12:23:16 +00:00
|
|
|
}
|
2022-03-22 17:05:43 +00:00
|
|
|
}
|