Permalink
Browse files

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.
  • Loading branch information...
1 parent 8dcf09f commit 57121604d36dd56562e619ea8dca3099be1c1bdd @garyrussell garyrussell committed with markfisher Oct 15, 2011
View
11 docs/src/reference/docbook/ip.xml
@@ -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
7 ...va/org/springframework/integration/ip/tcp/connection/AbstractClientConnectionFactory.java
@@ -74,8 +74,13 @@ protected void initializeConnection(TcpConnection connection, Socket socket) {
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
2 ...ain/java/org/springframework/integration/ip/tcp/connection/AbstractConnectionFactory.java
@@ -67,7 +67,7 @@
private volatile TcpSender sender;
- private volatile int soTimeout;
+ private volatile int soTimeout = -1;
private volatile int soSendBufferSize;
View
7 ...va/org/springframework/integration/ip/tcp/connection/AbstractServerConnectionFactory.java
@@ -84,11 +84,12 @@ protected void initializeConnection(TcpConnection connection, Socket socket) {
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
3 ...java/org/springframework/integration/ip/tcp/connection/TcpNioClientConnectionFactory.java
@@ -122,7 +122,8 @@ public void run() {
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
3 ...java/org/springframework/integration/ip/tcp/connection/TcpNioServerConnectionFactory.java
@@ -113,7 +113,8 @@ public void run() {
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);
}
}

0 comments on commit 5712160

Please sign in to comment.