mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 23:30:55 +03:00
Correctly closing channel and socket when LocalPortForwarder fails to open it. (Fix #175)
This commit is contained in:
committed by
Jeroen van Erp
parent
1e061aef25
commit
e6c7c17664
26
src/main/java/com/hierynomus/sshj/socket/Sockets.java
Normal file
26
src/main/java/com/hierynomus/sshj/socket/Sockets.java
Normal 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();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
|||||||
@@ -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!");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user