[SSHD-832] Allow user to specify local address for port forwarding
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/20dedf32 Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/20dedf32 Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/20dedf32 Branch: refs/heads/master Commit: 20dedf3262bc7d067cf69fe3edab2a004ac40698 Parents: ace6c9f Author: Markus Opitz <[email protected]> Authored: Mon Jul 9 20:56:42 2018 +0300 Committer: Goldstein Lyor <[email protected]> Committed: Tue Jul 10 07:24:51 2018 +0300 ---------------------------------------------------------------------- .../src/main/java/org/apache/sshd/client/SshClient.java | 5 +++-- .../java/org/apache/sshd/common/io/IoConnector.java | 10 ++++++++-- .../org/apache/sshd/common/io/nio2/Nio2Connector.java | 5 ++++- .../apache/sshd/server/forward/TcpipServerChannel.java | 12 +++++++++++- .../org/apache/sshd/common/io/mina/MinaConnector.java | 4 ++-- .../java/org/apache/sshd/netty/NettyIoConnector.java | 9 +++++++-- 6 files changed, 35 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/20dedf32/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java index 31e4234..733304f 100644 --- a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java +++ b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java @@ -551,8 +551,9 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa } ConnectFuture connectFuture = new DefaultConnectFuture(username + "@" + address, null); - SshFutureListener<IoConnectFuture> listener = createConnectCompletionListener(connectFuture, username, address, identities, useDefaultIdentities); - connector.connect(address).addListener(listener); + SshFutureListener<IoConnectFuture> listener = + createConnectCompletionListener(connectFuture, username, address, identities, useDefaultIdentities); + connector.connect(address, null).addListener(listener); return connectFuture; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/20dedf32/sshd-core/src/main/java/org/apache/sshd/common/io/IoConnector.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoConnector.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoConnector.java index 98ab8be..c546d44 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoConnector.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoConnector.java @@ -21,9 +21,15 @@ package org.apache.sshd.common.io; import java.net.SocketAddress; /** + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ public interface IoConnector extends IoService { - IoConnectFuture connect(SocketAddress address); - + /** + * @param targetAddress The target address to connect to + * @param localAddress The local address to use - if {@code null} an + * automatic ephemeral port and bind address is used + * @return The {@link IoConnectFuture future} representing the connection request + */ + IoConnectFuture connect(SocketAddress targetAddress, SocketAddress localAddress); } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/20dedf32/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java index 7ccb5de..2924caf 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java @@ -43,7 +43,7 @@ public class Nio2Connector extends Nio2Service implements IoConnector { } @Override - public IoConnectFuture connect(SocketAddress address) { + public IoConnectFuture connect(SocketAddress address, SocketAddress localAddress) { boolean debugEnabled = log.isDebugEnabled(); if (debugEnabled) { log.debug("Connecting to {}", address); @@ -56,6 +56,9 @@ public class Nio2Connector extends Nio2Service implements IoConnector { AsynchronousChannelGroup group = getChannelGroup(); channel = openAsynchronousSocketChannel(address, group); socket = setSocketOptions(channel); + if (localAddress != null) { + socket.bind(localAddress); + } Nio2CompletionHandler<Void, Object> completionHandler = ValidateUtils.checkNotNull(createConnectionCompletionHandler(future, socket, getFactoryManager(), getIoHandler()), "No connection completion handler created for %s", http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/20dedf32/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java b/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java index a16a0de..949fd55 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java @@ -21,6 +21,7 @@ package org.apache.sshd.server.forward; import java.io.IOException; import java.io.OutputStream; import java.net.ConnectException; +import java.net.SocketAddress; import java.util.Collection; import java.util.Objects; import java.util.concurrent.ExecutorService; @@ -102,6 +103,7 @@ public class TcpipServerChannel extends AbstractServerChannel implements Forward private SshdSocketAddress tunnelEntrance; private SshdSocketAddress tunnelExit; private SshdSocketAddress originatorAddress; + private SocketAddress localAddress; public TcpipServerChannel(ForwardingFilter.Type type) { this.type = Objects.requireNonNull(type, "No channel type specified"); @@ -111,6 +113,14 @@ public class TcpipServerChannel extends AbstractServerChannel implements Forward return type; } + public SocketAddress getLocalAddress() { + return localAddress; + } + + public void setLocalAddress(SocketAddress localAddress) { + this.localAddress = localAddress; + } + @Override public SshdSocketAddress getTunnelEntrance() { return tunnelEntrance; @@ -227,7 +237,7 @@ public class TcpipServerChannel extends AbstractServerChannel implements Forward IoServiceFactory ioServiceFactory = manager.getIoServiceFactory(); connector = ioServiceFactory.createConnector(handler); - IoConnectFuture future = connector.connect(address.toInetSocketAddress()); + IoConnectFuture future = connector.connect(address.toInetSocketAddress(), getLocalAddress()); future.addListener(future1 -> handleChannelConnectResult(f, future1)); return f; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/20dedf32/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaConnector.java ---------------------------------------------------------------------- diff --git a/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaConnector.java b/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaConnector.java index 77bb90a..22e85cc 100644 --- a/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaConnector.java +++ b/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaConnector.java @@ -74,7 +74,7 @@ public class MinaConnector extends MinaService implements org.apache.sshd.common } @Override - public IoConnectFuture connect(SocketAddress address) { + public IoConnectFuture connect(SocketAddress address, SocketAddress localAddress) { class Future extends DefaultSshFuture<IoConnectFuture> implements IoConnectFuture { Future(Object lock) { super(address, lock); @@ -110,7 +110,7 @@ public class MinaConnector extends MinaService implements org.apache.sshd.common IoConnectFuture future = new Future(null); IoConnector connector = getConnector(); - ConnectFuture connectFuture = connector.connect(address); + ConnectFuture connectFuture = connector.connect(address, localAddress); connectFuture.addListener((IoFutureListener<ConnectFuture>) cf -> { Throwable t = cf.getException(); if (t != null) { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/20dedf32/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoConnector.java ---------------------------------------------------------------------- diff --git a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoConnector.java b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoConnector.java index c485790..9dde3d9 100644 --- a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoConnector.java +++ b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoConnector.java @@ -70,14 +70,19 @@ public class NettyIoConnector extends NettyIoService implements IoConnector { } @Override - public IoConnectFuture connect(SocketAddress address) { + public IoConnectFuture connect(SocketAddress address, SocketAddress localAddress) { boolean debugEnabled = log.isDebugEnabled(); if (debugEnabled) { log.debug("Connecting to {}", address); } IoConnectFuture future = new DefaultIoConnectFuture(address, null); - ChannelFuture chf = bootstrap.connect(address); + ChannelFuture chf; + if (localAddress != null) { + chf = bootstrap.connect(address, localAddress); + } else { + chf = bootstrap.connect(address); + } Channel channel = chf.channel(); channel.attr(CONNECT_FUTURE_KEY).set(future); chf.addListener(cf -> {
