diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go index ceece58c4..68aaf9604 100644 --- a/wgengine/magicsock/magicsock.go +++ b/wgengine/magicsock/magicsock.go @@ -3121,6 +3121,7 @@ func (c *blockForeverConn) Close() error { return net.ErrClosed } c.closed = true + c.cond.Broadcast() return nil } diff --git a/wgengine/magicsock/magicsock_test.go b/wgengine/magicsock/magicsock_test.go index 5ae18de52..0db371a64 100644 --- a/wgengine/magicsock/magicsock_test.go +++ b/wgengine/magicsock/magicsock_test.go @@ -1763,3 +1763,27 @@ func (m *peerMap) validate() error { return nil } + +func TestBlockForeverConnUnblocks(t *testing.T) { + c := newBlockForeverConn() + done := make(chan error, 1) + go func() { + defer close(done) + _, _, err := c.ReadFrom(make([]byte, 1)) + done <- err + }() + time.Sleep(50 * time.Millisecond) // give ReadFrom time to get blocked + if err := c.Close(); err != nil { + t.Fatal(err) + } + timer := time.NewTimer(5 * time.Second) + defer timer.Stop() + select { + case err := <-done: + if err != net.ErrClosed { + t.Errorf("got %v; want net.ErrClosed", err) + } + case <-timer.C: + t.Fatal("timeout") + } +}