github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/app/dns/fakedns/fake.go (about) 1 //go:build !confonly 2 // +build !confonly 3 4 package fakedns 5 6 import ( 7 "context" 8 "math" 9 "math/big" 10 gonet "net" 11 "sync" 12 13 "github.com/v2fly/v2ray-core/v5/common" 14 "github.com/v2fly/v2ray-core/v5/common/cache" 15 "github.com/v2fly/v2ray-core/v5/common/net" 16 "github.com/v2fly/v2ray-core/v5/features/dns" 17 ) 18 19 type Holder struct { 20 domainToIP cache.Lru 21 nextIP *big.Int 22 mu *sync.Mutex 23 24 ipRange *gonet.IPNet 25 26 config *FakeDnsPool 27 } 28 29 func (fkdns *Holder) IsIPInIPPool(ip net.Address) bool { 30 if ip.Family().IsDomain() { 31 return false 32 } 33 return fkdns.ipRange.Contains(ip.IP()) 34 } 35 36 func (fkdns *Holder) GetFakeIPForDomain3(domain string, ipv4, ipv6 bool) []net.Address { 37 isIPv6 := fkdns.ipRange.IP.To4() == nil 38 if (isIPv6 && ipv6) || (!isIPv6 && ipv4) { 39 return fkdns.GetFakeIPForDomain(domain) 40 } 41 return []net.Address{} 42 } 43 44 func (*Holder) Type() interface{} { 45 return dns.FakeDNSEngineType() 46 } 47 48 func (fkdns *Holder) Start() error { 49 if fkdns.config != nil && fkdns.config.IpPool != "" && fkdns.config.LruSize != 0 { 50 return fkdns.initializeFromConfig() 51 } 52 return newError("invalid fakeDNS setting") 53 } 54 55 func (fkdns *Holder) Close() error { 56 fkdns.domainToIP = nil 57 fkdns.nextIP = nil 58 fkdns.ipRange = nil 59 fkdns.mu = nil 60 return nil 61 } 62 63 func NewFakeDNSHolder() (*Holder, error) { 64 var fkdns *Holder 65 var err error 66 67 if fkdns, err = NewFakeDNSHolderConfigOnly(nil); err != nil { 68 return nil, newError("Unable to create Fake Dns Engine").Base(err).AtError() 69 } 70 err = fkdns.initialize("198.18.0.0/15", 65535) 71 if err != nil { 72 return nil, err 73 } 74 return fkdns, nil 75 } 76 77 func NewFakeDNSHolderConfigOnly(conf *FakeDnsPool) (*Holder, error) { 78 return &Holder{nil, nil, nil, nil, conf}, nil 79 } 80 81 func (fkdns *Holder) initializeFromConfig() error { 82 return fkdns.initialize(fkdns.config.IpPool, int(fkdns.config.LruSize)) 83 } 84 85 func (fkdns *Holder) initialize(ipPoolCidr string, lruSize int) error { 86 var ipRange *gonet.IPNet 87 var ipaddr gonet.IP 88 var currentIP *big.Int 89 var err error 90 91 if ipaddr, ipRange, err = gonet.ParseCIDR(ipPoolCidr); err != nil { 92 return newError("Unable to parse CIDR for Fake DNS IP assignment").Base(err).AtError() 93 } 94 95 currentIP = big.NewInt(0).SetBytes(ipaddr) 96 if ipaddr.To4() != nil { 97 currentIP = big.NewInt(0).SetBytes(ipaddr.To4()) 98 } 99 100 ones, bits := ipRange.Mask.Size() 101 rooms := bits - ones 102 if math.Log2(float64(lruSize)) >= float64(rooms) { 103 return newError("LRU size is bigger than subnet size").AtError() 104 } 105 fkdns.domainToIP = cache.NewLru(lruSize) 106 fkdns.ipRange = ipRange 107 fkdns.nextIP = currentIP 108 fkdns.mu = new(sync.Mutex) 109 return nil 110 } 111 112 // GetFakeIPForDomain checks and generate a fake IP for a domain name 113 func (fkdns *Holder) GetFakeIPForDomain(domain string) []net.Address { 114 fkdns.mu.Lock() 115 defer fkdns.mu.Unlock() 116 if v, ok := fkdns.domainToIP.Get(domain); ok { 117 return []net.Address{v.(net.Address)} 118 } 119 var ip net.Address 120 for { 121 ip = net.IPAddress(fkdns.nextIP.Bytes()) 122 123 fkdns.nextIP = fkdns.nextIP.Add(fkdns.nextIP, big.NewInt(1)) 124 if !fkdns.ipRange.Contains(fkdns.nextIP.Bytes()) { 125 fkdns.nextIP = big.NewInt(0).SetBytes(fkdns.ipRange.IP) 126 } 127 128 // if we run for a long time, we may go back to beginning and start seeing the IP in use 129 if _, ok := fkdns.domainToIP.GetKeyFromValue(ip); !ok { 130 break 131 } 132 } 133 fkdns.domainToIP.Put(domain, ip) 134 return []net.Address{ip} 135 } 136 137 // GetDomainFromFakeDNS checks if an IP is a fake IP and have corresponding domain name 138 func (fkdns *Holder) GetDomainFromFakeDNS(ip net.Address) string { 139 if !ip.Family().IsIP() || !fkdns.ipRange.Contains(ip.IP()) { 140 return "" 141 } 142 if k, ok := fkdns.domainToIP.GetKeyFromValue(ip); ok { 143 return k.(string) 144 } 145 return "" 146 } 147 148 type HolderMulti struct { 149 holders []*Holder 150 } 151 152 func (h *HolderMulti) IsIPInIPPool(ip net.Address) bool { 153 if ip.Family().IsDomain() { 154 return false 155 } 156 for _, v := range h.holders { 157 if v.IsIPInIPPool(ip) { 158 return true 159 } 160 } 161 return false 162 } 163 164 func (h *HolderMulti) GetFakeIPForDomain3(domain string, ipv4, ipv6 bool) []net.Address { 165 var ret []net.Address 166 for _, v := range h.holders { 167 ret = append(ret, v.GetFakeIPForDomain3(domain, ipv4, ipv6)...) 168 } 169 return ret 170 } 171 172 func (h *HolderMulti) GetFakeIPForDomain(domain string) []net.Address { 173 var ret []net.Address 174 for _, v := range h.holders { 175 ret = append(ret, v.GetFakeIPForDomain(domain)...) 176 } 177 return ret 178 } 179 180 func (h *HolderMulti) GetDomainFromFakeDNS(ip net.Address) string { 181 for _, v := range h.holders { 182 if domain := v.GetDomainFromFakeDNS(ip); domain != "" { 183 return domain 184 } 185 } 186 return "" 187 } 188 189 func (h *HolderMulti) IsEmpty() bool { 190 return len(h.holders) == 0 191 } 192 193 func (h *HolderMulti) AddPool(poolConfig *FakeDnsPool) (*Holder, error) { 194 _, newIPRange, err := gonet.ParseCIDR(poolConfig.IpPool) 195 if err != nil { 196 return nil, err 197 } 198 running := false 199 for _, v := range h.holders { 200 var ipRange *gonet.IPNet 201 if v.ipRange != nil { 202 ipRange = v.ipRange 203 running = true 204 } else { 205 _, ipRange, err = gonet.ParseCIDR(v.config.IpPool) 206 if err != nil { 207 return nil, err 208 } 209 } 210 if ipRange.String() == newIPRange.String() { 211 return v, nil 212 } 213 if ipRange.Contains(newIPRange.IP) || newIPRange.Contains(ipRange.IP) { 214 return nil, newError("Trying to add ip pool ", newIPRange, " that overlaps with existing ip pool ", ipRange) 215 } 216 } 217 holder, err := NewFakeDNSHolderConfigOnly(poolConfig) 218 if err != nil { 219 return nil, err 220 } 221 if running { 222 if err := holder.Start(); err != nil { 223 return nil, err 224 } 225 } 226 h.holders = append(h.holders, holder) 227 return holder, nil 228 } 229 230 func (h *HolderMulti) AddPoolMulti(poolMultiConfig *FakeDnsPoolMulti) (*HolderMulti, error) { 231 holderMulti := &HolderMulti{} 232 for _, poolConfig := range poolMultiConfig.Pools { 233 pool, err := h.AddPool(poolConfig) 234 if err != nil { 235 return nil, err 236 } 237 holderMulti.holders = append(holderMulti.holders, pool) 238 } 239 return holderMulti, nil // Returned holderMulti holds references to pools managed by `h` 240 } 241 242 func (h *HolderMulti) Type() interface{} { 243 return dns.FakeDNSEngineType() 244 } 245 246 func (h *HolderMulti) Start() error { 247 for _, v := range h.holders { 248 if err := v.Start(); err != nil { 249 return newError("Cannot start all fake dns pools").Base(err) 250 } 251 } 252 return nil 253 } 254 255 func (h *HolderMulti) Close() error { 256 for _, v := range h.holders { 257 if err := v.Close(); err != nil { 258 return newError("Cannot close all fake dns pools").Base(err) 259 } 260 } 261 return nil 262 } 263 264 func (h *HolderMulti) createHolderGroups(conf *FakeDnsPoolMulti) error { 265 for _, pool := range conf.Pools { 266 _, err := h.AddPool(pool) 267 if err != nil { 268 return err 269 } 270 } 271 return nil 272 } 273 274 func NewFakeDNSHolderMulti(conf *FakeDnsPoolMulti) (*HolderMulti, error) { 275 holderMulti := &HolderMulti{} 276 if err := holderMulti.createHolderGroups(conf); err != nil { 277 return nil, err 278 } 279 return holderMulti, nil 280 } 281 282 func init() { 283 common.Must(common.RegisterConfig((*FakeDnsPool)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { 284 var f *Holder 285 var err error 286 if f, err = NewFakeDNSHolderConfigOnly(config.(*FakeDnsPool)); err != nil { 287 return nil, err 288 } 289 return f, nil 290 })) 291 292 common.Must(common.RegisterConfig((*FakeDnsPoolMulti)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { 293 var f *HolderMulti 294 var err error 295 if f, err = NewFakeDNSHolderMulti(config.(*FakeDnsPoolMulti)); err != nil { 296 return nil, err 297 } 298 return f, nil 299 })) 300 }