You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2018/07/10 04:24:59 UTC
[2/3] mina-sshd git commit: [SSHD-832] Allow users to specify a local
socket address when creating an SSH client connection
[SSHD-832] Allow users to specify a local socket address when creating an SSH client connection
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/f1cc8509
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/f1cc8509
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/f1cc8509
Branch: refs/heads/master
Commit: f1cc85099aab8f8d9e09c054bcbbeea18fd669b1
Parents: 20dedf3
Author: Lyor Goldstein <ly...@gmail.com>
Authored: Mon Jul 9 21:11:41 2018 +0300
Committer: Goldstein Lyor <ly...@c-b4.com>
Committed: Tue Jul 10 07:24:51 2018 +0300
----------------------------------------------------------------------
.../java/org/apache/sshd/client/SshClient.java | 41 ++++++++-------
.../client/session/ClientSessionCreator.java | 52 ++++++++++++++++++--
.../AbstractSimpleClientSessionCreator.java | 19 ++++++-
.../org/apache/sshd/common/AttributeStore.java | 4 +-
.../apache/sshd/common/io/IoConnectFuture.java | 2 +-
.../org/apache/sshd/common/io/IoSession.java | 11 ++---
.../apache/sshd/common/io/IoWriteFuture.java | 2 +-
7 files changed, 99 insertions(+), 32 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1cc8509/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 733304f..143e4d7 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
@@ -131,7 +131,6 @@ import org.apache.sshd.common.util.net.SshdSocketAddress;
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public class SshClient extends AbstractFactoryManager implements ClientFactoryManager, ClientSessionCreator, Closeable {
-
public static final Factory<SshClient> DEFAULT_SSH_CLIENT_FACTORY = SshClient::new;
/**
@@ -433,7 +432,9 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
}
@Override
- public ConnectFuture connect(String username, String host, int port) throws IOException {
+ public ConnectFuture connect(
+ String username, String host, int port, SocketAddress localAddress)
+ throws IOException {
HostConfigEntryResolver resolver = getHostConfigEntryResolver();
HostConfigEntry entry = resolver.resolveEffectiveHost(host, port, username);
if (entry == null) {
@@ -455,14 +456,16 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
}
}
- return connect(entry);
+ return connect(entry, localAddress);
}
@Override
- public ConnectFuture connect(String username, SocketAddress address) throws IOException {
- Objects.requireNonNull(address, "No target address");
- if (address instanceof InetSocketAddress) {
- InetSocketAddress inetAddress = (InetSocketAddress) address;
+ public ConnectFuture connect(
+ String username, SocketAddress targetAddress, SocketAddress localAddress)
+ throws IOException {
+ Objects.requireNonNull(targetAddress, "No target address");
+ if (targetAddress instanceof InetSocketAddress) {
+ InetSocketAddress inetAddress = (InetSocketAddress) targetAddress;
String host = ValidateUtils.checkNotNullAndNotEmpty(inetAddress.getHostString(), "No host");
int port = inetAddress.getPort();
ValidateUtils.checkTrue(port > 0, "Invalid port: %d", port);
@@ -474,7 +477,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
log.debug("connect({}@{}:{}) no overrides", username, host, port);
}
- return doConnect(username, address, Collections.emptyList(), true);
+ return doConnect(username, targetAddress, localAddress, Collections.emptyList(), true);
} else {
if (log.isDebugEnabled()) {
log.debug("connect({}@{}:{}) effective: {}", username, host, port, entry);
@@ -484,21 +487,22 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
}
} else {
if (log.isDebugEnabled()) {
- log.debug("connect({}@{}) not an InetSocketAddress: {}", username, address, address.getClass().getName());
+ log.debug("connect({}@{}) not an InetSocketAddress: {}", username, targetAddress, targetAddress.getClass().getName());
}
- return doConnect(username, address, Collections.emptyList(), true);
+ return doConnect(username, targetAddress, localAddress, Collections.emptyList(), true);
}
}
@Override
- public ConnectFuture connect(HostConfigEntry hostConfig) throws IOException {
+ public ConnectFuture connect(HostConfigEntry hostConfig, SocketAddress localAddress) throws IOException {
Objects.requireNonNull(hostConfig, "No host configuration");
String host = ValidateUtils.checkNotNullAndNotEmpty(hostConfig.getHostName(), "No target host");
int port = hostConfig.getPort();
ValidateUtils.checkTrue(port > 0, "Invalid port: %d", port);
Collection<KeyPair> keys = loadClientIdentities(hostConfig.getIdentities(), IoUtils.EMPTY_LINK_OPTIONS);
- return doConnect(hostConfig.getUsername(), new InetSocketAddress(host, port), keys, !hostConfig.isIdentitiesOnly());
+ return doConnect(hostConfig.getUsername(), new InetSocketAddress(host, port),
+ localAddress, keys, !hostConfig.isIdentitiesOnly());
}
protected List<KeyPair> loadClientIdentities(Collection<String> locations, LinkOption... options) throws IOException {
@@ -544,16 +548,17 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
}
protected ConnectFuture doConnect(
- String username, SocketAddress address, Collection<? extends KeyPair> identities, boolean useDefaultIdentities)
- throws IOException {
+ String username, SocketAddress targetAddress, SocketAddress localAddress,
+ Collection<? extends KeyPair> identities, boolean useDefaultIdentities)
+ throws IOException {
if (connector == null) {
throw new IllegalStateException("SshClient not started. Please call start() method before connecting to a server");
}
- ConnectFuture connectFuture = new DefaultConnectFuture(username + "@" + address, null);
+ ConnectFuture connectFuture = new DefaultConnectFuture(username + "@" + targetAddress, null);
SshFutureListener<IoConnectFuture> listener =
- createConnectCompletionListener(connectFuture, username, address, identities, useDefaultIdentities);
- connector.connect(address, null).addListener(listener);
+ createConnectCompletionListener(connectFuture, username, targetAddress, identities, useDefaultIdentities);
+ connector.connect(targetAddress, localAddress).addListener(listener);
return connectFuture;
}
@@ -573,7 +578,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
if (t != null) {
if (log.isDebugEnabled()) {
log.debug("operationComplete({}@{}) failed ({}): {}",
- username, address, t.getClass().getSimpleName(), t.getMessage());
+ username, address, t.getClass().getSimpleName(), t.getMessage());
}
connectFuture.setException(t);
} else {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1cc8509/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionCreator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionCreator.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionCreator.java
index c3d46e5..4d0a7e8 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionCreator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionCreator.java
@@ -39,7 +39,24 @@ public interface ClientSessionCreator {
* connect to it
* @see #connect(HostConfigEntry)
*/
- ConnectFuture connect(String username, String host, int port) throws IOException;
+ default ConnectFuture connect(String username, String host, int port) throws IOException {
+ return connect(username, host, port, null);
+ }
+
+ /**
+ * Resolves the <U>effective</U> {@link HostConfigEntry} and connects to it
+ *
+ * @param username The intended username
+ * @param host The target host name/address - never {@code null}/empty
+ * @param port The target port
+ * @param localAddress The local address to use - if {@code null} an
+ * automatic ephemeral port and bind address is used
+ * @return A {@link ConnectFuture}
+ * @throws IOException If failed to resolve the effective target or
+ * connect to it
+ * @see #connect(HostConfigEntry)
+ */
+ ConnectFuture connect(String username, String host, int port, SocketAddress localAddress) throws IOException;
/**
* Resolves the <U>effective</U> {@link HostConfigEntry} and connects to it
@@ -53,12 +70,41 @@ public interface ClientSessionCreator {
* connect to it
* @see #connect(HostConfigEntry)
*/
- ConnectFuture connect(String username, SocketAddress address) throws IOException;
+ default ConnectFuture connect(String username, SocketAddress address) throws IOException {
+ return connect(username, address, null);
+ }
+
+ /**
+ * Resolves the <U>effective</U> {@link HostConfigEntry} and connects to it
+ *
+ * @param username The intended username
+ * @param targetAddress The intended target {@link SocketAddress} - never {@code null}.
+ * If this is an {@link java.net.InetSocketAddress} then the <U>effective</U>
+ * {@link HostConfigEntry} is resolved and used.
+ * @param localAddress The local address to use - if {@code null} an
+ * automatic ephemeral port and bind address is used
+ * @return A {@link ConnectFuture}
+ * @throws IOException If failed to resolve the effective target or
+ * connect to it
+ * @see #connect(HostConfigEntry)
+ */
+ ConnectFuture connect(String username, SocketAddress targetAddress, SocketAddress localAddress) throws IOException;
+
+ /**
+ * @param hostConfig The effective {@link HostConfigEntry} to connect to - never {@code null}
+ * @return A {@link ConnectFuture}
+ * @throws IOException If failed to create the connection future
+ */
+ default ConnectFuture connect(HostConfigEntry hostConfig) throws IOException {
+ return connect(hostConfig, null);
+ }
/**
* @param hostConfig The effective {@link HostConfigEntry} to connect to - never {@code null}
+ * @param localAddress The local address to use - if {@code null} an
+ * automatic ephemeral port and bind address is used
* @return A {@link ConnectFuture}
* @throws IOException If failed to create the connection future
*/
- ConnectFuture connect(HostConfigEntry hostConfig) throws IOException;
+ ConnectFuture connect(HostConfigEntry hostConfig, SocketAddress localAddress) throws IOException;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1cc8509/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClientSessionCreator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClientSessionCreator.java b/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClientSessionCreator.java
index b929c6f..3dd904f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClientSessionCreator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClientSessionCreator.java
@@ -136,7 +136,7 @@ public abstract class AbstractSimpleClientSessionCreator extends AbstractSimpleC
* @return The {@link SimpleClient} wrapper. <B>Note:</B> closing the wrapper
* also closes the underlying sessions creator.
*/
- public static SimpleClient wrap(final ClientSessionCreator creator, final Channel channel) {
+ public static SimpleClient wrap(ClientSessionCreator creator, Channel channel) {
Objects.requireNonNull(creator, "No sessions creator");
Objects.requireNonNull(channel, "No channel");
return new AbstractSimpleClientSessionCreator() {
@@ -146,16 +146,33 @@ public abstract class AbstractSimpleClientSessionCreator extends AbstractSimpleC
}
@Override
+ public ConnectFuture connect(String username, String host, int port, SocketAddress localAddress)
+ throws IOException {
+ return creator.connect(username, host, port, localAddress);
+ }
+
+ @Override
public ConnectFuture connect(String username, SocketAddress address) throws IOException {
return creator.connect(username, address);
}
@Override
+ public ConnectFuture connect(String username, SocketAddress targetAddress, SocketAddress localAddress)
+ throws IOException {
+ return creator.connect(username, targetAddress, localAddress);
+ }
+
+ @Override
public ConnectFuture connect(HostConfigEntry hostConfig) throws IOException {
return creator.connect(hostConfig);
}
@Override
+ public ConnectFuture connect(HostConfigEntry hostConfig, SocketAddress localAddress) throws IOException {
+ return creator.connect(hostConfig, localAddress);
+ }
+
+ @Override
public boolean isOpen() {
return channel.isOpen();
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1cc8509/sshd-core/src/main/java/org/apache/sshd/common/AttributeStore.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/AttributeStore.java b/sshd-core/src/main/java/org/apache/sshd/common/AttributeStore.java
index 4907efa..2b58d94 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/AttributeStore.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/AttributeStore.java
@@ -66,7 +66,7 @@ public interface AttributeStore {
*
* @param <T> The generic attribute type
* @param key The key of the attribute; must not be {@code null}.
- * @return <tt>null</tt> if there is no value associated with the specified key
+ * @return {@code null} if there is no value associated with the specified key
*/
<T> T getAttribute(AttributeKey<T> key);
@@ -95,7 +95,7 @@ public interface AttributeStore {
*
* @param <T> The generic attribute type
* @param key The key of the attribute; must not be {@code null}.
- * @return <tt>null</tt> if there is no value associated with the specified key
+ * @return {@code null} if there is no value associated with the specified key
*/
<T> T resolveAttribute(AttributeKey<T> key);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1cc8509/sshd-core/src/main/java/org/apache/sshd/common/io/IoConnectFuture.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoConnectFuture.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoConnectFuture.java
index 91f2a90..0f946b3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoConnectFuture.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoConnectFuture.java
@@ -32,7 +32,7 @@ public interface IoConnectFuture extends SshFuture<IoConnectFuture> {
/**
* Returns the cause of the connection failure.
*
- * @return <tt>null</tt> if the connect operation is not finished yet,
+ * @return {@code null} if the connect operation is not finished yet,
* or if the connection attempt is successful.
* @see #getSession()
*/
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1cc8509/sshd-core/src/main/java/org/apache/sshd/common/io/IoSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoSession.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoSession.java
index 1c629bd..489eda7 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoSession.java
@@ -34,7 +34,7 @@ public interface IoSession extends PacketWriter, Closeable {
* Returns the value of the user-defined attribute of this session.
*
* @param key the key of the attribute
- * @return <tt>null</tt> if there is no attribute with the specified key
+ * @return {@code null} if there is no attribute with the specified key
*/
Object getAttribute(Object key);
@@ -43,7 +43,7 @@ public interface IoSession extends PacketWriter, Closeable {
*
* @param key the key of the attribute
* @param value the value of the attribute
- * @return The old value of the attribute. <tt>null</tt> if it is new.
+ * @return The old value of the attribute. {@code null} if it is new.
*/
Object setAttribute(Object key, Object value);
@@ -61,7 +61,7 @@ public interface IoSession extends PacketWriter, Closeable {
*
* @param key The key of the attribute we want to set
* @param value The value we want to set
- * @return The old value of the attribute. <tt>null</tt> if not found.
+ * @return The old value of the attribute. {@code null} if not found.
*/
Object setAttributeIfAbsent(Object key, Object value);
@@ -69,7 +69,7 @@ public interface IoSession extends PacketWriter, Closeable {
* Removes a user-defined attribute with the specified key.
*
* @param key The key of the attribute we want to remove
- * @return The old value of the attribute - <tt>null</tt> if not found.
+ * @return The old value of the attribute - {@code null} if not found.
*/
Object removeAttribute(Object key);
@@ -79,8 +79,7 @@ public interface IoSession extends PacketWriter, Closeable {
SocketAddress getRemoteAddress();
/**
- * @return the socket address of local machine which is associated with this
- * session.
+ * @return the socket address of local machine which is associated with this session.
*/
SocketAddress getLocalAddress();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1cc8509/sshd-core/src/main/java/org/apache/sshd/common/io/IoWriteFuture.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoWriteFuture.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoWriteFuture.java
index 95d33bd..543f285 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoWriteFuture.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoWriteFuture.java
@@ -30,7 +30,7 @@ public interface IoWriteFuture extends SshFuture<IoWriteFuture>, VerifiableFutur
/**
* @return the cause of the write failure if and only if the write
* operation has failed due to an {@link Exception}. Otherwise,
- * <tt>null</tt> is returned (use {@link #isDone()} to distinguish
+ * {@code null} is returned (use {@link #isDone()} to distinguish
* between the two.
*/
Throwable getException();