diff --git a/common/nnip/netip.go b/common/nnip/netip.go new file mode 100644 index 00000000..e4566138 --- /dev/null +++ b/common/nnip/netip.go @@ -0,0 +1,53 @@ +package nnip + +import ( + "encoding/binary" + "net" + "net/netip" +) + +// IpToAddr converts the net.IP to netip.Addr. +// If slice's length is not 4 or 16, IpToAddr returns netip.Addr{} +func IpToAddr(slice net.IP) netip.Addr { + ip := slice + if len(ip) != 4 { + if ip = slice.To4(); ip == nil { + ip = slice + } + } + + if addr, ok := netip.AddrFromSlice(ip); ok { + return addr + } + return netip.Addr{} +} + +// UnMasked returns p's last IP address. +// If p is invalid, UnMasked returns netip.Addr{} +func UnMasked(p netip.Prefix) netip.Addr { + if !p.IsValid() { + return netip.Addr{} + } + + buf := p.Addr().As16() + + hi := binary.BigEndian.Uint64(buf[:8]) + lo := binary.BigEndian.Uint64(buf[8:]) + + bits := p.Bits() + if bits <= 32 { + bits += 96 + } + + hi = hi | ^uint64(0)>>bits + lo = lo | ^(^uint64(0) << (128 - bits)) + + binary.BigEndian.PutUint64(buf[:8], hi) + binary.BigEndian.PutUint64(buf[8:], lo) + + addr := netip.AddrFrom16(buf) + if p.Addr().Is4() { + return addr.Unmap() + } + return addr +} diff --git a/component/fakeip/pool.go b/component/fakeip/pool.go index 57613a48..0137f705 100644 --- a/component/fakeip/pool.go +++ b/component/fakeip/pool.go @@ -1,12 +1,11 @@ package fakeip import ( - "encoding/binary" "errors" - "math/bits" "net/netip" "sync" + "github.com/Dreamacro/clash/common/nnip" "github.com/Dreamacro/clash/component/profile/cachefile" "github.com/Dreamacro/clash/component/trie" ) @@ -16,11 +15,6 @@ const ( cycleKey = "key-cycle-fake-ip" ) -type uint128 struct { - hi uint64 - lo uint64 -} - type store interface { GetByHost(host string) (netip.Addr, bool) PutByHost(host string, ip netip.Addr) @@ -122,7 +116,7 @@ func (p *Pool) FlushFakeIP() error { err := p.store.FlushFakeIP() if err == nil { p.cycle = false - p.offset = p.first + p.offset = p.first.Prev() } return err } @@ -173,10 +167,10 @@ func New(options Options) (*Pool, error) { hostAddr = options.IPNet.Masked().Addr() gateway = hostAddr.Next() first = gateway.Next().Next() - last = add(hostAddr, 1<