]> Cypherpunks repositories - gostls13.git/commitdiff
net, syscall: make ECONNRESET/ECONNABORTED only temporary for Accept
authorIan Lance Taylor <iant@golang.org>
Tue, 1 May 2018 03:23:37 +0000 (20:23 -0700)
committerIan Lance Taylor <iant@golang.org>
Tue, 1 May 2018 14:50:33 +0000 (14:50 +0000)
Updates #6163
Fixes #24808

Change-Id: I4f5c686ebf60f72f71f566199ee3e946076202bb
Reviewed-on: https://go-review.googlesource.com/110439
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/net/error_nacl.go [new file with mode: 0644]
src/net/error_plan9.go [new file with mode: 0644]
src/net/error_unix.go [new file with mode: 0644]
src/net/error_windows.go [new file with mode: 0644]
src/net/net.go
src/net/net_test.go
src/syscall/syscall_unix.go
src/syscall/syscall_windows.go

diff --git a/src/net/error_nacl.go b/src/net/error_nacl.go
new file mode 100644 (file)
index 0000000..caad133
--- /dev/null
@@ -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 (file)
index 0000000..caad133
--- /dev/null
@@ -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 (file)
index 0000000..633861e
--- /dev/null
@@ -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 (file)
index 0000000..570b97b
--- /dev/null
@@ -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
+}
index b023d7c93f82ea71ca41e9efb54890639c8409a2..94561dd7492d0489c22d568b566175bf76e587b4 100644 (file)
@@ -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()
index 024505e7c628a6cf15ca2ecaeecba1625173676c..c82aa070a2d34970f2a3486d9b0886afd0f37620 100644 (file)
@@ -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)
+}
index a6347482734faea79acc7d30ea97f026cecee290..c9c0f62dd2f517719c4903f2c838e57e40f1e7be 100644 (file)
@@ -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 {
index 9026fcdacf959198f84b61a5ee4e79cf66025953..5cfdb76e2bf5bbc972f3c9269c8b366b26cc4037 100644 (file)
@@ -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 {