Description
I propose we fix #18804 (net: reconsider representation of IP) by importing the inet.af/netaddr
into the standard library, probably as net/netaddr
, so the IP
type is netaddr.IP
(the net
package already has an IP type). We wouldn't need to import all of it, at least not right away, but I think it'd be nice if we did... the package types work together very well.
This blog post explains the advantages of netaddr.IP
over net.IP
:
https://tailscale.com/blog/netaddr-new-ip-type-for-go/
Notably, it's small, comparable, and doesn't allocate.
Code is at https://github.com/inetaf/netaddr. Everybody has a Go CLA filed ( inetaf/netaddr#181) and the license is compatible.
Having an allocation-free IP address in the standard library means we'd be able to fix #45886 ("net: add API to receive multiple UDP packets (potentially in one system call)") which ends with #45886 (comment) ("We may want to wait on doing anything here until we figure out what to do with IP addresses, which still allocate."). More generally, this would improve Go's UDP performance, which has never gotten much attention. But with things like QUIC and WireGuard (both UDP-based), Go's alloc-heavy UDP handling is starting to get in the way.
Yes, we'd then have two IP types in the standard library.
As part of this, we'd then add:
- conversion funcs in net to go between them (
net
would depend onnetaddr
, not vice-versa) - the
net
package internals would switch tonetaddr.IP
for performance/allocs, converting tonet.IP
orIPAddr
on the edges only. - a couple new methods would be added (notably to
UDPConn
) to send/receive UDP packets usingnetaddr.IP
alloc-free (we'd then have ~5 ways to send/recv UDP packets instead of ~4)
/cc @danderson, @josharian, @mdlayher, @crawshaw, @tklauser (co-authors), @neild (co-author for #45886)