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

View File

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