Allow keeping tcpNoDelay untouched (default)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Allow keeping tcpNoDelay untouched (default)

František Kučera
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



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

tomcat-tcpNoDelay-1.diff (844 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Allow keeping tcpNoDelay untouched (default)

markt
On July 14, 2019 5:10:11 PM UTC, "František Kučera" <[hidden email]> 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: [hidden email]
For additional commands, e-mail: [hidden email]