2020-09-17 10:48:42 +08:00
|
|
|
package dns
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net"
|
2022-04-12 00:31:04 +08:00
|
|
|
"net/netip"
|
2020-09-17 10:48:42 +08:00
|
|
|
|
|
|
|
"github.com/Dreamacro/clash/common/cache"
|
2022-04-19 17:46:13 +08:00
|
|
|
"github.com/Dreamacro/clash/common/nnip"
|
2020-09-17 10:48:42 +08:00
|
|
|
"github.com/Dreamacro/clash/component/fakeip"
|
2021-10-18 21:08:27 +08:00
|
|
|
C "github.com/Dreamacro/clash/constant"
|
2020-09-17 10:48:42 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type ResolverEnhancer struct {
|
2021-10-18 21:08:27 +08:00
|
|
|
mode C.DNSMode
|
2020-09-17 10:48:42 +08:00
|
|
|
fakePool *fakeip.Pool
|
2022-04-12 00:31:04 +08:00
|
|
|
mapping *cache.LruCache[netip.Addr, string]
|
2020-09-17 10:48:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (h *ResolverEnhancer) FakeIPEnabled() bool {
|
2021-10-18 21:08:27 +08:00
|
|
|
return h.mode == C.DNSFakeIP
|
2020-09-17 10:48:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (h *ResolverEnhancer) MappingEnabled() bool {
|
2021-10-18 21:08:27 +08:00
|
|
|
return h.mode == C.DNSFakeIP || h.mode == C.DNSMapping
|
2020-09-17 10:48:42 +08:00
|
|
|
}
|
|
|
|
|
2020-10-17 12:52:43 +08:00
|
|
|
func (h *ResolverEnhancer) IsExistFakeIP(ip net.IP) bool {
|
2020-09-17 10:48:42 +08:00
|
|
|
if !h.FakeIPEnabled() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
if pool := h.fakePool; pool != nil {
|
2022-04-19 17:46:13 +08:00
|
|
|
return pool.Exist(nnip.IpToAddr(ip))
|
2020-09-17 10:48:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2020-10-17 12:52:43 +08:00
|
|
|
func (h *ResolverEnhancer) IsFakeIP(ip net.IP) bool {
|
|
|
|
if !h.FakeIPEnabled() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-04-19 17:46:13 +08:00
|
|
|
addr := nnip.IpToAddr(ip)
|
2022-04-12 00:31:04 +08:00
|
|
|
|
2020-10-17 12:52:43 +08:00
|
|
|
if pool := h.fakePool; pool != nil {
|
2022-04-12 00:31:04 +08:00
|
|
|
return pool.IPNet().Contains(addr) && addr != pool.Gateway() && addr != pool.Broadcast()
|
2022-03-15 02:43:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *ResolverEnhancer) IsFakeBroadcastIP(ip net.IP) bool {
|
|
|
|
if !h.FakeIPEnabled() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
if pool := h.fakePool; pool != nil {
|
2022-04-19 17:46:13 +08:00
|
|
|
return pool.Broadcast() == nnip.IpToAddr(ip)
|
2020-10-17 12:52:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2020-09-17 10:48:42 +08:00
|
|
|
func (h *ResolverEnhancer) FindHostByIP(ip net.IP) (string, bool) {
|
2022-04-19 17:46:13 +08:00
|
|
|
addr := nnip.IpToAddr(ip)
|
2020-09-17 10:48:42 +08:00
|
|
|
if pool := h.fakePool; pool != nil {
|
2022-04-12 00:31:04 +08:00
|
|
|
if host, existed := pool.LookBack(addr); existed {
|
2020-09-17 10:48:42 +08:00
|
|
|
return host, true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if mapping := h.mapping; mapping != nil {
|
2022-04-12 00:31:04 +08:00
|
|
|
if host, existed := h.mapping.Get(addr); existed {
|
2022-04-05 20:23:16 +08:00
|
|
|
return host, true
|
2020-09-17 10:48:42 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return "", false
|
|
|
|
}
|
|
|
|
|
2022-03-30 23:54:52 +08:00
|
|
|
func (h *ResolverEnhancer) InsertHostByIP(ip net.IP, host string) {
|
|
|
|
if mapping := h.mapping; mapping != nil {
|
2022-04-19 17:46:13 +08:00
|
|
|
h.mapping.Set(nnip.IpToAddr(ip), host)
|
2022-03-30 23:54:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-13 05:55:08 +08:00
|
|
|
func (h *ResolverEnhancer) FlushFakeIP() error {
|
|
|
|
if h.fakePool != nil {
|
|
|
|
return h.fakePool.FlushFakeIP()
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-09-17 10:48:42 +08:00
|
|
|
func (h *ResolverEnhancer) PatchFrom(o *ResolverEnhancer) {
|
|
|
|
if h.mapping != nil && o.mapping != nil {
|
|
|
|
o.mapping.CloneTo(h.mapping)
|
|
|
|
}
|
|
|
|
|
|
|
|
if h.fakePool != nil && o.fakePool != nil {
|
2021-10-11 20:48:58 +08:00
|
|
|
h.fakePool.CloneFrom(o.fakePool)
|
2020-09-17 10:48:42 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-13 16:47:47 +08:00
|
|
|
func (h *ResolverEnhancer) StoreFakePoolState() {
|
2022-03-23 01:05:43 +08:00
|
|
|
if h.fakePool != nil {
|
2022-04-13 05:55:08 +08:00
|
|
|
h.fakePool.StoreState()
|
2022-03-23 01:05:43 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-17 10:48:42 +08:00
|
|
|
func NewEnhancer(cfg Config) *ResolverEnhancer {
|
|
|
|
var fakePool *fakeip.Pool
|
2022-04-12 00:31:04 +08:00
|
|
|
var mapping *cache.LruCache[netip.Addr, string]
|
2020-09-17 10:48:42 +08:00
|
|
|
|
2021-10-18 21:08:27 +08:00
|
|
|
if cfg.EnhancedMode != C.DNSNormal {
|
2020-09-17 10:48:42 +08:00
|
|
|
fakePool = cfg.Pool
|
2022-04-12 00:31:04 +08:00
|
|
|
mapping = cache.NewLRUCache[netip.Addr, string](cache.WithSize[netip.Addr, string](4096), cache.WithStale[netip.Addr, string](true))
|
2020-09-17 10:48:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return &ResolverEnhancer{
|
|
|
|
mode: cfg.EnhancedMode,
|
|
|
|
fakePool: fakePool,
|
|
|
|
mapping: mapping,
|
|
|
|
}
|
|
|
|
}
|