summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/transport/udp
diff options
context:
space:
mode:
authorIan Gudger <igudger@google.com>2019-09-09 14:00:51 -0700
committergVisor bot <gvisor-bot@google.com>2019-09-09 14:02:00 -0700
commit9dfcd8b09fceff830c880065db66821e53c500b0 (patch)
treed74957c5aec88a3c867f141435add6ba219d45ab /pkg/tcpip/transport/udp
parent3733b9b893ec33877b1b46c56fe07c3856942d3f (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
Diffstat (limited to 'pkg/tcpip/transport/udp')
-rw-r--r--pkg/tcpip/transport/udp/endpoint.go4
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
}