Skip to content

Commit

Permalink
net: close connection in localServer teardown
Browse files Browse the repository at this point in the history
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 <[email protected]>
TryBot-Result: Go Bot <[email protected]>
Trust: Meng Zhuo <[email protected]>
Reviewed-by: Damien Neil <[email protected]>
  • Loading branch information
mengzhuo committed Dec 16, 2020
1 parent 8981092 commit 08b5091
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/net/conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
12 changes: 9 additions & 3 deletions src/net/mockserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -99,18 +100,23 @@ 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 {
case "unix", "unixpacket":
os.Remove(address)
}
}
ls.lnmu.Unlock()
return nil
}

Expand Down Expand Up @@ -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) {
Expand All @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/net/protoconn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions src/net/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down
2 changes: 1 addition & 1 deletion src/net/tcpsock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down

0 comments on commit 08b5091

Please sign in to comment.