From: Jason A. Donenfeld Date: Fri, 5 Nov 2021 12:02:09 +0000 (+0100) Subject: net: do more faithful conversion from AddrPort to UDPAddr X-Git-Tag: go1.18beta1~393 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=4d0683965bd05aee6845bf6849c85c4bf2bb10d4;p=gostls13.git net: do more faithful conversion from AddrPort to UDPAddr A UDPAddr with a nil IP is a valid state, representing an AF-agnostic unspecified address, so checking for addr.IsValid() isn't correct; remove that, as it's only needed in the UDP rx path where it can be added. Secondly, forcing everything to be IPv6 also is not correct, and was likely done when the missing .AsSlice() made doing the right thing less ergonomic. Fix this by using .AsSlice(), which properly preserves IP version. Change-Id: Idd1eaecd4076f32a843f859a0a9802ef98f956d3 Reviewed-on: https://go-review.googlesource.com/c/go/+/361478 Trust: Jason A. Donenfeld Trust: Josh Bleecher Snyder Run-TryBot: Jason A. Donenfeld TryBot-Result: Go Bot Reviewed-by: Russ Cox --- diff --git a/src/net/udpsock.go b/src/net/udpsock.go index 622b1f83fb..6d29a39edf 100644 --- a/src/net/udpsock.go +++ b/src/net/udpsock.go @@ -99,16 +99,12 @@ func ResolveUDPAddr(network, address string) (*UDPAddr, error) { return addrs.forResolve(network, address).(*UDPAddr), nil } -// UDPAddrFromAddrPort returns addr as a UDPAddr. -// -// If addr is not valid, it returns nil. +// UDPAddrFromAddrPort returns addr as a UDPAddr. If addr.IsValid() is false, +// then the returned UDPAddr will contain a nil IP field, indicating an +// address family-agnostic unspecified address. func UDPAddrFromAddrPort(addr netip.AddrPort) *UDPAddr { - if !addr.IsValid() { - return nil - } - ip16 := addr.Addr().As16() return &UDPAddr{ - IP: IP(ip16[:]), + IP: addr.Addr().AsSlice(), Zone: addr.Addr().Zone(), Port: int(addr.Port()), } @@ -189,7 +185,9 @@ func (c *UDPConn) ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) { var ap netip.AddrPort n, oobn, flags, ap, err = c.ReadMsgUDPAddrPort(b, oob) - addr = UDPAddrFromAddrPort(ap) + if ap.IsValid() { + addr = UDPAddrFromAddrPort(ap) + } return } diff --git a/src/net/udpsock_test.go b/src/net/udpsock_test.go index 9fe74f47a2..01b8d39216 100644 --- a/src/net/udpsock_test.go +++ b/src/net/udpsock_test.go @@ -603,3 +603,35 @@ func BenchmarkWriteToReadFromUDPAddrPort(b *testing.B) { } } } + +func TestUDPIPVersionReadMsg(t *testing.T) { + conn, err := ListenUDP("udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)}) + if err != nil { + t.Fatal(err) + } + defer conn.Close() + daddr := conn.LocalAddr().(*UDPAddr).AddrPort() + buf := make([]byte, 8) + _, err = conn.WriteToUDPAddrPort(buf, daddr) + if err != nil { + t.Fatal(err) + } + _, _, _, saddr, err := conn.ReadMsgUDPAddrPort(buf, nil) + if err != nil { + t.Fatal(err) + } + if !saddr.Addr().Is4() { + t.Error("returned AddrPort is not IPv4") + } + _, err = conn.WriteToUDPAddrPort(buf, daddr) + if err != nil { + t.Fatal(err) + } + _, _, _, soldaddr, err := conn.ReadMsgUDP(buf, nil) + if err != nil { + t.Fatal(err) + } + if len(soldaddr.IP) != 4 { + t.Error("returned UDPAddr is not IPv4") + } +}