INT-1872 Allow Indefinite Socket Timeout

Previously, for single-use server sockets, and for client sockets
that have a collaborating inbound adapter, the socket timeout
was set to 10 seconds, with no way to set to infinity. The work
around was to set it to Integer.MAX_VALUE.

The intent was to avoid DoS attacks and mis-behaved clients, but
some users have expressed a desire to be able to set an infinite
timeout in both scenarios.

A future release may remove the 10 second default from the client
socket that has a collaborating inbound adapter, and default to
infinity. For this reason, that case now emits a warning.

The default 10 second timeout on single-use server sockets will
likely remain.

INT-1872 Remove WARN Log

We decided to eliminate the log message regarding a possible
future change to the default timeout for client sockets used
for request/reply.
This commit is contained in:
Gary Russell
2011-10-14 22:39:33 -04:00
committed by Mark Fisher
parent 8dcf09f834
commit 57121604d3
6 changed files with 19 additions and 14 deletions

View File

@@ -725,12 +725,7 @@
factory.
</para>
<para>
It is not currently possible to set this to an infinite value
(0); the maximum value can be set using a SpEL expression as
follows.
<programlisting>
so-timeout="#{T(java.lang.Integer).MAX_VALUE}"
</programlisting>
Setting the attribute to 0 will enable an infinite timeout.
</para>
</note>
</para>
@@ -867,7 +862,9 @@
<entry>Y</entry>
<entry></entry>
<entry>Defaults to 0 (infinity), except when the connection
factory is used by collaborating adapters, where it
factory is used by collaborating adapters, and for
server connection factories with single-use="true".
In those cases, it
defaults to the default reply timeout (10 seconds).
See the section about collaborating adapters above
and <classname>java.net.Socket. setSoTimeout()</classname>.

View File

@@ -74,8 +74,13 @@ public abstract class AbstractClientConnectionFactory extends AbstractConnection
connection.registerListener(listener);
}
if (listener != null || this.isSingleUse()) {
if (this.getSoTimeout() <= 0) {
if (this.getSoTimeout() < 0) {
try {
/* Default so-timeout, when we have a collaborating inbound adapter,
* may go to infinity in a future release; currently it's 10 seconds.
* While it makes sense in a request/reply scenario, it doesn't
* really for completely asynchronous communication between peers.
*/
socket.setSoTimeout(DEFAULT_REPLY_TIMEOUT);
} catch (SocketException e) {
logger.error("Error setting default reply timeout", e);

View File

@@ -67,7 +67,7 @@ public abstract class AbstractConnectionFactory extends IntegrationObjectSupport
private volatile TcpSender sender;
private volatile int soTimeout;
private volatile int soTimeout = -1;
private volatile int soSendBufferSize;

View File

@@ -84,11 +84,12 @@ public abstract class AbstractServerConnectionFactory extends AbstractConnection
connection.setSerializer(this.getSerializer());
connection.setSingleUse(this.isSingleUse());
/*
* If we have a collaborating outbound channel adapter and we are configured
* If we are configured
* for single use; need to enforce a timeout on the socket so we will close
* it some period after the response was sent (timeout on the next read).
* if the client connects, but sends nothing. (Protect against DoS).
* Behavior can be overridden by explicitly setting the timeout to zero.
*/
if (this.isSingleUse() && this.getSoTimeout() <= 0 && listener != null) {
if (this.isSingleUse() && this.getSoTimeout() < 0) {
try {
socket.setSoTimeout(DEFAULT_REPLY_TIMEOUT);
} catch (SocketException e) {

View File

@@ -122,7 +122,8 @@ public class TcpNioClientConnectionFactory extends
this.selector = Selector.open();
while (this.isActive()) {
SocketChannel newChannel;
int selectionCount = selector.select(this.getSoTimeout());
int soTimeout = this.getSoTimeout();
int selectionCount = selector.select(soTimeout < 0 ? 0 : soTimeout);
while ((newChannel = newChannels.poll()) != null) {
newChannel.register(this.selector, SelectionKey.OP_READ, connections.get(newChannel));
}

View File

@@ -113,7 +113,8 @@ public class TcpNioServerConnectionFactory extends AbstractServerConnectionFacto
private void doSelect(ServerSocketChannel server, final Selector selector)
throws IOException, ClosedChannelException, SocketException {
while (this.isActive()) {
int selectionCount = selector.select(this.getSoTimeout());
int soTimeout = this.getSoTimeout();
int selectionCount = selector.select(soTimeout < 0 ? 0 : soTimeout);
this.processNioSelections(selectionCount, selector, server, this.connections);
}
}