chore: cleanup netip code

This commit is contained in:
wwqgtxx 2025-04-09 11:39:00 +08:00
parent b2d2890866
commit cac2bf72e1
10 changed files with 48 additions and 109 deletions

View file

@ -7,7 +7,6 @@ import (
"strconv"
"strings"
"github.com/metacubex/mihomo/common/nnip"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/transport/socks5"
)
@ -21,13 +20,13 @@ func parseSocksAddr(target socks5.Addr) *C.Metadata {
metadata.Host = strings.TrimRight(string(target[2:2+target[1]]), ".")
metadata.DstPort = uint16((int(target[2+target[1]]) << 8) | int(target[2+target[1]+1]))
case socks5.AtypIPv4:
metadata.DstIP = nnip.IpToAddr(net.IP(target[1 : 1+net.IPv4len]))
metadata.DstIP, _ = netip.AddrFromSlice(target[1 : 1+net.IPv4len])
metadata.DstPort = uint16((int(target[1+net.IPv4len]) << 8) | int(target[1+net.IPv4len+1]))
case socks5.AtypIPv6:
ip6, _ := netip.AddrFromSlice(target[1 : 1+net.IPv6len])
metadata.DstIP = ip6.Unmap()
metadata.DstIP, _ = netip.AddrFromSlice(target[1 : 1+net.IPv6len])
metadata.DstPort = uint16((int(target[1+net.IPv6len]) << 8) | int(target[1+net.IPv6len+1]))
}
metadata.DstIP = metadata.DstIP.Unmap()
return metadata
}

View file

@ -1,73 +0,0 @@
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
}
// PrefixCompare returns an integer comparing two prefixes.
// The result will be 0 if p == p2, -1 if p < p2, and +1 if p > p2.
// modify from https://github.com/golang/go/issues/61642#issuecomment-1848587909
func PrefixCompare(p, p2 netip.Prefix) int {
// compare by validity, address family and prefix base address
if c := p.Masked().Addr().Compare(p2.Masked().Addr()); c != 0 {
return c
}
// compare by prefix length
f1, f2 := p.Bits(), p2.Bits()
if f1 < f2 {
return -1
}
if f1 > f2 {
return 1
}
// compare by prefix address
return p.Addr().Compare(p2.Addr())
}

View file

@ -6,7 +6,6 @@ import (
"net"
"net/netip"
"github.com/metacubex/mihomo/common/nnip"
"github.com/metacubex/mihomo/component/iface"
"github.com/insomniacslk/dhcp/dhcpv4"
@ -86,12 +85,14 @@ func receiveOffer(conn net.PacketConn, id dhcpv4.TransactionID, result chan<- []
return
}
dnsAddr := make([]netip.Addr, l)
for i := 0; i < l; i++ {
dnsAddr[i] = nnip.IpToAddr(dns[i])
results := make([]netip.Addr, 0, len(dns))
for _, ip := range dns {
if addr, ok := netip.AddrFromSlice(ip); ok {
results = append(results, addr.Unmap())
}
}
result <- dnsAddr
result <- results
return
}

View file

@ -6,9 +6,10 @@ import (
"strings"
"sync"
"github.com/metacubex/mihomo/common/nnip"
"github.com/metacubex/mihomo/component/profile/cachefile"
C "github.com/metacubex/mihomo/constant"
"go4.org/netipx"
)
const (
@ -183,7 +184,7 @@ func New(options Options) (*Pool, error) {
hostAddr = options.IPNet.Masked().Addr()
gateway = hostAddr.Next()
first = gateway.Next().Next().Next() // default start with 198.18.0.4
last = nnip.UnMasked(options.IPNet)
last = netipx.PrefixLastIP(options.IPNet)
)
if !options.IPNet.IsValid() || !first.IsValid() || !first.Less(last) {

View file

@ -87,6 +87,7 @@ func findProcessName(network string, ip netip.Addr, port int) (uint32, string, e
default:
continue
}
srcIP = srcIP.Unmap()
if ip == srcIP {
// xsocket_n.so_last_pid

View file

@ -10,7 +10,6 @@ import (
"syscall"
"unsafe"
"github.com/metacubex/mihomo/common/nnip"
"github.com/metacubex/mihomo/log"
)
@ -136,13 +135,14 @@ func (s *searcher) Search(buf []byte, ip netip.Addr, port uint16, isTCP bool) (u
switch {
case flag&0x1 > 0 && isIPv4:
// ipv4
srcIP = nnip.IpToAddr(buf[inp+s.ip : inp+s.ip+4])
srcIP, _ = netip.AddrFromSlice(buf[inp+s.ip : inp+s.ip+4])
case flag&0x2 > 0 && !isIPv4:
// ipv6
srcIP = nnip.IpToAddr(buf[inp+s.ip-12 : inp+s.ip+4])
srcIP, _ = netip.AddrFromSlice(buf[inp+s.ip-12 : inp+s.ip+4])
default:
continue
}
srcIP = srcIP.Unmap()
if ip != srcIP {
continue

View file

@ -7,7 +7,6 @@ import (
"syscall"
"unsafe"
"github.com/metacubex/mihomo/common/nnip"
"github.com/metacubex/mihomo/log"
"golang.org/x/sys/windows"
@ -137,7 +136,8 @@ func (s *searcher) Search(b []byte, ip netip.Addr, port uint16) (uint32, error)
continue
}
srcIP := nnip.IpToAddr(row[s.ip : s.ip+s.ipSize])
srcIP, _ := netip.AddrFromSlice(row[s.ip : s.ip+s.ipSize])
srcIP = srcIP.Unmap()
// windows binds an unbound udp socket to 0.0.0.0/[::] while first sendto
if ip != srcIP && (!srcIP.IsUnspecified() || s.tcpState != -1) {
continue

View file

@ -6,7 +6,6 @@ import (
"time"
"github.com/metacubex/mihomo/common/lru"
"github.com/metacubex/mihomo/common/nnip"
"github.com/metacubex/mihomo/component/fakeip"
R "github.com/metacubex/mihomo/component/resolver"
C "github.com/metacubex/mihomo/constant"
@ -120,14 +119,21 @@ func withMapping(mapping *lru.LruCache[netip.Addr, string]) middleware {
switch a := ans.(type) {
case *D.A:
ip = nnip.IpToAddr(a.A)
ip, _ = netip.AddrFromSlice(a.A)
ttl = a.Hdr.Ttl
case *D.AAAA:
ip = nnip.IpToAddr(a.AAAA)
ip, _ = netip.AddrFromSlice(a.AAAA)
ttl = a.Hdr.Ttl
default:
continue
}
if !ip.IsValid() {
continue
}
if !ip.IsGlobalUnicast() {
continue
}
ip = ip.Unmap()
if ttl < 1 {
ttl = 1

View file

@ -10,7 +10,6 @@ import (
"strings"
"time"
"github.com/metacubex/mihomo/common/nnip"
"github.com/metacubex/mihomo/common/picker"
"github.com/metacubex/mihomo/component/dialer"
"github.com/metacubex/mihomo/component/resolver"
@ -150,19 +149,24 @@ func handleMsgWithEmptyAnswer(r *D.Msg) *D.Msg {
return msg
}
func msgToIP(msg *D.Msg) []netip.Addr {
ips := []netip.Addr{}
func msgToIP(msg *D.Msg) (ips []netip.Addr) {
for _, answer := range msg.Answer {
var ip netip.Addr
switch ans := answer.(type) {
case *D.AAAA:
ips = append(ips, nnip.IpToAddr(ans.AAAA))
ip, _ = netip.AddrFromSlice(ans.AAAA)
case *D.A:
ips = append(ips, nnip.IpToAddr(ans.A))
ip, _ = netip.AddrFromSlice(ans.A)
default:
continue
}
if !ip.IsValid() {
continue
}
ip = ip.Unmap()
ips = append(ips, ip)
}
return ips
return
}
func msgToDomain(msg *D.Msg) string {

View file

@ -3,9 +3,9 @@ package config
import (
"net/netip"
"github.com/metacubex/mihomo/common/nnip"
C "github.com/metacubex/mihomo/constant"
"go4.org/netipx"
"golang.org/x/exp/slices"
)
@ -70,11 +70,11 @@ type Tun struct {
func (t *Tun) Sort() {
slices.Sort(t.DNSHijack)
slices.SortFunc(t.Inet4Address, nnip.PrefixCompare)
slices.SortFunc(t.Inet6Address, nnip.PrefixCompare)
slices.SortFunc(t.RouteAddress, nnip.PrefixCompare)
slices.SortFunc(t.Inet4Address, netipx.ComparePrefix)
slices.SortFunc(t.Inet6Address, netipx.ComparePrefix)
slices.SortFunc(t.RouteAddress, netipx.ComparePrefix)
slices.Sort(t.RouteAddressSet)
slices.SortFunc(t.RouteExcludeAddress, nnip.PrefixCompare)
slices.SortFunc(t.RouteExcludeAddress, netipx.ComparePrefix)
slices.Sort(t.RouteExcludeAddressSet)
slices.Sort(t.IncludeInterface)
slices.Sort(t.ExcludeInterface)
@ -86,10 +86,10 @@ func (t *Tun) Sort() {
slices.Sort(t.IncludePackage)
slices.Sort(t.ExcludePackage)
slices.SortFunc(t.Inet4RouteAddress, nnip.PrefixCompare)
slices.SortFunc(t.Inet6RouteAddress, nnip.PrefixCompare)
slices.SortFunc(t.Inet4RouteExcludeAddress, nnip.PrefixCompare)
slices.SortFunc(t.Inet6RouteExcludeAddress, nnip.PrefixCompare)
slices.SortFunc(t.Inet4RouteAddress, netipx.ComparePrefix)
slices.SortFunc(t.Inet6RouteAddress, netipx.ComparePrefix)
slices.SortFunc(t.Inet4RouteExcludeAddress, netipx.ComparePrefix)
slices.SortFunc(t.Inet6RouteExcludeAddress, netipx.ComparePrefix)
}
func (t *Tun) Equal(other Tun) bool {