Skip to content

Commit

Permalink
Correctly closing channel and socket when LocalPortForwarder fails to…
Browse files Browse the repository at this point in the history
… open it. (Fix #175)
  • Loading branch information
akandratovich authored and hierynomus committed Mar 27, 2015
1 parent 1e061ae commit e6c7c17
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 19 deletions.
26 changes: 26 additions & 0 deletions src/main/java/com/hierynomus/sshj/socket/Sockets.java
Original file line number Diff line number Diff line change
@@ -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();
}
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -23,6 +24,8 @@
import java.net.Socket;
import java.util.concurrent.TimeUnit;

import static com.hierynomus.sshj.socket.Sockets.asCloseable;

public class SocketStreamCopyMonitor
extends Thread {

Expand All @@ -32,16 +35,6 @@ private SocketStreamCopyMonitor(Runnable r) {
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) {
Expand All @@ -54,7 +47,7 @@ public void run() {
}
} catch (IOException ignored) {
} finally {
IOUtils.closeQuietly(channel, wrapSocket(socket));
IOUtils.closeQuietly(channel, asCloseable(socket));
}
}
}).start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -30,6 +30,8 @@
import java.net.Socket;
import java.util.concurrent.TimeUnit;

import static com.hierynomus.sshj.socket.Sockets.asCloseable;

public class LocalPortForwarder {

public static class Parameters {
Expand Down Expand Up @@ -112,11 +114,15 @@ public LocalPortForwarder(Connection conn, Parameters parameters, ServerSocket s
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;
}
}

/**
Expand All @@ -130,7 +136,7 @@ public void listen()
while (!Thread.currentThread().isInterrupted()) {
final Socket socket = serverSocket.accept();
log.debug("Got connection from {}", socket.getRemoteSocketAddress());
openChannel(socket).start();
startChannel(socket);
}
log.debug("Interrupted!");
}
Expand Down

0 comments on commit e6c7c17

Please sign in to comment.