-
Notifications
You must be signed in to change notification settings - Fork 18.1k
proposal: net/netip: add UnmappedEquals(netip.AddrPort)
to netip.AddrPort
#54366
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I don't think we want to add API for this. We're trying to fix the real problem (ReadMsgUDPAddrPort etc returning bad netip.Addr/AddrPort values) instead in #54234 |
I wouldn't call this "the real problem" or "bad values". It is natural for ReadMsgUDPAddrPort calls on IPv6 UDP sockets to return IPv4-mapped IPv6 addresses, because that's how the underlying socket works. A method like |
The following benchmark uses // AddrPortMappedEqual returns whether the two addresses point to the same endpoint.
// An IPv4 address and an IPv4-mapped IPv6 address pointing to the same endpoint are considered equal.
// For example, 1.1.1.1:53 and [::ffff:1.1.1.1]:53 are considered equal.
func AddrPortMappedEqual(l, r netip.AddrPort) bool {
if l == r {
return true
}
return l.Port() == r.Port() && l.Addr().Unmap() == r.Addr().Unmap()
}
type addrPortHeader struct {
ip [16]byte
z unsafe.Pointer
port uint16
}
func AddrPortMappedEqualUnsafe(l, r netip.AddrPort) bool {
lp := (*addrPortHeader)(unsafe.Pointer(&l))
rp := (*addrPortHeader)(unsafe.Pointer(&r))
return lp.ip == rp.ip && lp.port == rp.port
} var (
addrPort4 = netip.AddrPortFrom(netip.AddrFrom4([4]byte{127, 0, 0, 1}), 1080)
addrPort4in6 = netip.AddrPortFrom(netip.AddrFrom16([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1}), 1080)
)
func BenchmarkAddrPortMappedEqual(b *testing.B) {
b.Run("Equal", func(b *testing.B) {
for i := 0; i < b.N; i++ {
AddrPortMappedEqual(addrPort4, addrPort4)
}
})
b.Run("NotEqual", func(b *testing.B) {
for i := 0; i < b.N; i++ {
AddrPortMappedEqual(addrPort4, addrPort4in6)
}
})
}
func BenchmarkAddrPortMappedEqualUnsafe(b *testing.B) {
b.Run("Equal", func(b *testing.B) {
for i := 0; i < b.N; i++ {
AddrPortMappedEqualUnsafe(addrPort4, addrPort4)
}
})
b.Run("NotEqual", func(b *testing.B) {
for i := 0; i < b.N; i++ {
AddrPortMappedEqualUnsafe(addrPort4, addrPort4in6)
}
})
}
|
In configuration and other places, IPv4 addresses are usually specified unmapped, like
1.1.1.1:53
. When dealing withReadFromUDPAddrPort
andReadMsgUDPAddrPort
, the returnednetip.AddrPort
is likely to be an IPv4-mapped IPv6 address, like[::ffff:1.1.1.1]:53
, depending on how the UDP socket was opened.To check whether these 2 addresses point to the same endpoint, we would have to do something like:
It'd be nice if we have a method on
netip.AddrPort
to directly compare the unexportedaddr
field innetip.Addr
. I propose we add something like:The method can also be called
MappedEquals
if #54365 is accepted./cc @bradfitz
The text was updated successfully, but these errors were encountered: