Fix race condition (*tcp.endpoint).Close

Atomically close the endpoint. Before this change, it was possible for
multiple callers to perform duplicate work.

PiperOrigin-RevId: 300462110
This commit is contained in:
Tamir Duberstein 2020-03-11 19:56:13 -07:00 committed by gVisor bot
parent 61051f2268
commit 538e35f61b
1 changed files with 1 additions and 8 deletions

View File

@ -825,6 +825,7 @@ func (e *endpoint) Abort() {
func (e *endpoint) Close() {
e.mu.Lock()
closed := e.closed
e.closed = true
e.mu.Unlock()
if closed {
return
@ -833,13 +834,7 @@ func (e *endpoint) Close() {
// Issue a shutdown so that the peer knows we won't send any more data
// if we're connected, or stop accepting if we're listening.
e.Shutdown(tcpip.ShutdownWrite | tcpip.ShutdownRead)
e.closeNoShutdown()
}
// closeNoShutdown closes the endpoint without doing a full shutdown. This is
// used when a connection needs to be aborted with a RST and we want to skip
// a full 4 way TCP shutdown.
func (e *endpoint) closeNoShutdown() {
e.mu.Lock()
// For listening sockets, we always release ports inline so that they
@ -858,8 +853,6 @@ func (e *endpoint) closeNoShutdown() {
e.boundPortFlags = ports.Flags{}
}
// Mark endpoint as closed.
e.closed = true
// Either perform the local cleanup or kick the worker to make sure it
// knows it needs to cleanup.
switch e.EndpointState() {