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 2016/12/10 09:25:21 UTC
mina-sshd git commit: [SSHD-722] Propagate socket settings on
accepted SSHD server AsynchronousServerSocketChannel
Repository: mina-sshd
Updated Branches:
refs/heads/master 168adf20a -> 331bdfc9d
[SSHD-722] Propagate socket settings on accepted SSHD server AsynchronousServerSocketChannel
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/331bdfc9
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/331bdfc9
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/331bdfc9
Branch: refs/heads/master
Commit: 331bdfc9d9ef7473dadbd674548a08a7c2a9cc88
Parents: 168adf2
Author: Lyor Goldstein <ly...@gmail.com>
Authored: Sat Dec 10 11:25:30 2016 +0200
Committer: Lyor Goldstein <ly...@gmail.com>
Committed: Sat Dec 10 11:25:30 2016 +0200
----------------------------------------------------------------------
.../keys/loader/putty/RSAPuttyKeyDecoder.java | 1 -
.../io/DefaultIoServiceFactoryFactory.java | 2 +-
.../org/apache/sshd/common/io/IoAcceptor.java | 1 +
.../org/apache/sshd/common/io/IoHandler.java | 1 +
.../org/apache/sshd/common/io/IoService.java | 6 ++
.../apache/sshd/common/io/IoServiceFactory.java | 1 +
.../sshd/common/io/mina/MinaAcceptor.java | 23 +++---
.../sshd/common/io/mina/MinaConnector.java | 24 ++++--
.../apache/sshd/common/io/mina/MinaService.java | 57 ++++++++++++---
.../sshd/common/io/nio2/Nio2Acceptor.java | 15 ++--
.../sshd/common/io/nio2/Nio2Connector.java | 11 +--
.../apache/sshd/common/io/nio2/Nio2Service.java | 77 +++++++++++++++-----
.../sshd/common/io/nio2/Nio2ServiceFactory.java | 1 +
.../apache/sshd/common/io/nio2/Nio2Session.java | 1 +
.../java/org/apache/sshd/server/SshServer.java | 4 +-
.../sshd/common/io/nio2/Nio2ServiceTest.java | 73 +++++++++++++++++--
16 files changed, 221 insertions(+), 77 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/331bdfc9/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/RSAPuttyKeyDecoder.java
----------------------------------------------------------------------
diff --git a/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/RSAPuttyKeyDecoder.java b/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/RSAPuttyKeyDecoder.java
index b4f9687..d0de05d 100644
--- a/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/RSAPuttyKeyDecoder.java
+++ b/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/RSAPuttyKeyDecoder.java
@@ -67,5 +67,4 @@ public class RSAPuttyKeyDecoder extends AbstractPuttyKeyDecoder {
PrivateKey prvKey = kf.generatePrivate(prvSpec);
return Collections.singletonList(new KeyPair(pubKey, prvKey));
}
-
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/331bdfc9/sshd-core/src/main/java/org/apache/sshd/common/io/DefaultIoServiceFactoryFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/DefaultIoServiceFactoryFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/io/DefaultIoServiceFactoryFactory.java
index aad572d..cfba0f4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/DefaultIoServiceFactoryFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/DefaultIoServiceFactoryFactory.java
@@ -29,9 +29,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public class DefaultIoServiceFactoryFactory extends AbstractIoServiceFactoryFactory {
-
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultIoServiceFactoryFactory.class);
private IoServiceFactoryFactory factory;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/331bdfc9/sshd-core/src/main/java/org/apache/sshd/common/io/IoAcceptor.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoAcceptor.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoAcceptor.java
index ce38403..a86b73e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoAcceptor.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoAcceptor.java
@@ -27,6 +27,7 @@ import java.util.Set;
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public interface IoAcceptor extends IoService {
+ int DEFAULT_BACKLOG = 0;
void bind(Collection<? extends SocketAddress> addresses) throws IOException;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/331bdfc9/sshd-core/src/main/java/org/apache/sshd/common/io/IoHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoHandler.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoHandler.java
index 7a34d35..848604d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoHandler.java
@@ -21,6 +21,7 @@ package org.apache.sshd.common.io;
import org.apache.sshd.common.util.Readable;
/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public interface IoHandler {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/331bdfc9/sshd-core/src/main/java/org/apache/sshd/common/io/IoService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoService.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoService.java
index c73f8f2..69dcdee 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoService.java
@@ -23,8 +23,14 @@ import java.util.Map;
import org.apache.sshd.common.Closeable;
/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public interface IoService extends Closeable {
+ /**
+ * Socket reuse address.
+ * See {@link java.net.StandardSocketOptions#SO_REUSEADDR}
+ */
+ boolean DEFAULT_REUSE_ADDRESS = true;
/**
* Returns the map of all sessions which are currently managed by this
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/331bdfc9/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceFactory.java
index cec089c..6d8c261 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceFactory.java
@@ -21,6 +21,7 @@ package org.apache.sshd.common.io;
import org.apache.sshd.common.Closeable;
/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public interface IoServiceFactory extends Closeable {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/331bdfc9/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaAcceptor.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaAcceptor.java b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaAcceptor.java
index bfd87f6..c49315d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaAcceptor.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaAcceptor.java
@@ -34,11 +34,9 @@ import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.PropertyResolverUtils;
/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public class MinaAcceptor extends MinaService implements org.apache.sshd.common.io.IoAcceptor, IoHandler {
- public static final int DEFAULT_BACKLOG = 0;
- public static final boolean DEFAULT_REUSE_ADDRESS = true;
-
protected final AtomicReference<IoAcceptor> acceptorHolder = new AtomicReference<>(null);
// Acceptor
@@ -85,32 +83,37 @@ public class MinaAcceptor extends MinaService implements org.apache.sshd.common.
@Override
public void bind(Collection<? extends SocketAddress> addresses) throws IOException {
- getAcceptor().bind(addresses);
+ IoAcceptor acceptor = getAcceptor();
+ acceptor.bind(addresses);
}
@Override
public void bind(SocketAddress address) throws IOException {
- getAcceptor().bind(address);
+ IoAcceptor acceptor = getAcceptor();
+ acceptor.bind(address);
}
@Override
public void unbind() {
- getAcceptor().unbind();
+ IoAcceptor acceptor = getAcceptor();
+ acceptor.unbind();
}
@Override
public void unbind(Collection<? extends SocketAddress> addresses) {
- getAcceptor().unbind(addresses);
+ IoAcceptor acceptor = getAcceptor();
+ acceptor.unbind(addresses);
}
@Override
public void unbind(SocketAddress address) {
- getAcceptor().unbind(address);
+ IoAcceptor acceptor = getAcceptor();
+ acceptor.unbind(address);
}
@Override
public Set<SocketAddress> getBoundAddresses() {
- return getAcceptor().getLocalAddresses();
+ IoAcceptor acceptor = getAcceptor();
+ return acceptor.getLocalAddresses();
}
-
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/331bdfc9/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaConnector.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaConnector.java b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaConnector.java
index 176d565..4b48787 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaConnector.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaConnector.java
@@ -26,6 +26,7 @@ import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.service.IoProcessor;
+import org.apache.mina.core.session.IoSession;
import org.apache.mina.transport.socket.nio.NioSession;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.apache.sshd.common.FactoryManager;
@@ -33,9 +34,9 @@ import org.apache.sshd.common.future.DefaultSshFuture;
import org.apache.sshd.common.io.IoConnectFuture;
/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public class MinaConnector extends MinaService implements org.apache.sshd.common.io.IoConnector, IoHandler {
-
protected final AtomicReference<IoConnector> connectorHolder = new AtomicReference<>(null);
public MinaConnector(FactoryManager manager, org.apache.sshd.common.io.IoHandler handler, IoProcessor<NioSession> ioProcessor) {
@@ -61,7 +62,9 @@ public class MinaConnector extends MinaService implements org.apache.sshd.common
connectorHolder.set(connector);
}
- log.debug("Created IoConnector");
+ if (log.isDebugEnabled()) {
+ log.debug("Created IoConnector");
+ }
return connector;
}
@@ -104,17 +107,22 @@ public class MinaConnector extends MinaService implements org.apache.sshd.common
setValue(exception);
}
}
- final IoConnectFuture future = new Future(null);
- getConnector().connect(address).addListener((IoFutureListener<ConnectFuture>) cf -> {
- if (cf.getException() != null) {
- future.setException(cf.getException());
+
+ IoConnectFuture future = new Future(null);
+ IoConnector connector = getConnector();
+ ConnectFuture connectFuture = connector.connect(address);
+ connectFuture.addListener((IoFutureListener<ConnectFuture>) cf -> {
+ Throwable t = cf.getException();
+ if (t != null) {
+ future.setException(t);
} else if (cf.isCanceled()) {
future.cancel();
} else {
- future.setSession(getSession(cf.getSession()));
+ IoSession ioSession = cf.getSession();
+ org.apache.sshd.common.io.IoSession sshSession = getSession(ioSession);
+ future.setSession(sshSession);
}
});
return future;
}
-
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/331bdfc9/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaService.java b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaService.java
index 2bff584..65014fc 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaService.java
@@ -21,6 +21,7 @@ package org.apache.sshd.common.io.mina;
import java.util.HashMap;
import java.util.Map;
+import org.apache.mina.core.RuntimeIoException;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.service.IoProcessor;
@@ -33,9 +34,11 @@ import org.apache.mina.transport.socket.nio.NioSession;
import org.apache.sshd.common.Closeable;
import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.PropertyResolverUtils;
+import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.closeable.AbstractCloseable;
/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public abstract class MinaService extends AbstractCloseable implements org.apache.sshd.common.io.IoService, IoHandler, Closeable {
protected final FactoryManager manager;
@@ -52,12 +55,14 @@ public abstract class MinaService extends AbstractCloseable implements org.apach
protected abstract IoService getIoService();
public void dispose() {
- getIoService().dispose();
+ IoService ioService = getIoService();
+ ioService.dispose();
}
@Override
protected void doCloseImmediately() {
- getIoService().dispose();
+ IoService ioService = getIoService();
+ ioService.dispose();
super.doCloseImmediately();
}
@@ -123,33 +128,62 @@ public abstract class MinaService extends AbstractCloseable implements org.apach
}
protected void configure(SocketSessionConfig config) {
- Integer intVal;
- Boolean boolVal;
- boolVal = getBoolean(FactoryManager.SOCKET_KEEPALIVE);
+ Boolean boolVal = getBoolean(FactoryManager.SOCKET_KEEPALIVE);
if (boolVal != null) {
- config.setKeepAlive(boolVal);
+ try {
+ config.setKeepAlive(boolVal);
+ } catch (RuntimeIoException t) {
+ handleConfigurationError(config, FactoryManager.SOCKET_KEEPALIVE, boolVal, t);
+ }
}
- intVal = getInteger(FactoryManager.SOCKET_SNDBUF);
+
+ Integer intVal = getInteger(FactoryManager.SOCKET_SNDBUF);
if (intVal != null) {
- config.setSendBufferSize(intVal);
+ try {
+ config.setSendBufferSize(intVal);
+ } catch (RuntimeIoException t) {
+ handleConfigurationError(config, FactoryManager.SOCKET_SNDBUF, intVal, t);
+ }
}
+
intVal = getInteger(FactoryManager.SOCKET_RCVBUF);
if (intVal != null) {
- config.setReceiveBufferSize(intVal);
+ try {
+ config.setReceiveBufferSize(intVal);
+ } catch (RuntimeIoException t) {
+ handleConfigurationError(config, FactoryManager.SOCKET_RCVBUF, intVal, t);
+ }
}
+
intVal = getInteger(FactoryManager.SOCKET_LINGER);
if (intVal != null) {
- config.setSoLinger(intVal);
+ try {
+ config.setSoLinger(intVal);
+ } catch (RuntimeIoException t) {
+ handleConfigurationError(config, FactoryManager.SOCKET_LINGER, intVal, t);
+ }
}
+
boolVal = getBoolean(FactoryManager.TCP_NODELAY);
if (boolVal != null) {
- config.setTcpNoDelay(boolVal);
+ try {
+ config.setTcpNoDelay(boolVal);
+ } catch (RuntimeIoException t) {
+ handleConfigurationError(config, FactoryManager.TCP_NODELAY, boolVal, t);
+ }
}
+
if (sessionConfig != null) {
config.setAll(sessionConfig);
}
}
+ protected void handleConfigurationError(SocketSessionConfig config, String propName, Object propValue, RuntimeIoException t) {
+ Throwable e = GenericUtils.resolveExceptionCause(t);
+ log.warn("handleConfigurationError({}={}) failed ({}) to configure: {}",
+ propName, propValue, e.getClass().getSimpleName(), e.getMessage());
+ }
+
protected Integer getInteger(String property) {
return PropertyResolverUtils.getInteger(manager, property);
}
@@ -157,5 +191,4 @@ public abstract class MinaService extends AbstractCloseable implements org.apach
protected Boolean getBoolean(String property) {
return PropertyResolverUtils.getBoolean(manager, property);
}
-
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/331bdfc9/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
index 83d79db..23be6c1 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
@@ -20,7 +20,6 @@ package org.apache.sshd.common.io.nio2;
import java.io.IOException;
import java.net.SocketAddress;
-import java.net.StandardSocketOptions;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
@@ -41,10 +40,9 @@ import org.apache.sshd.common.io.IoHandler;
import org.apache.sshd.common.util.ValidateUtils;
/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public class Nio2Acceptor extends Nio2Service implements IoAcceptor {
- public static final int DEFAULT_BACKLOG = 0;
-
protected final Map<SocketAddress, AsynchronousServerSocketChannel> channels = new ConcurrentHashMap<>();
private int backlog = DEFAULT_BACKLOG;
@@ -60,13 +58,9 @@ public class Nio2Acceptor extends Nio2Service implements IoAcceptor {
if (log.isDebugEnabled()) {
log.debug("Binding Nio2Acceptor to address {}", address);
}
- AsynchronousServerSocketChannel socket = openAsynchronousServerSocketChannel(address, group);
- setOption(socket, FactoryManager.SOCKET_KEEPALIVE, StandardSocketOptions.SO_KEEPALIVE, null);
- setOption(socket, FactoryManager.SOCKET_LINGER, StandardSocketOptions.SO_LINGER, null);
- setOption(socket, FactoryManager.SOCKET_RCVBUF, StandardSocketOptions.SO_RCVBUF, null);
- setOption(socket, FactoryManager.SOCKET_REUSEADDR, StandardSocketOptions.SO_REUSEADDR, Boolean.TRUE);
- setOption(socket, FactoryManager.SOCKET_SNDBUF, StandardSocketOptions.SO_SNDBUF, null);
- setOption(socket, FactoryManager.TCP_NODELAY, StandardSocketOptions.TCP_NODELAY, null);
+
+ AsynchronousServerSocketChannel socket =
+ setSocketOptions(openAsynchronousServerSocketChannel(address, group));
socket.bind(address, backlog);
SocketAddress local = socket.getLocalAddress();
channels.put(local, socket);
@@ -172,6 +166,7 @@ public class Nio2Acceptor extends Nio2Service implements IoAcceptor {
try {
// Create a session
IoHandler handler = getIoHandler();
+ setSocketOptions(result);
session = Objects.requireNonNull(createSession(Nio2Acceptor.this, address, result, handler), "No NIO2 session created");
handler.sessionCreated(session);
sessions.put(session.getId(), session);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/331bdfc9/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 2c2b6a5..c7a9fe5 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
@@ -20,7 +20,6 @@ package org.apache.sshd.common.io.nio2;
import java.io.IOException;
import java.net.SocketAddress;
-import java.net.StandardSocketOptions;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousSocketChannel;
@@ -49,14 +48,8 @@ public class Nio2Connector extends Nio2Service implements IoConnector {
IoConnectFuture future = new DefaultIoConnectFuture(null);
try {
AsynchronousChannelGroup group = getChannelGroup();
- AsynchronousSocketChannel socket = openAsynchronousSocketChannel(address, group);
- setOption(socket, FactoryManager.SOCKET_KEEPALIVE, StandardSocketOptions.SO_KEEPALIVE, null);
- setOption(socket, FactoryManager.SOCKET_LINGER, StandardSocketOptions.SO_LINGER, null);
- setOption(socket, FactoryManager.SOCKET_RCVBUF, StandardSocketOptions.SO_RCVBUF, null);
- setOption(socket, FactoryManager.SOCKET_REUSEADDR, StandardSocketOptions.SO_REUSEADDR, Boolean.TRUE);
- setOption(socket, FactoryManager.SOCKET_SNDBUF, StandardSocketOptions.SO_SNDBUF, null);
- setOption(socket, FactoryManager.TCP_NODELAY, StandardSocketOptions.TCP_NODELAY, null);
-
+ AsynchronousSocketChannel socket =
+ setSocketOptions(openAsynchronousSocketChannel(address, group));
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/331bdfc9/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java
index a031532..aab42c4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java
@@ -21,10 +21,12 @@ package org.apache.sshd.common.io.nio2;
import java.io.IOException;
import java.net.SocketOption;
import java.net.SocketTimeoutException;
+import java.net.StandardSocketOptions;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.NetworkChannel;
import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
@@ -39,11 +41,28 @@ import org.apache.sshd.common.io.IoHandler;
import org.apache.sshd.common.io.IoService;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.Pair;
import org.apache.sshd.common.util.closeable.AbstractInnerCloseable;
/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public abstract class Nio2Service extends AbstractInnerCloseable implements IoService, FactoryManagerHolder {
+ public static final Map<String, Pair<SocketOption<?>, Object>> CONFIGURABLE_OPTIONS =
+ Collections.unmodifiableMap(new LinkedHashMap<String, Pair<SocketOption<?>, Object>>() {
+ // Not serializing it
+ private static final long serialVersionUID = 1L;
+
+ {
+ put(FactoryManager.SOCKET_KEEPALIVE, new Pair<SocketOption<?>, Object>(StandardSocketOptions.SO_KEEPALIVE, null));
+ put(FactoryManager.SOCKET_LINGER, new Pair<SocketOption<?>, Object>(StandardSocketOptions.SO_LINGER, null));
+ put(FactoryManager.SOCKET_RCVBUF, new Pair<SocketOption<?>, Object>(StandardSocketOptions.SO_RCVBUF, null));
+ put(FactoryManager.SOCKET_REUSEADDR, new Pair<SocketOption<?>, Object>(StandardSocketOptions.SO_REUSEADDR, DEFAULT_REUSE_ADDRESS));
+ put(FactoryManager.SOCKET_SNDBUF, new Pair<SocketOption<?>, Object>(StandardSocketOptions.SO_SNDBUF, null));
+ put(FactoryManager.TCP_NODELAY, new Pair<SocketOption<?>, Object>(StandardSocketOptions.TCP_NODELAY, null));
+ }
+ });
+
protected final Map<Long, IoSession> sessions;
protected final AtomicBoolean disposing = new AtomicBoolean();
private final FactoryManager manager;
@@ -105,7 +124,25 @@ public abstract class Nio2Service extends AbstractInnerCloseable implements IoSe
sessions.remove(session.getId());
}
- protected <T> void setOption(NetworkChannel socket, String property, SocketOption<T> option, T defaultValue) throws IOException {
+ @SuppressWarnings("unchecked")
+ protected <S extends NetworkChannel> S setSocketOptions(S socket) throws IOException {
+ Collection<? extends SocketOption<?>> supported = socket.supportedOptions();
+ if (GenericUtils.isEmpty(supported)) {
+ return socket;
+ }
+
+ for (Map.Entry<String, Pair<SocketOption<?>, Object>> ce : CONFIGURABLE_OPTIONS.entrySet()) {
+ String property = ce.getKey();
+ Pair<SocketOption<?>, Object> defConfig = ce.getValue();
+ @SuppressWarnings("rawtypes")
+ SocketOption option = defConfig.getKey();
+ setOption(socket, property, option, defConfig.getValue());
+ }
+
+ return socket;
+ }
+
+ protected <T> boolean setOption(NetworkChannel socket, String property, SocketOption<T> option, T defaultValue) throws IOException {
PropertyResolver manager = getFactoryManager();
String valStr = PropertyResolverUtils.getString(manager, property);
T val = defaultValue;
@@ -116,28 +153,34 @@ public abstract class Nio2Service extends AbstractInnerCloseable implements IoSe
} else if (type == Boolean.class) {
val = type.cast(Boolean.valueOf(valStr));
} else {
- throw new IllegalStateException("Unsupported socket option type " + type);
+ throw new IllegalStateException("Unsupported socket option type (" + type + ") " + property + "=" + valStr);
}
}
- if (val != null) {
- Collection<? extends SocketOption<?>> supported = socket.supportedOptions();
- if ((GenericUtils.size(supported) <= 0) || (!supported.contains(option))) {
- log.warn("Unsupported socket option (" + option + ") to set using property '" + property + "' value=" + val);
- return;
+ if (val == null) {
+ return false;
+ }
+
+ Collection<? extends SocketOption<?>> supported = socket.supportedOptions();
+ if (GenericUtils.isEmpty(supported) || (!supported.contains(option))) {
+ if (log.isDebugEnabled()) {
+ log.debug("Unsupported socket option ({}) to set using {}={}", option, property, val);
}
+ return false;
+ }
- try {
- socket.setOption(option, val);
- if (log.isDebugEnabled()) {
- log.debug("setOption({})[{}] from property={}", option, val, property);
- }
- } catch (IOException | RuntimeException e) {
- log.warn("Unable (" + e.getClass().getSimpleName() + ")"
- + " to set socket option " + option
- + " using property '" + property + "' value=" + val
- + ": " + e.getMessage());
+ try {
+ socket.setOption(option, val);
+ if (log.isDebugEnabled()) {
+ log.debug("setOption({})[{}] from property={}", option, val, property);
}
+ return true;
+ } catch (IOException | RuntimeException e) {
+ log.warn("Unable (" + e.getClass().getSimpleName() + ")"
+ + " to set socket option " + option
+ + " using property " + property + "=" + val
+ + ": " + e.getMessage());
+ return false;
}
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/331bdfc9/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactory.java
index 5fb773f..1cdb651 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactory.java
@@ -32,6 +32,7 @@ import org.apache.sshd.common.io.IoHandler;
import org.apache.sshd.common.util.threads.ThreadUtils;
/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public class Nio2ServiceFactory extends AbstractIoServiceFactory {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/331bdfc9/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
index 9947581..a007116 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
@@ -45,6 +45,7 @@ import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.closeable.AbstractCloseable;
/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public class Nio2Session extends AbstractCloseable implements IoSession {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/331bdfc9/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
index aa06c44..7fc8004 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
@@ -386,7 +386,9 @@ public class SshServer extends AbstractFactoryManager implements ServerFactoryMa
}
protected IoAcceptor createAcceptor() {
- return getIoServiceFactory().createAcceptor(getSessionFactory());
+ IoServiceFactory ioFactory = getIoServiceFactory();
+ SessionFactory sessFactory = getSessionFactory();
+ return ioFactory.createAcceptor(sessFactory);
}
protected SessionFactory createSessionFactory() {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/331bdfc9/sshd-core/src/test/java/org/apache/sshd/common/io/nio2/Nio2ServiceTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/io/nio2/Nio2ServiceTest.java b/sshd-core/src/test/java/org/apache/sshd/common/io/nio2/Nio2ServiceTest.java
index 8b51101..eae0bc8 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/io/nio2/Nio2ServiceTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/io/nio2/Nio2ServiceTest.java
@@ -20,11 +20,23 @@
package org.apache.sshd.common.io.nio2;
import java.net.Socket;
+import java.net.SocketOption;
+import java.nio.channels.AsynchronousSocketChannel;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.PropertyResolverUtils;
+import org.apache.sshd.common.io.IoSession;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.Pair;
import org.apache.sshd.server.SshServer;
+import org.apache.sshd.server.session.ServerSessionImpl;
+import org.apache.sshd.server.session.SessionFactory;
import org.apache.sshd.util.test.BaseTestSupport;
import org.junit.FixMethodOrder;
import org.junit.Test;
@@ -39,24 +51,69 @@ public class Nio2ServiceTest extends BaseTestSupport {
super();
}
- @Test // see SSHD-554
+ @Test // see SSHD-554, SSHD-722
public void testSetSocketOptions() throws Exception {
try (SshServer sshd = setupTestServer()) {
- PropertyResolverUtils.updateProperty(sshd, FactoryManager.SOCKET_KEEPALIVE, true);
- PropertyResolverUtils.updateProperty(sshd, FactoryManager.SOCKET_LINGER, 5);
- PropertyResolverUtils.updateProperty(sshd, FactoryManager.SOCKET_RCVBUF, 1024);
- PropertyResolverUtils.updateProperty(sshd, FactoryManager.SOCKET_REUSEADDR, true);
- PropertyResolverUtils.updateProperty(sshd, FactoryManager.SOCKET_SNDBUF, 1024);
- PropertyResolverUtils.updateProperty(sshd, FactoryManager.TCP_NODELAY, true);
+ Map<String, Object> expectedOptions =
+ Collections.unmodifiableMap(new LinkedHashMap<String, Object>() {
+ // Not serializing it
+ private static final long serialVersionUID = 1L;
- sshd.start();
+ {
+ put(FactoryManager.SOCKET_KEEPALIVE, true);
+ put(FactoryManager.SOCKET_LINGER, 5);
+ put(FactoryManager.SOCKET_RCVBUF, 1024);
+ put(FactoryManager.SOCKET_REUSEADDR, true);
+ put(FactoryManager.SOCKET_SNDBUF, 1024);
+ put(FactoryManager.TCP_NODELAY, true);
+ }
+ });
+ for (Map.Entry<String, ?> oe : expectedOptions.entrySet()) {
+ PropertyResolverUtils.updateProperty(sshd, oe.getKey(), oe.getValue());
+ }
+
+ Semaphore sigSem = new Semaphore(0, true);
+ sshd.setSessionFactory(new SessionFactory(sshd) {
+ @Override
+ protected ServerSessionImpl doCreateSession(IoSession ioSession) throws Exception {
+ validateSocketOptions(ioSession);
+ sigSem.release();
+ return super.doCreateSession(ioSession);
+ }
+
+ private void validateSocketOptions(IoSession ioSession) throws Exception {
+ if (!(ioSession instanceof Nio2Session)) {
+ return;
+ }
+ AsynchronousSocketChannel socket = ((Nio2Session) ioSession).getSocket();
+ Collection<? extends SocketOption<?>> supported = socket.supportedOptions();
+ if (GenericUtils.isEmpty(supported)) {
+ return;
+ }
+
+ for (Map.Entry<String, ?> oe : expectedOptions.entrySet()) {
+ String propName = oe.getKey();
+ Object expValue = oe.getValue();
+ Pair<SocketOption<?>, ?> optionEntry = Nio2Service.CONFIGURABLE_OPTIONS.get(propName);
+ SocketOption<?> option = optionEntry.getKey();
+ if (!supported.contains(option)) {
+ continue;
+ }
+
+ Object actValue = socket.getOption(option);
+ assertEquals("Mismatched value for " + propName + "/" + option, expValue, actValue);
+ }
+ }
+ });
+ sshd.start();
int port = sshd.getPort();
long startTime = System.nanoTime();
try (Socket s = new Socket(TEST_LOCALHOST, port)) {
long endTime = System.nanoTime();
long duration = endTime - startTime;
assertTrue("Connect duration is too high: " + duration, duration <= TimeUnit.SECONDS.toNanos(15L));
+ assertTrue("Validation not completed on time", sigSem.tryAcquire(15L, TimeUnit.SECONDS));
} finally {
sshd.stop();
}