You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by gn...@apache.org on 2014/12/12 14:18:15 UTC
[6/6] mina-sshd git commit: [SSHD-386] Allow controlling socket
options
[SSHD-386] Allow controlling socket options
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/f3d58b90
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/f3d58b90
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/f3d58b90
Branch: refs/heads/master
Commit: f3d58b906d795bac587f77eedb4647ad421b260d
Parents: 55bc681
Author: Guillaume Nodet <gn...@apache.org>
Authored: Fri Dec 12 14:07:55 2014 +0100
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Fri Dec 12 14:07:55 2014 +0100
----------------------------------------------------------------------
.../org/apache/sshd/common/FactoryManager.java | 42 ++++++++++++++++++++
.../sshd/common/io/mina/MinaAcceptor.java | 35 +++++-----------
.../sshd/common/io/mina/MinaConnector.java | 6 +--
.../apache/sshd/common/io/mina/MinaService.java | 37 +++++++++++++++++
.../sshd/common/io/nio2/Nio2Acceptor.java | 14 ++++++-
.../sshd/common/io/nio2/Nio2Connector.java | 7 ++++
.../apache/sshd/common/io/nio2/Nio2Service.java | 26 ++++++++++++
7 files changed, 136 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f3d58b90/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
index 037b718..c78f8e8 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
@@ -71,6 +71,48 @@ public interface FactoryManager {
public static final String IDLE_TIMEOUT = "idle-timeout";
/**
+ * Socket backlog.
+ * See {@link java.nio.channels.AsynchronousServerSocketChannel#bind(java.net.SocketAddress, int)}
+ */
+ public static final String SOCKET_BACKLOG = "socket-backlog";
+
+ /**
+ * Socket keep-alive.
+ * See {@link java.net.StandardSocketOptions#SO_KEEPALIVE}
+ */
+ public static final String SOCKET_KEEPALIVE = "socket-keepalive";
+
+ /**
+ * Socket send buffer size.
+ * See {@link java.net.StandardSocketOptions#SO_SNDBUF}
+ */
+ public static final String SOCKET_SNDBUF = "socket-sndbuf";
+
+ /**
+ * Socket receive buffer size.
+ * See {@link java.net.StandardSocketOptions#SO_RCVBUF}
+ */
+ public static final String SOCKET_RCVBUF = "socket-rcvbuf";
+
+ /**
+ * Socket reuse address.
+ * See {@link java.net.StandardSocketOptions#SO_REUSEADDR}
+ */
+ public static final String SOCKET_REUSEADDR = "socket-reuseaddr";
+
+ /**
+ * Socket linger.
+ * See {@link java.net.StandardSocketOptions#SO_LINGER}
+ */
+ public static final String SOCKET_LINGER = "socket-linger";
+
+ /**
+ * Socket tcp no-delay.
+ * See {@link java.net.StandardSocketOptions#TCP_NODELAY}
+ */
+ public static final String TCP_NODELAY = "tcp-nodelay";
+
+ /**
* A map of properties that can be used to configure the SSH server
* or client. This map will never be changed by either the server or
* client and is not supposed to be changed at runtime (changes are not
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f3d58b90/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 107972e..7a20d78 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
@@ -19,7 +19,6 @@
package org.apache.sshd.common.io.mina;
import java.io.IOException;
-import java.net.Socket;
import java.net.SocketAddress;
import java.util.Collection;
import java.util.Set;
@@ -28,7 +27,6 @@ import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.service.IoProcessor;
import org.apache.mina.core.service.IoService;
-import org.apache.mina.core.session.IoSessionConfig;
import org.apache.mina.transport.socket.nio.NioSession;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.apache.sshd.common.FactoryManager;
@@ -39,12 +37,20 @@ public class MinaAcceptor extends MinaService implements org.apache.sshd.common.
protected volatile IoAcceptor acceptor;
// Acceptor
- protected int backlog = 50;
+ protected int backlog = 0;
protected boolean reuseAddress = true;
- protected IoSessionConfig sessionConfig;
public MinaAcceptor(FactoryManager manager, org.apache.sshd.common.io.IoHandler handler, IoProcessor<NioSession> ioProcessor) {
super(manager, handler, ioProcessor);
+
+ String valStr = manager.getProperties().get(FactoryManager.SOCKET_BACKLOG);
+ if (valStr != null) {
+ backlog = Integer.parseInt(valStr);
+ }
+ valStr = manager.getProperties().get(FactoryManager.SOCKET_REUSEADDR);
+ if (valStr != null) {
+ reuseAddress = Boolean.parseBoolean(valStr);
+ }
}
protected IoAcceptor createAcceptor() {
@@ -52,26 +58,7 @@ public class MinaAcceptor extends MinaService implements org.apache.sshd.common.
acceptor.setCloseOnDeactivation(false);
acceptor.setReuseAddress(reuseAddress);
acceptor.setBacklog(backlog);
-
- // MINA itself forces our socket receive buffer to 1024 bytes
- // by default, despite what the operating system defaults to.
- // This limits us to about 3 MB/s incoming data transfer. By
- // forcing back to the operating system default we can get a
- // decent transfer rate again.
- //
- final Socket s = new Socket();
- try {
- try {
- acceptor.getSessionConfig().setReceiveBufferSize(s.getReceiveBufferSize());
- } finally {
- s.close();
- }
- } catch (IOException e) {
- log.warn("cannot adjust SO_RCVBUF back to system default", e);
- }
- if (sessionConfig != null) {
- acceptor.getSessionConfig().setAll(sessionConfig);
- }
+ configure(acceptor.getSessionConfig());
return acceptor;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f3d58b90/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 8181652..6e4e368 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
@@ -25,7 +25,6 @@ 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.IoSessionConfig;
import org.apache.mina.transport.socket.nio.NioSession;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.apache.sshd.common.FactoryManager;
@@ -37,7 +36,6 @@ import org.apache.sshd.common.io.IoConnectFuture;
public class MinaConnector extends MinaService implements org.apache.sshd.common.io.IoConnector, IoHandler {
protected volatile IoConnector connector;
- protected IoSessionConfig sessionConfig;
public MinaConnector(FactoryManager manager, org.apache.sshd.common.io.IoHandler handler, IoProcessor<NioSession> ioProcessor) {
super(manager, handler, ioProcessor);
@@ -45,9 +43,7 @@ public class MinaConnector extends MinaService implements org.apache.sshd.common
protected IoConnector createConnector() {
NioSocketConnector connector = new NioSocketConnector(ioProcessor);
- if (sessionConfig != null) {
- connector.getSessionConfig().setAll(sessionConfig);
- }
+ configure(connector.getSessionConfig());
return connector;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f3d58b90/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 6d962ed..1981eb8 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
@@ -28,6 +28,8 @@ import org.apache.mina.core.service.IoProcessor;
import org.apache.mina.core.service.IoService;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
+import org.apache.mina.core.session.IoSessionConfig;
+import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSession;
import org.apache.sshd.common.Closeable;
import org.apache.sshd.common.FactoryManager;
@@ -45,6 +47,7 @@ public abstract class MinaService extends IoHandlerAdapter implements org.apache
protected final FactoryManager manager;
protected final org.apache.sshd.common.io.IoHandler handler;
protected final IoProcessor<NioSession> ioProcessor;
+ protected IoSessionConfig sessionConfig;
public MinaService(FactoryManager manager, org.apache.sshd.common.io.IoHandler handler, IoProcessor<NioSession> ioProcessor) {
this.manager = manager;
@@ -106,4 +109,38 @@ public abstract class MinaService extends IoHandlerAdapter implements org.apache
return (org.apache.sshd.common.io.IoSession)
session.getAttribute(org.apache.sshd.common.io.IoSession.class);
}
+
+ protected void configure(SocketSessionConfig config) {
+ Integer intVal;
+ Boolean boolVal;
+ if ((boolVal = getBoolean(FactoryManager.SOCKET_KEEPALIVE)) != null) {
+ config.setKeepAlive(boolVal);
+ }
+ if ((intVal = getInteger(FactoryManager.SOCKET_SNDBUF)) != null) {
+ config.setSendBufferSize(intVal);
+ }
+ if ((intVal = getInteger(FactoryManager.SOCKET_RCVBUF)) != null) {
+ config.setReceiveBufferSize(intVal);
+ }
+ if ((intVal = getInteger(FactoryManager.SOCKET_LINGER)) != null) {
+ config.setSoLinger(intVal);
+ }
+ if ((boolVal = getBoolean(FactoryManager.SOCKET_LINGER)) != null) {
+ config.setTcpNoDelay(boolVal);
+ }
+ if (sessionConfig != null) {
+ config.setAll(sessionConfig);
+ }
+ }
+
+ protected Integer getInteger(String property) {
+ String strVal = manager.getProperties().get(property);
+ return (strVal != null) ? Integer.parseInt(strVal) : null;
+ }
+
+ protected Boolean getBoolean(String property) {
+ String strVal = manager.getProperties().get(property);
+ return (strVal != null) ? Boolean.parseBoolean(strVal) : null;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f3d58b90/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 f9fab11..9bba704 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
@@ -41,18 +41,28 @@ import org.apache.sshd.common.io.IoHandler;
public class Nio2Acceptor extends Nio2Service implements IoAcceptor {
private final Map<SocketAddress, AsynchronousServerSocketChannel> channels;
- private int backlog = 50;
+ private int backlog = 0;
public Nio2Acceptor(FactoryManager manager, IoHandler handler, AsynchronousChannelGroup group) {
super(manager, handler, group);
channels = new ConcurrentHashMap<SocketAddress, AsynchronousServerSocketChannel>();
+
+ String valStr = manager.getProperties().get(FactoryManager.SOCKET_BACKLOG);
+ if (valStr != null) {
+ backlog = Integer.parseInt(valStr);
+ }
}
public void bind(Collection<? extends SocketAddress> addresses) throws IOException {
for (SocketAddress address : addresses) {
logger.debug("Binding Nio2Acceptor to address {}", address);
AsynchronousServerSocketChannel socket = AsynchronousServerSocketChannel.open(group);
- socket.setOption(StandardSocketOptions.SO_REUSEADDR, Boolean.TRUE);
+ 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);
socket.bind(address, backlog);
SocketAddress local = socket.getLocalAddress();
channels.put(local, socket);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f3d58b90/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 d427ef4..0ad182b 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,6 +20,7 @@ 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;
@@ -43,6 +44,12 @@ public class Nio2Connector extends Nio2Service implements IoConnector {
final IoConnectFuture future = new DefaultIoConnectFuture(null);
try {
final AsynchronousSocketChannel socket = AsynchronousSocketChannel.open(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);
socket.connect(address, null, new Nio2CompletionHandler<Void, Object>() {
protected void onCompleted(Void result, Object attachment) {
try {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f3d58b90/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 3c5a2b7..4bdb8f7 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
@@ -18,7 +18,10 @@
*/
package org.apache.sshd.common.io.nio2;
+import java.io.IOException;
+import java.net.SocketOption;
import java.nio.channels.AsynchronousChannelGroup;
+import java.nio.channels.NetworkChannel;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -72,4 +75,27 @@ public abstract class Nio2Service extends CloseableUtils.AbstractInnerCloseable
public void sessionClosed(Nio2Session session) {
sessions.remove(session.getId());
}
+
+ protected <T> void setOption(NetworkChannel socket, String property, SocketOption<T> option, T defaultValue) throws IOException {
+ String valStr = manager.getProperties().get(property);
+ T val = defaultValue;
+ if (valStr != null) {
+ Class<T> type = option.type();
+ if (type == Integer.class) {
+ val = type.cast(Integer.parseInt(valStr));
+ } else if (type == Boolean.class) {
+ val = type.cast(Boolean.parseBoolean(valStr));
+ } else {
+ throw new IllegalStateException("Unsupported socket option type " + type);
+ }
+ }
+ if (val != null) {
+ try {
+ socket.setOption(option, val);
+ } catch (IOException e) {
+ logger.warn("Unable to set socket option " + option + " to " + val, e);
+ }
+ }
+ }
+
}