diff --git a/src/net/udpsock_posix.go b/src/net/udpsock_posix.go index fcfb9c004cd..96fb373ce77 100644 --- a/src/net/udpsock_posix.go +++ b/src/net/udpsock_posix.go @@ -50,6 +50,9 @@ func (c *UDPConn) readFrom(b []byte, addr *UDPAddr) (int, *UDPAddr, error) { *addr = UDPAddr{IP: sa.Addr[0:], Port: sa.Port} case *syscall.SockaddrInet6: *addr = UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneCache.name(int(sa.ZoneId))} + default: + // No sockaddr, so don't return UDPAddr. + addr = nil } return n, addr, err } diff --git a/src/net/udpsock_test.go b/src/net/udpsock_test.go index b4000b5664d..0e8c3511c36 100644 --- a/src/net/udpsock_test.go +++ b/src/net/udpsock_test.go @@ -8,7 +8,9 @@ package net import ( + "errors" "internal/testenv" + "os" "reflect" "runtime" "testing" @@ -446,6 +448,33 @@ func TestUDPReadSizeError(t *testing.T) { } } +// TestUDPReadTimeout verifies that ReadFromUDP with timeout returns an error +// without data or an address. +func TestUDPReadTimeout(t *testing.T) { + la, err := ResolveUDPAddr("udp4", "127.0.0.1:0") + if err != nil { + t.Fatal(err) + } + c, err := ListenUDP("udp4", la) + if err != nil { + t.Fatal(err) + } + defer c.Close() + + c.SetDeadline(time.Now()) + b := make([]byte, 1) + n, addr, err := c.ReadFromUDP(b) + if !errors.Is(err, os.ErrDeadlineExceeded) { + t.Errorf("ReadFromUDP got err %v want os.ErrDeadlineExceeded", err) + } + if n != 0 { + t.Errorf("ReadFromUDP got n %d want 0", n) + } + if addr != nil { + t.Errorf("ReadFromUDP got addr %+#v want nil", addr) + } +} + func BenchmarkWriteToReadFromUDP(b *testing.B) { conn, err := ListenUDP("udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)}) if err != nil {