Correctly closing channel and socket when LocalPortForwarder fails to open it. (Fix #175)

This commit is contained in:
Andrew Kondratovich
2015-02-12 11:27:08 +03:00
committed by Jeroen van Erp
parent 1e061aef25
commit e6c7c17664
3 changed files with 44 additions and 19 deletions

View File

@@ -0,0 +1,26 @@
package com.hierynomus.sshj.socket;
import java.io.Closeable;
import java.io.IOException;
import java.net.Socket;
public class Sockets {
/**
* Java 7 and up have Socket implemented as Closeable, whereas Java6 did not have this inheritance.
* @param socket The socket to wrap as Closeable
* @return
*/
public static Closeable asCloseable(final Socket socket) {
if (Closeable.class.isAssignableFrom(socket.getClass())) {
return Closeable.class.cast(socket);
} else {
return new Closeable() {
@Override
public void close() throws IOException {
socket.close();
}
};
}
}
}

View File

@@ -15,6 +15,7 @@
*/
package net.schmizz.sshj.connection.channel;
import com.hierynomus.sshj.socket.Sockets;
import net.schmizz.concurrent.Event;
import net.schmizz.sshj.common.IOUtils;
@@ -23,6 +24,8 @@ import java.io.IOException;
import java.net.Socket;
import java.util.concurrent.TimeUnit;
import static com.hierynomus.sshj.socket.Sockets.asCloseable;
public class SocketStreamCopyMonitor
extends Thread {
@@ -32,16 +35,6 @@ public class SocketStreamCopyMonitor
setDaemon(true);
}
private static Closeable wrapSocket(final Socket socket) {
return new Closeable() {
@Override
public void close()
throws IOException {
socket.close();
}
};
}
public static void monitor(final int frequency, final TimeUnit unit,
final Event<IOException> x, final Event<IOException> y,
final Channel channel, final Socket socket) {
@@ -54,7 +47,7 @@ public class SocketStreamCopyMonitor
}
} catch (IOException ignored) {
} finally {
IOUtils.closeQuietly(channel, wrapSocket(socket));
IOUtils.closeQuietly(channel, asCloseable(socket));
}
}
}).start();

View File

@@ -16,12 +16,12 @@
package net.schmizz.sshj.connection.channel.direct;
import net.schmizz.concurrent.Event;
import net.schmizz.sshj.common.IOUtils;
import net.schmizz.sshj.common.SSHPacket;
import net.schmizz.sshj.common.StreamCopier;
import net.schmizz.sshj.connection.Connection;
import net.schmizz.sshj.connection.ConnectionException;
import net.schmizz.sshj.connection.channel.SocketStreamCopyMonitor;
import net.schmizz.sshj.transport.TransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -30,6 +30,8 @@ import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.TimeUnit;
import static com.hierynomus.sshj.socket.Sockets.asCloseable;
public class LocalPortForwarder {
public static class Parameters {
@@ -112,11 +114,15 @@ public class LocalPortForwarder {
this.serverSocket = serverSocket;
}
protected DirectTCPIPChannel openChannel(Socket socket)
throws TransportException, ConnectionException {
final DirectTCPIPChannel chan = new DirectTCPIPChannel(conn, socket, parameters);
chan.open();
return chan;
private void startChannel(Socket socket) throws IOException {
DirectTCPIPChannel chan = new DirectTCPIPChannel(conn, socket, parameters);
try {
chan.open();
chan.start();
} catch (IOException e) {
IOUtils.closeQuietly(chan, asCloseable(socket));
throw e;
}
}
/**
@@ -130,7 +136,7 @@ public class LocalPortForwarder {
while (!Thread.currentThread().isInterrupted()) {
final Socket socket = serverSocket.accept();
log.debug("Got connection from {}", socket.getRemoteSocketAddress());
openChannel(socket).start();
startChannel(socket);
}
log.debug("Interrupted!");
}