From 598df45fceb6e10d643ed0c07a3df80cffd507f1 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Mon, 10 Mar 2025 11:45:10 -0700 Subject: [PATCH] net: unblock UDP Reads upon Close on plan9, add test Fixes #72770 Change-Id: I42be7c7349961188f4b5d73287a3550aba323893 Reviewed-on: https://go-review.googlesource.com/c/go/+/656395 LUCI-TryBot-Result: Go LUCI Reviewed-by: Ian Lance Taylor Reviewed-by: David du Colombier <0intro@gmail.com> Reviewed-by: Russ Cox --- src/net/fd_plan9.go | 5 +++++ src/net/net_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/net/fd_plan9.go b/src/net/fd_plan9.go index da41bc0c34..66a12e7d7d 100644 --- a/src/net/fd_plan9.go +++ b/src/net/fd_plan9.go @@ -126,6 +126,11 @@ func (fd *netFD) Close() error { return err } } + if fd.net == "udp" { + // The following line is required to unblock Reads. + // See https://go.dev/issue/72770. + fd.SetReadDeadline(time.Now().Add(-time.Hour)) + } err := fd.ctl.Close() if fd.data != nil { if err1 := fd.data.Close(); err1 != nil && err == nil { diff --git a/src/net/net_test.go b/src/net/net_test.go index 4a5dc3b73a..705ac45c6b 100644 --- a/src/net/net_test.go +++ b/src/net/net_test.go @@ -508,6 +508,32 @@ func TestCloseUnblocksRead(t *testing.T) { withTCPConnPair(t, client, server) } +// Issue 72770: verify that a blocked UDP read is woken up by a Close. +func TestCloseUnblocksReadUDP(t *testing.T) { + t.Parallel() + pc, err := ListenPacket("udp", "127.0.0.1:0") + if err != nil { + t.Fatal(err) + } + time.AfterFunc(250*time.Millisecond, func() { + t.Logf("closing conn...") + pc.Close() + }) + timer := time.AfterFunc(time.Second*10, func() { + panic("timeout waiting for Close") + }) + defer timer.Stop() + + n, src, err := pc.(*UDPConn).ReadFromUDPAddrPort([]byte{}) + + // Check for n > 0. Checking err == nil alone isn't enough; + // on macOS, it returns (n=0, src=0.0.0.0:0, err=nil). + if n > 0 { + t.Fatalf("unexpected Read success from ReadFromUDPAddrPort; read %d bytes from %v, err=%v", n, src, err) + } + t.Logf("got expected UDP read error") +} + // Issue 24808: verify that ECONNRESET is not temporary for read. func TestNotTemporaryRead(t *testing.T) { t.Parallel() -- 2.50.0