You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by František Kučera <ko...@frantovo.cz> on 2019/07/14 17:10:11 UTC

Allow keeping tcpNoDelay untouched (default)

Hello,

I got this error when new HTTP request comes:

14-Jul-2019 18:18:39.296 SEVERE [http-nio-8080-Acceptor] 
org.apache.tomcat.util.net.NioEndpoint.setSocketOptions Error setting 
socket options
         java.net.SocketException: Operace není podporována
                 at sun.nio.ch.Net.setIntOption0(Native Method)
                 at sun.nio.ch.Net.setSocketOption(Net.java:334)
                 at 
sun.nio.ch.SocketChannelImpl.setOption(SocketChannelImpl.java:190)
                 at 
sun.nio.ch.SocketAdaptor.setBooleanOption(SocketAdaptor.java:271)
                 at 
sun.nio.ch.SocketAdaptor.setTcpNoDelay(SocketAdaptor.java:306)
                 at 
org.apache.tomcat.util.net.SocketProperties.setProperties(SocketProperties.java:204)
                 at 
org.apache.tomcat.util.net.NioEndpoint.setSocketOptions(NioEndpoint.java:401)
                 at 
org.apache.tomcat.util.net.NioEndpoint.setSocketOptions(NioEndpoint.java:73)
                 at 
org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:115)
                 at java.lang.Thread.run(Thread.java:748)

do not panic, this does not happen in normal conditions - my setup is 
kind of special. Given socket does not support the tcpNoDelay option, so 
it throws an exception. To get rid of it, I patched the Tomcat's source 
code (see attachment, it patches the latest git version).

I am looking for a more clean solution that could be merged in the 
official sources. IMHO it might keep the state of socket's tcpNoDelay 
untouched (i.e. do not call setTcpNoDelay() method) if there is no 
explicit configuration to set this option.

I looked in the git history and current sources and there is the 
condition: "if (tcpNoDelay != null)" and:

/**
  * TCP_NO_DELAY option. JVM default used if not set.
  */
protected Boolean tcpNoDelay = Boolean.TRUE;

and it was "tcpNoDelay = null;" in 2008. So it seems that it worked this 
way before... But now it always calls setTcpNoDelay(true) if not 
configured to false (and then it calls setTcpNoDelay(false)). I have not 
found any way to configure Tomcat to not set this option and keep the 
socket in its original state.

Or there might be a third option in the tcpNoDelay configuration 
<https://tomcat.apache.org/tomcat-9.0-doc/config/http.html> like 
"default" or "null" besides the "true" and "false" (i.e. convert some 
booleans to Booleans in the source code and allow the null value). This 
might be more backward compatible behavior.

I can help with writing the patch and testing but I would appreciate 
some design advice.

Context: I am interested in making applications listen on unix domain 
sockets instead of TCP ones (e.g. Jetty can work this way) and 
especially in listening on sockets inherited from parent process (the 
"useInheritedChannel" in Tomcat's Connector configuration). And unix 
domain socket has no tcpNoDelay option obviously.

Franta


Re: Allow keeping tcpNoDelay untouched (default)

Posted by Mark Thomas <ma...@apache.org>.
On July 14, 2019 5:10:11 PM UTC, "František Kučera" <ko...@frantovo.cz> wrote:
>Hello,
>
>I got this error when new HTTP request comes:
>
>14-Jul-2019 18:18:39.296 SEVERE [http-nio-8080-Acceptor] 
>org.apache.tomcat.util.net.NioEndpoint.setSocketOptions Error setting 
>socket options
>         java.net.SocketException: Operace není podporována
>                 at sun.nio.ch.Net.setIntOption0(Native Method)
>                 at sun.nio.ch.Net.setSocketOption(Net.java:334)
>                 at 
>sun.nio.ch.SocketChannelImpl.setOption(SocketChannelImpl.java:190)
>                 at 
>sun.nio.ch.SocketAdaptor.setBooleanOption(SocketAdaptor.java:271)
>                 at 
>sun.nio.ch.SocketAdaptor.setTcpNoDelay(SocketAdaptor.java:306)
>                 at 
>org.apache.tomcat.util.net.SocketProperties.setProperties(SocketProperties.java:204)
>                 at 
>org.apache.tomcat.util.net.NioEndpoint.setSocketOptions(NioEndpoint.java:401)
>                 at 
>org.apache.tomcat.util.net.NioEndpoint.setSocketOptions(NioEndpoint.java:73)
>                 at 
>org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:115)
>                 at java.lang.Thread.run(Thread.java:748)
>
>do not panic, this does not happen in normal conditions - my setup is 
>kind of special. Given socket does not support the tcpNoDelay option,
>so 
>it throws an exception. To get rid of it, I patched the Tomcat's source
>
>code (see attachment, it patches the latest git version).
>
>I am looking for a more clean solution that could be merged in the 
>official sources. IMHO it might keep the state of socket's tcpNoDelay 
>untouched (i.e. do not call setTcpNoDelay() method) if there is no 
>explicit configuration to set this option.
>
>I looked in the git history and current sources and there is the 
>condition: "if (tcpNoDelay != null)" and:
>
>/**
>  * TCP_NO_DELAY option. JVM default used if not set.
>  */
>protected Boolean tcpNoDelay = Boolean.TRUE;
>
>and it was "tcpNoDelay = null;" in 2008. So it seems that it worked
>this 
>way before... But now it always calls setTcpNoDelay(true) if not 
>configured to false (and then it calls setTcpNoDelay(false)). I have
>not 
>found any way to configure Tomcat to not set this option and keep the 
>socket in its original state.
>
>Or there might be a third option in the tcpNoDelay configuration 
><https://tomcat.apache.org/tomcat-9.0-doc/config/http.html> like 
>"default" or "null" besides the "true" and "false" (i.e. convert some 
>booleans to Booleans in the source code and allow the null value). This
>
>might be more backward compatible behavior.
>
>I can help with writing the patch and testing but I would appreciate 
>some design advice.
>
>Context: I am interested in making applications listen on unix domain 
>sockets instead of TCP ones (e.g. Jetty can work this way) and 
>especially in listening on sockets inherited from parent process (the 
>"useInheritedChannel" in Tomcat's Connector configuration). And unix 
>domain socket has no tcpNoDelay option obviously.
>
>Franta

I recommend creating a bugzilla issue for this so that it doesn't get lost.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org