diff options
author | Ian Gudger <igudger@google.com> | 2019-09-09 14:00:51 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2019-09-09 14:02:00 -0700 |
commit | 9dfcd8b09fceff830c880065db66821e53c500b0 (patch) | |
tree | d74957c5aec88a3c867f141435add6ba219d45ab | |
parent | 3733b9b893ec33877b1b46c56fe07c3856942d3f (diff) |
Fix ephemeral port leak.
Fix a bug where udp.(*endpoint).Disconnect [accessible in gVisor via
epsocket.(*SocketOperations).Connect with AF_UNSPEC] would leak a port
reservation if the socket/endpoint had an ephemeral port assigned to it.
glibc's getaddrinfo uses connect with AF_UNSPEC, causing each call of
getaddrinfo to leak a port. Call getaddrinfo too many times and you run out of
ports (shows up as connect returning EAGAIN and getaddrinfo returning
EAI_NONAME "Name or service not known").
PiperOrigin-RevId: 268071160
-rw-r--r-- | pkg/tcpip/transport/udp/endpoint.go | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 66455ef46..dccb9a7eb 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -747,6 +747,10 @@ func (e *endpoint) Disconnect() *tcpip.Error { } e.state = StateBound } else { + if e.id.LocalPort != 0 { + // Release the ephemeral port. + e.stack.ReleasePort(e.effectiveNetProtos, ProtocolNumber, e.id.LocalAddress, e.id.LocalPort) + } e.state = StateInitial } |