Close raw channel when bind / connect fails (#25840)

Currently we are failing to close socket channels when the initial bind
or connect operation fails. This leaves the file descriptor hanging
around. This closes the channel when an exception occurs during bind or
connect.
This commit is contained in:
Tim Brooks 2017-07-22 13:55:33 -05:00 committed by GitHub
parent c72fc55283
commit 0a4b38b60c
1 changed files with 23 additions and 4 deletions

View File

@ -27,6 +27,7 @@ import org.elasticsearch.transport.nio.AcceptingSelector;
import org.elasticsearch.transport.nio.SocketSelector; import org.elasticsearch.transport.nio.SocketSelector;
import org.elasticsearch.transport.nio.TcpReadHandler; import org.elasticsearch.transport.nio.TcpReadHandler;
import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
@ -113,8 +114,13 @@ public class ChannelFactory {
SocketChannel openNioChannel(InetSocketAddress remoteAddress) throws IOException { SocketChannel openNioChannel(InetSocketAddress remoteAddress) throws IOException {
SocketChannel socketChannel = SocketChannel.open(); SocketChannel socketChannel = SocketChannel.open();
configureSocketChannel(socketChannel); try {
PrivilegedSocketAccess.connect(socketChannel, remoteAddress); configureSocketChannel(socketChannel);
PrivilegedSocketAccess.connect(socketChannel, remoteAddress);
} catch (IOException e) {
closeRawChannel(socketChannel, e);
throw e;
}
return socketChannel; return socketChannel;
} }
@ -129,11 +135,24 @@ public class ChannelFactory {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false); serverSocketChannel.configureBlocking(false);
ServerSocket socket = serverSocketChannel.socket(); ServerSocket socket = serverSocketChannel.socket();
socket.setReuseAddress(tcpReusedAddress); try {
serverSocketChannel.bind(address); socket.setReuseAddress(tcpReusedAddress);
serverSocketChannel.bind(address);
} catch (IOException e) {
closeRawChannel(serverSocketChannel, e);
throw e;
}
return serverSocketChannel; return serverSocketChannel;
} }
private void closeRawChannel(Closeable c, IOException e) {
try {
c.close();
} catch (IOException closeException) {
e.addSuppressed(closeException);
}
}
private void configureSocketChannel(SocketChannel channel) throws IOException { private void configureSocketChannel(SocketChannel channel) throws IOException {
channel.configureBlocking(false); channel.configureBlocking(false);
Socket socket = channel.socket(); Socket socket = channel.socket();