Close raw channel when bind / connect fails
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.
@@ -27,6 +27,7 @@ import org.elasticsearch.transport.nio.AcceptingSelector;
import org.elasticsearch.transport.nio.SocketSelector;
import org.elasticsearch.transport.nio.TcpReadHandler;
+import java.io.Closeable;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
@@ -113,8 +114,13 @@ public class ChannelFactory {
SocketChannel openNioChannel(InetSocketAddress remoteAddress) throws IOException {
SocketChannel socketChannel = SocketChannel.open();
+ try {
configureSocketChannel(socketChannel);
PrivilegedSocketAccess.connect(socketChannel, remoteAddress);
+ } catch (IOException e) {
+ closeRawChannel(socketChannel, e);
+ throw e;
+ }
return socketChannel;
}
@@ -129,11 +135,24 @@ public class ChannelFactory {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
ServerSocket socket = serverSocketChannel.socket();
+ try {
socket.setReuseAddress(tcpReusedAddress);
serverSocketChannel.bind(address);
+ } catch (IOException e) {
+ closeRawChannel(serverSocketChannel, e);
+ throw e;
+ }
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 {
channel.configureBlocking(false);
Socket socket = channel.socket();
