]> Cypherpunks repositories - gostls13.git/commitdiff
net: do more faithful conversion from AddrPort to UDPAddr
authorJason A. Donenfeld <Jason@zx2c4.com>
Fri, 5 Nov 2021 12:02:09 +0000 (13:02 +0100)
committerJason A. Donenfeld <Jason@zx2c4.com>
Wed, 10 Nov 2021 22:16:25 +0000 (22:16 +0000)
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 <Jason@zx2c4.com>
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
src/net/udpsock.go
src/net/udpsock_test.go

index 622b1f83fb2b4423aedbbdad6d823eca5986e6ff..6d29a39edfcfcb389401e6bba22841a5f6605390 100644 (file)
@@ -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
 }
 
index 9fe74f47a2bbb297c8b750269dcc32e0462d6d41..01b8d39216aaed1eaa0307b75a5bcfb826065813 100644 (file)
@@ -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")
+       }
+}