8231260: (dc) DatagramChannel::disconnect changes the port of the local address to 0 (lnx)

DatagramChannel::disconnect will attempt to rebind to the original port if the local port switches back to 0 after the association is disolved by the system.

Reviewed-by: alanb, chegar, fweimer
This commit is contained in:
Daniel Fuchs 2019-10-09 17:38:58 +01:00
parent fddd963cec
commit a690af3832
3 changed files with 134 additions and 3 deletions

View file

@ -875,6 +875,11 @@ class DatagramChannelImpl
if (state == ST_CONNECTED)
throw new AlreadyConnectedException();
// ensure that the socket is bound
if (localAddress == null) {
bindInternal(null);
}
int n = Net.connect(family,
fd,
isa.getAddress(),
@ -932,8 +937,21 @@ class DatagramChannelImpl
remoteAddress = null;
state = ST_UNCONNECTED;
// refresh local address
localAddress = Net.localAddress(fd);
// check whether rebind is needed
InetSocketAddress isa = Net.localAddress(fd);
if (isa.getPort() == 0) {
// On Linux, if bound to ephemeral port,
// disconnect does not preserve that port.
// In this case, try to rebind to the previous port.
int port = localAddress.getPort();
localAddress = isa; // in case Net.bind fails
Net.bind(family, fd, isa.getAddress(), port);
isa = Net.localAddress(fd); // refresh address
assert isa.getPort() == port;
}
// refresh localAddress
localAddress = isa;
}
} finally {
writeLock.unlock();