diff --git a/README.md b/README.md index 48ed9dc0..485c4314 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ experimental: # enable: true # set true to enable dns (default is false) # ipv6: false # default is false # listen: 0.0.0.0:53 - # enhanced-mode: redir-host + # enhanced-mode: redir-host # or fake-ip # nameserver: # - 114.114.114.114 # - tls://dns.rubyfish.cn:853 # dns over tls diff --git a/component/fakeip/pool.go b/component/fakeip/pool.go new file mode 100644 index 00000000..76c421e3 --- /dev/null +++ b/component/fakeip/pool.go @@ -0,0 +1,50 @@ +package fakeip + +import ( + "errors" + "net" +) + +// Pool is a implementation about fake ip generator without storage +type Pool struct { + max uint32 + min uint32 + offset uint32 +} + +// Get return a new fake ip +func (p *Pool) Get() net.IP { + ip := uintToIP(p.min + p.offset) + p.offset = (p.offset + 1) % (p.max - p.min) + return ip +} + +func ipToUint(ip net.IP) uint32 { + v := uint32(ip[0]) << 24 + v += uint32(ip[1]) << 16 + v += uint32(ip[2]) << 8 + v += uint32(ip[3]) + return v +} + +func uintToIP(v uint32) net.IP { + return net.IPv4(byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) +} + +// New return Pool instance +func New(ipnet *net.IPNet) (*Pool, error) { + min := ipToUint(ipnet.IP) + 1 + + ones, bits := ipnet.Mask.Size() + total := 1<