mirror of
https://github.com/golang/go
synced 2024-11-11 21:30:23 -07:00
net: close connection in localServer teardown
The transponder sets up a deferred close on accepted connections which is fine after the client reads all data. However there are no mutexes nor channels to block the transponder from closing. If the scheduler runs close before the client read, it will cause an EOF failure. Fixes #42720 Change-Id: Ic21b476c5efc9265a80a2c6f8484efdb5af66405 Reviewed-on: https://go-review.googlesource.com/c/go/+/273672 Run-TryBot: Meng Zhuo <mzh@golangcn.org> TryBot-Result: Go Bot <gobot@golang.org> Trust: Meng Zhuo <mzh@golangcn.org> Reviewed-by: Damien Neil <dneil@google.com>
This commit is contained in:
parent
8981092d71
commit
08b5091d03
@ -32,7 +32,7 @@ func TestConnAndListener(t *testing.T) {
|
||||
}
|
||||
defer ls.teardown()
|
||||
ch := make(chan error, 1)
|
||||
handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
|
||||
handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) }
|
||||
if err := ls.buildup(handler); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ type localServer struct {
|
||||
lnmu sync.RWMutex
|
||||
Listener
|
||||
done chan bool // signal that indicates server stopped
|
||||
cl []Conn // accepted connection list
|
||||
}
|
||||
|
||||
func (ls *localServer) buildup(handler func(*localServer, Listener)) error {
|
||||
@ -99,10 +100,16 @@ func (ls *localServer) buildup(handler func(*localServer, Listener)) error {
|
||||
|
||||
func (ls *localServer) teardown() error {
|
||||
ls.lnmu.Lock()
|
||||
defer ls.lnmu.Unlock()
|
||||
if ls.Listener != nil {
|
||||
network := ls.Listener.Addr().Network()
|
||||
address := ls.Listener.Addr().String()
|
||||
ls.Listener.Close()
|
||||
for _, c := range ls.cl {
|
||||
if err := c.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
<-ls.done
|
||||
ls.Listener = nil
|
||||
switch network {
|
||||
@ -110,7 +117,6 @@ func (ls *localServer) teardown() error {
|
||||
os.Remove(address)
|
||||
}
|
||||
}
|
||||
ls.lnmu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -203,7 +209,7 @@ func newDualStackServer() (*dualStackServer, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func transponder(ln Listener, ch chan<- error) {
|
||||
func (ls *localServer) transponder(ln Listener, ch chan<- error) {
|
||||
defer close(ch)
|
||||
|
||||
switch ln := ln.(type) {
|
||||
@ -220,7 +226,7 @@ func transponder(ln Listener, ch chan<- error) {
|
||||
ch <- err
|
||||
return
|
||||
}
|
||||
defer c.Close()
|
||||
ls.cl = append(ls.cl, c)
|
||||
|
||||
network := ln.Addr().Network()
|
||||
if c.LocalAddr().Network() != network || c.RemoteAddr().Network() != network {
|
||||
|
@ -72,7 +72,7 @@ func TestTCPConnSpecificMethods(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ch := make(chan error, 1)
|
||||
handler := func(ls *localServer, ln Listener) { transponder(ls.Listener, ch) }
|
||||
handler := func(ls *localServer, ln Listener) { ls.transponder(ls.Listener, ch) }
|
||||
ls, err := (&streamListener{Listener: ln}).newLocalServer()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -86,7 +86,7 @@ func TestTCPServer(t *testing.T) {
|
||||
}
|
||||
for i := 0; i < N; i++ {
|
||||
ch := tpchs[i]
|
||||
handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
|
||||
handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) }
|
||||
if err := lss[i].buildup(handler); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -178,7 +178,7 @@ func TestUnixAndUnixpacketServer(t *testing.T) {
|
||||
}
|
||||
for i := 0; i < N; i++ {
|
||||
ch := tpchs[i]
|
||||
handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
|
||||
handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) }
|
||||
if err := lss[i].buildup(handler); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -393,7 +393,7 @@ func TestIPv6LinkLocalUnicastTCP(t *testing.T) {
|
||||
}
|
||||
defer ls.teardown()
|
||||
ch := make(chan error, 1)
|
||||
handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
|
||||
handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) }
|
||||
if err := ls.buildup(handler); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user