fix: correctly handle ipv6 zone

This commit is contained in:
wwqgtxx 2025-03-17 23:51:21 +08:00
parent e3d4ec2476
commit 7c444a91d3
3 changed files with 22 additions and 10 deletions

View File

@ -45,7 +45,11 @@ func (c *enhanceUDPConn) WaitReadFrom() (data []byte, put func(), addr net.Addr,
addr = &net.UDPAddr{IP: ip[:], Port: from.Port} addr = &net.UDPAddr{IP: ip[:], Port: from.Port}
case *syscall.SockaddrInet6: case *syscall.SockaddrInet6:
ip := from.Addr // copy from.Addr; ip escapes, so this line allocates 16 bytes ip := from.Addr // copy from.Addr; ip escapes, so this line allocates 16 bytes
addr = &net.UDPAddr{IP: ip[:], Port: from.Port, Zone: strconv.FormatInt(int64(from.ZoneId), 10)} zone := ""
if from.ZoneId != 0 {
zone = strconv.FormatInt(int64(from.ZoneId), 10)
}
addr = &net.UDPAddr{IP: ip[:], Port: from.Port, Zone: zone}
} }
} }
// udp should not convert readN == 0 to io.EOF // udp should not convert readN == 0 to io.EOF

View File

@ -54,7 +54,11 @@ func (c *enhanceUDPConn) WaitReadFrom() (data []byte, put func(), addr net.Addr,
addr = &net.UDPAddr{IP: ip[:], Port: from.Port} addr = &net.UDPAddr{IP: ip[:], Port: from.Port}
case *windows.SockaddrInet6: case *windows.SockaddrInet6:
ip := from.Addr // copy from.Addr; ip escapes, so this line allocates 16 bytes ip := from.Addr // copy from.Addr; ip escapes, so this line allocates 16 bytes
addr = &net.UDPAddr{IP: ip[:], Port: from.Port, Zone: strconv.FormatInt(int64(from.ZoneId), 10)} zone := ""
if from.ZoneId != 0 {
zone = strconv.FormatInt(int64(from.ZoneId), 10)
}
addr = &net.UDPAddr{IP: ip[:], Port: from.Port, Zone: zone}
} }
} }
// udp should not convert readN == 0 to io.EOF // udp should not convert readN == 0 to io.EOF

View File

@ -3,8 +3,9 @@
package dns package dns
import ( import (
"net" "net/netip"
"os" "os"
"strconv"
"syscall" "syscall"
"unsafe" "unsafe"
@ -23,28 +24,31 @@ func dnsReadConfig() (servers []string, err error) {
if err != nil { if err != nil {
continue continue
} }
var ip net.IP var ip netip.Addr
switch sa := sa.(type) { switch sa := sa.(type) {
case *syscall.SockaddrInet4: case *syscall.SockaddrInet4:
ip = net.IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3]) ip = netip.AddrFrom4(sa.Addr)
case *syscall.SockaddrInet6: case *syscall.SockaddrInet6:
ip = make(net.IP, net.IPv6len) if sa.Addr[0] == 0xfe && sa.Addr[1] == 0xc0 {
copy(ip, sa.Addr[:])
if ip[0] == 0xfe && ip[1] == 0xc0 {
// Ignore these fec0/10 ones. Windows seems to // Ignore these fec0/10 ones. Windows seems to
// populate them as defaults on its misc rando // populate them as defaults on its misc rando
// interfaces. // interfaces.
continue continue
} }
ip = netip.AddrFrom16(sa.Addr)
if sa.ZoneId != 0 {
ip = ip.WithZone(strconv.FormatInt(int64(sa.ZoneId), 10))
}
//continue //continue
default: default:
// Unexpected type. // Unexpected type.
continue continue
} }
if slices.Contains(servers, ip.String()) { ipStr := ip.String()
if slices.Contains(servers, ipStr) {
continue continue
} }
servers = append(servers, ip.String()) servers = append(servers, ipStr)
} }
} }
return return