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();
             }