From 433ba582f7c72636066ec92679a325b7ee15297c Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Mon, 1 Nov 2021 13:23:39 -0700 Subject: [PATCH] net: optimize WriteToUDPAddrPort MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See the recent change optimizing WriteMsgUDPAddrPort for an explanation of why this change includes copy/paste/modify instead of implementing WriteToUDP using WriteToUDPAddrPort. name old time/op new time/op delta WriteToReadFromUDPAddrPort-8 5.02µs ± 3% 4.71µs ± 2% -6.31% (p=0.000 n=15+14) name old alloc/op new alloc/op delta WriteToReadFromUDPAddrPort-8 68.0B ± 0% 4.0B ± 0% -94.12% (p=0.000 n=15+15) name old allocs/op new allocs/op delta WriteToReadFromUDPAddrPort-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=15+15) Change-Id: I301715e774de07eb6ccb4e329ccf2e554609abc1 Reviewed-on: https://go-review.googlesource.com/c/go/+/360599 Trust: Josh Bleecher Snyder Run-TryBot: Josh Bleecher Snyder TryBot-Result: Go Bot Reviewed-by: Brad Fitzpatrick --- src/net/udpsock.go | 13 ++++++++----- src/net/udpsock_plan9.go | 4 ++++ src/net/udpsock_posix.go | 26 ++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/net/udpsock.go b/src/net/udpsock.go index 0d563fd4f5..a829789a1b 100644 --- a/src/net/udpsock.go +++ b/src/net/udpsock.go @@ -207,11 +207,14 @@ func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) { // WriteToUDPAddrPort acts like WriteTo but takes a netip.AddrPort. func (c *UDPConn) WriteToUDPAddrPort(b []byte, addr netip.AddrPort) (int, error) { - // TODO(bradfitz): make this efficient, making the internal net package - // type throughout be netip.Addr and only converting to the net.IP slice - // version at the edge. But for now (2021-10-20), this is a wrapper around - // the old way. - return c.WriteToUDP(b, UDPAddrFromAddrPort(addr)) + if !c.ok() { + return 0, syscall.EINVAL + } + n, err := c.writeToAddrPort(b, addr) + if err != nil { + err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addrPortUDPAddr{addr}, Err: err} + } + return n, err } // WriteTo implements the PacketConn WriteTo method. diff --git a/src/net/udpsock_plan9.go b/src/net/udpsock_plan9.go index ac5afa2281..dfb81a8d0c 100644 --- a/src/net/udpsock_plan9.go +++ b/src/net/udpsock_plan9.go @@ -53,6 +53,10 @@ func (c *UDPConn) writeTo(b []byte, addr *UDPAddr) (int, error) { return len(b), nil } +func (c *UDPConn) writeToAddrPort(b []byte, addr netip.AddrPort) (int, error) { + return c.writeTo(b, UDPAddrFromAddrPort(addr)) // TODO: optimize instead of allocating +} + func (c *UDPConn) writeMsg(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) { return 0, 0, syscall.EPLAN9 } diff --git a/src/net/udpsock_posix.go b/src/net/udpsock_posix.go index 646687d148..718d11e60f 100644 --- a/src/net/udpsock_posix.go +++ b/src/net/udpsock_posix.go @@ -109,6 +109,32 @@ func (c *UDPConn) writeTo(b []byte, addr *UDPAddr) (int, error) { } } +func (c *UDPConn) writeToAddrPort(b []byte, addr netip.AddrPort) (int, error) { + if c.fd.isConnected { + return 0, ErrWriteToConnected + } + if !addr.IsValid() { + return 0, errMissingAddress + } + + switch c.fd.family { + case syscall.AF_INET: + sa, err := addrPortToSockaddrInet4(addr) + if err != nil { + return 0, err + } + return c.fd.writeToInet4(b, sa) + case syscall.AF_INET6: + sa, err := addrPortToSockaddrInet6(addr) + if err != nil { + return 0, err + } + return c.fd.writeToInet6(b, sa) + default: + return 0, &AddrError{Err: "invalid address family", Addr: addr.Addr().String()} + } +} + func (c *UDPConn) writeMsg(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) { if c.fd.isConnected && addr != nil { return 0, 0, ErrWriteToConnected