From: Ian Lance Taylor Date: Tue, 1 May 2018 03:23:37 +0000 (-0700) Subject: net, syscall: make ECONNRESET/ECONNABORTED only temporary for Accept X-Git-Tag: go1.11beta1~587 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=7f6105f138b3836e9ad85b8da26d44c742bf217b;p=gostls13.git net, syscall: make ECONNRESET/ECONNABORTED only temporary for Accept Updates #6163 Fixes #24808 Change-Id: I4f5c686ebf60f72f71f566199ee3e946076202bb Reviewed-on: https://go-review.googlesource.com/110439 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- diff --git a/src/net/error_nacl.go b/src/net/error_nacl.go new file mode 100644 index 0000000000..caad133b77 --- /dev/null +++ b/src/net/error_nacl.go @@ -0,0 +1,9 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package net + +func isConnError(err error) bool { + return false +} diff --git a/src/net/error_plan9.go b/src/net/error_plan9.go new file mode 100644 index 0000000000..caad133b77 --- /dev/null +++ b/src/net/error_plan9.go @@ -0,0 +1,9 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package net + +func isConnError(err error) bool { + return false +} diff --git a/src/net/error_unix.go b/src/net/error_unix.go new file mode 100644 index 0000000000..633861e759 --- /dev/null +++ b/src/net/error_unix.go @@ -0,0 +1,16 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd linux netbsd openbsd solaris + +package net + +import "syscall" + +func isConnError(err error) bool { + if se, ok := err.(syscall.Errno); ok { + return se == syscall.ECONNRESET || se == syscall.ECONNABORTED + } + return false +} diff --git a/src/net/error_windows.go b/src/net/error_windows.go new file mode 100644 index 0000000000..570b97b278 --- /dev/null +++ b/src/net/error_windows.go @@ -0,0 +1,14 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package net + +import "syscall" + +func isConnError(err error) bool { + if se, ok := err.(syscall.Errno); ok { + return se == syscall.WSAECONNRESET || se == syscall.WSAECONNABORTED + } + return false +} diff --git a/src/net/net.go b/src/net/net.go index b023d7c93f..94561dd749 100644 --- a/src/net/net.go +++ b/src/net/net.go @@ -490,6 +490,12 @@ type temporary interface { } func (e *OpError) Temporary() bool { + // Treat ECONNRESET and ECONNABORTED as temporary errors when + // they come from calling accept. See issue 6163. + if e.Op == "accept" && isConnError(e.Err) { + return true + } + if ne, ok := e.Err.(*os.SyscallError); ok { t, ok := ne.Err.(temporary) return ok && t.Temporary() diff --git a/src/net/net_test.go b/src/net/net_test.go index 024505e7c6..c82aa070a2 100644 --- a/src/net/net_test.go +++ b/src/net/net_test.go @@ -516,3 +516,30 @@ func TestCloseUnblocksRead(t *testing.T) { } withTCPConnPair(t, client, server) } + +// Issue 24808: verify that ECONNRESET is not temporary for read. +func TestNotTemporaryRead(t *testing.T) { + t.Parallel() + server := func(cs *TCPConn) error { + cs.SetLinger(0) + // Give the client time to get stuck in a Read. + time.Sleep(20 * time.Millisecond) + cs.Close() + return nil + } + client := func(ss *TCPConn) error { + _, err := ss.Read([]byte{0}) + if err == nil { + return errors.New("Read succeeded unexpectedly") + } else if err == io.EOF { + // This happens on NaCl and Plan 9. + return nil + } else if ne, ok := err.(Error); !ok { + return fmt.Errorf("unexpected error %v", err) + } else if ne.Temporary() { + return fmt.Errorf("unexpected temporary error %v", err) + } + return nil + } + withTCPConnPair(t, client, server) +} diff --git a/src/syscall/syscall_unix.go b/src/syscall/syscall_unix.go index a634748273..c9c0f62dd2 100644 --- a/src/syscall/syscall_unix.go +++ b/src/syscall/syscall_unix.go @@ -121,7 +121,7 @@ func (e Errno) Error() string { } func (e Errno) Temporary() bool { - return e == EINTR || e == EMFILE || e == ECONNRESET || e == ECONNABORTED || e.Timeout() + return e == EINTR || e == EMFILE || e.Timeout() } func (e Errno) Timeout() bool { diff --git a/src/syscall/syscall_windows.go b/src/syscall/syscall_windows.go index 9026fcdacf..5cfdb76e2b 100644 --- a/src/syscall/syscall_windows.go +++ b/src/syscall/syscall_windows.go @@ -110,7 +110,7 @@ func (e Errno) Error() string { } func (e Errno) Temporary() bool { - return e == EINTR || e == EMFILE || e == WSAECONNABORTED || e == WSAECONNRESET || e.Timeout() + return e == EINTR || e == EMFILE || e.Timeout() } func (e Errno) Timeout() bool {