github.com/v2fly/v2ray-core/v4@v4.45.2/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 12 "github.com/v2fly/v2ray-core/v4/common" 13 "github.com/v2fly/v2ray-core/v4/common/cache" 14 "github.com/v2fly/v2ray-core/v4/common/net" 15 "github.com/v2fly/v2ray-core/v4/features/dns" 16 ) 17 18 type Holder struct { 19 domainToIP cache.Lru 20 nextIP *big.Int 21 22 ipRange *gonet.IPNet 23 24 config *FakeDnsPool 25 } 26 27 func (fkdns *Holder) IsIPInIPPool(ip net.Address) bool { 28 if ip.Family().IsDomain() { 29 return false 30 } 31 return fkdns.ipRange.Contains(ip.IP()) 32 } 33 34 func (fkdns *Holder) GetFakeIPForDomain3(domain string, ipv4, ipv6 bool) []net.Address { 35 isIPv6 := fkdns.ipRange.IP.To4() == nil 36 if (isIPv6 && ipv6) || (!isIPv6 && ipv4) { 37 return fkdns.GetFakeIPForDomain(domain) 38 } 39 return []net.Address{} 40 } 41 42 func (*Holder) Type() interface{} { 43 return (*dns.FakeDNSEngine)(nil) 44 } 45 46 func (fkdns *Holder) Start() error { 47 if fkdns.config != nil && fkdns.config.IpPool != "" && fkdns.config.LruSize != 0 { 48 return fkdns.initializeFromConfig() 49 } 50 return newError("invalid fakeDNS setting") 51 } 52 53 func (fkdns *Holder) Close() error { 54 fkdns.domainToIP = nil 55 fkdns.nextIP = nil 56 fkdns.ipRange = nil 57 return nil 58 } 59 60 func NewFakeDNSHolder() (*Holder, error) { 61 var fkdns *Holder 62 var err error 63 64 if fkdns, err = NewFakeDNSHolderConfigOnly(nil); err != nil { 65 return nil, newError("Unable to create Fake Dns Engine").Base(err).AtError() 66 } 67 err = fkdns.initialize("198.18.0.0/15", 65535) 68 if err != nil { 69 return nil, err 70 } 71 return fkdns, nil 72 } 73 74 func NewFakeDNSHolderConfigOnly(conf *FakeDnsPool) (*Holder, error) { 75 return &Holder{nil, nil, nil, conf}, nil 76 } 77 78 func (fkdns *Holder) initializeFromConfig() error { 79 return fkdns.initialize(fkdns.config.IpPool, int(fkdns.config.LruSize)) 80 } 81 82 func (fkdns *Holder) initialize(ipPoolCidr string, lruSize int) error { 83 var ipRange *gonet.IPNet 84 var ipaddr gonet.IP 85 var currentIP *big.Int 86 var err error 87 88 if ipaddr, ipRange, err = gonet.ParseCIDR(ipPoolCidr); err != nil { 89 return newError("Unable to parse CIDR for Fake DNS IP assignment").Base(err).AtError() 90 } 91 92 currentIP = big.NewInt(0).SetBytes(ipaddr) 93 if ipaddr.To4() != nil { 94 currentIP = big.NewInt(0).SetBytes(ipaddr.To4()) 95 } 96 97 ones, bits := ipRange.Mask.Size() 98 rooms := bits - ones 99 if math.Log2(float64(lruSize)) >= float64(rooms) { 100 return newError("LRU size is bigger than subnet size").AtError() 101 } 102 fkdns.domainToIP = cache.NewLru(lruSize) 103 fkdns.ipRange = ipRange 104 fkdns.nextIP = currentIP 105 return nil 106 } 107 108 // GetFakeIPForDomain check and generate a fake IP for a domain name 109 func (fkdns *Holder) GetFakeIPForDomain(domain string) []net.Address { 110 if v, ok := fkdns.domainToIP.Get(domain); ok { 111 return []net.Address{v.(net.Address)} 112 } 113 var ip net.Address 114 for { 115 ip = net.IPAddress(fkdns.nextIP.Bytes()) 116 117 fkdns.nextIP = fkdns.nextIP.Add(fkdns.nextIP, big.NewInt(1)) 118 if !fkdns.ipRange.Contains(fkdns.nextIP.Bytes()) { 119 fkdns.nextIP = big.NewInt(0).SetBytes(fkdns.ipRange.IP) 120 } 121 122 // if we run for a long time, we may go back to beginning and start seeing the IP in use 123 if _, ok := fkdns.domainToIP.GetKeyFromValue(ip); !ok { 124 break 125 } 126 } 127 fkdns.domainToIP.Put(domain, ip) 128 return []net.Address{ip} 129 } 130 131 // GetDomainFromFakeDNS check if an IP is a fake IP and have corresponding domain name 132 func (fkdns *Holder) GetDomainFromFakeDNS(ip net.Address) string { 133 if !ip.Family().IsIP() || !fkdns.ipRange.Contains(ip.IP()) { 134 return "" 135 } 136 if k, ok := fkdns.domainToIP.GetKeyFromValue(ip); ok { 137 return k.(string) 138 } 139 return "" 140 } 141 142 type HolderMulti struct { 143 holders []*Holder 144 145 config *FakeDnsPoolMulti 146 } 147 148 func (h *HolderMulti) IsIPInIPPool(ip net.Address) bool { 149 if ip.Family().IsDomain() { 150 return false 151 } 152 for _, v := range h.holders { 153 if v.IsIPInIPPool(ip) { 154 return true 155 } 156 } 157 return false 158 } 159 160 func (h *HolderMulti) GetFakeIPForDomain3(domain string, ipv4, ipv6 bool) []net.Address { 161 var ret []net.Address 162 for _, v := range h.holders { 163 ret = append(ret, v.GetFakeIPForDomain3(domain, ipv4, ipv6)...) 164 } 165 return ret 166 } 167 168 func (h *HolderMulti) GetFakeIPForDomain(domain string) []net.Address { 169 var ret []net.Address 170 for _, v := range h.holders { 171 ret = append(ret, v.GetFakeIPForDomain(domain)...) 172 } 173 return ret 174 } 175 176 func (h *HolderMulti) GetDomainFromFakeDNS(ip net.Address) string { 177 for _, v := range h.holders { 178 if domain := v.GetDomainFromFakeDNS(ip); domain != "" { 179 return domain 180 } 181 } 182 return "" 183 } 184 185 func (h *HolderMulti) Type() interface{} { 186 return (*dns.FakeDNSEngine)(nil) 187 } 188 189 func (h *HolderMulti) Start() error { 190 for _, v := range h.holders { 191 if v.config != nil && v.config.IpPool != "" && v.config.LruSize != 0 { 192 if err := v.Start(); err != nil { 193 return newError("Cannot start all fake dns pools").Base(err) 194 } 195 } else { 196 return newError("invalid fakeDNS setting") 197 } 198 } 199 return nil 200 } 201 202 func (h *HolderMulti) Close() error { 203 for _, v := range h.holders { 204 if err := v.Close(); err != nil { 205 return newError("Cannot close all fake dns pools").Base(err) 206 } 207 } 208 return nil 209 } 210 211 func (h *HolderMulti) createHolderGroups() error { 212 for _, v := range h.config.Pools { 213 holder, err := NewFakeDNSHolderConfigOnly(v) 214 if err != nil { 215 return err 216 } 217 h.holders = append(h.holders, holder) 218 } 219 return nil 220 } 221 222 func NewFakeDNSHolderMulti(conf *FakeDnsPoolMulti) (*HolderMulti, error) { 223 holderMulti := &HolderMulti{nil, conf} 224 if err := holderMulti.createHolderGroups(); err != nil { 225 return nil, err 226 } 227 return holderMulti, nil 228 } 229 230 func init() { 231 common.Must(common.RegisterConfig((*FakeDnsPool)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { 232 var f *Holder 233 var err error 234 if f, err = NewFakeDNSHolderConfigOnly(config.(*FakeDnsPool)); err != nil { 235 return nil, err 236 } 237 return f, nil 238 })) 239 240 common.Must(common.RegisterConfig((*FakeDnsPoolMulti)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { 241 var f *HolderMulti 242 var err error 243 if f, err = NewFakeDNSHolderMulti(config.(*FakeDnsPoolMulti)); err != nil { 244 return nil, err 245 } 246 return f, nil 247 })) 248 }