Commit 7f6105f1 authored by Ian Lance Taylor's avatar Ian Lance Taylor

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 <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 1129ec2f
// 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
}
// 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
}
// 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
}
// 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
}
......@@ -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()
......
......@@ -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)
}
......@@ -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 {
......
......@@ -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 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment