From 7182b9cf52087bc354104ad2a23fcf4c468ab20e Mon Sep 17 00:00:00 2001 From: Zhaozhong Ni Date: Mon, 14 Jan 2019 13:32:31 -0800 Subject: [PATCH] netstack: release port inline for listening sockets only. PiperOrigin-RevId: 229243918 Change-Id: Ie14ef34e66ae851ed080f57b7d26a369a66f7664 --- pkg/tcpip/transport/tcp/endpoint.go | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 5281f8be2..1ee9f8d25 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -410,18 +410,18 @@ func (e *endpoint) Close() { e.mu.Lock() - // We always release ports inline so that they are immediately available - // for reuse after Close() is called. If also registered, it means this - // is a listening socket, so we must unregister as well otherwise the - // next user would fail in Listen() when trying to register. - if e.isPortReserved { - e.stack.ReleasePort(e.effectiveNetProtos, ProtocolNumber, e.id.LocalAddress, e.id.LocalPort) - e.isPortReserved = false - + // For listening sockets, we always release ports inline so that they + // are immediately available for reuse after Close() is called. If also + // registered, we unregister as well otherwise the next user would fail + // in Listen() when trying to register. + if e.state == stateListen && e.isPortReserved { if e.isRegistered { e.stack.UnregisterTransportEndpoint(e.boundNICID, e.effectiveNetProtos, ProtocolNumber, e.id, e) e.isRegistered = false } + + e.stack.ReleasePort(e.effectiveNetProtos, ProtocolNumber, e.id.LocalAddress, e.id.LocalPort) + e.isPortReserved = false } // Either perform the local cleanup or kick the worker to make sure it @@ -457,6 +457,12 @@ func (e *endpoint) cleanupLocked() { if e.isRegistered { e.stack.UnregisterTransportEndpoint(e.boundNICID, e.effectiveNetProtos, ProtocolNumber, e.id, e) + e.isRegistered = false + } + + if e.isPortReserved { + e.stack.ReleasePort(e.effectiveNetProtos, ProtocolNumber, e.id.LocalAddress, e.id.LocalPort) + e.isPortReserved = false } e.route.Release()