From e58fa87566ddc82e7fb1c491524bd5d29fd65dc3 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 20 Apr 2024 15:21:24 +0200 Subject: [PATCH] catch spurious UDP sendmsg errors in multiplex integration test (#4451) * catch spurious UDP sendmsg errors in multiplex integration test * platform-dependent isPermissionError --- integrationtests/self/multiplex_test.go | 8 +++++++ .../self/self_suite_linux_test.go | 21 +++++++++++++++++++ .../self/self_suite_others_test.go | 7 +++++++ 3 files changed, 36 insertions(+) create mode 100644 integrationtests/self/self_suite_linux_test.go create mode 100644 integrationtests/self/self_suite_others_test.go diff --git a/integrationtests/self/multiplex_test.go b/integrationtests/self/multiplex_test.go index 7b202c71a..0641f8b6e 100644 --- a/integrationtests/self/multiplex_test.go +++ b/integrationtests/self/multiplex_test.go @@ -249,6 +249,7 @@ var _ = Describe("Multiplexing", func() { defer GinkgoRecover() ticker := time.NewTicker(time.Millisecond / 10) defer ticker.Stop() + var wroteFirstPacket bool for { select { case <-ticker.C: @@ -258,11 +259,18 @@ var _ = Describe("Multiplexing", func() { b := make([]byte, packetLen) rand.Read(b[1:]) // keep the first byte set to 0, so it's not classified as a QUIC packet _, err := tr1.WriteTo(b, tr2.Conn.LocalAddr()) + // The first sendmsg call on a new UDP socket sometimes errors on Linux. + // It's not clear why this happens. + // See https://github.com/golang/go/issues/63322. + if err != nil && !wroteFirstPacket && isPermissionError(err) { + _, err = tr1.WriteTo(b, tr2.Conn.LocalAddr()) + } if ctx.Err() != nil { // ctx canceled while Read was executing return } Expect(err).ToNot(HaveOccurred()) sentPackets.Add(1) + wroteFirstPacket = true } }() diff --git a/integrationtests/self/self_suite_linux_test.go b/integrationtests/self/self_suite_linux_test.go new file mode 100644 index 000000000..7baa1f48e --- /dev/null +++ b/integrationtests/self/self_suite_linux_test.go @@ -0,0 +1,21 @@ +//go:build linux + +package self_test + +import ( + "errors" + "os" + + "golang.org/x/sys/unix" +) + +// The first sendmsg call on a new UDP socket sometimes errors on Linux. +// It's not clear why this happens. +// See https://github.com/golang/go/issues/63322. +func isPermissionError(err error) bool { + var serr *os.SyscallError + if errors.As(err, &serr) { + return serr.Syscall == "sendmsg" && serr.Err == unix.EPERM + } + return false +} diff --git a/integrationtests/self/self_suite_others_test.go b/integrationtests/self/self_suite_others_test.go new file mode 100644 index 000000000..c0080d358 --- /dev/null +++ b/integrationtests/self/self_suite_others_test.go @@ -0,0 +1,7 @@ +//go:build !linux + +package self_test + +func isPermissionError(err error) bool { + return false +}